高程算法:关于装箱问题的C描述的一段小不解

kakajenifer 2003-08-29 07:57:42
程序有部分代码是:
for (q=j->next;q!=NULL&&q->link!=NULL;q=q->link);
if (q==NULL)
{ p->link=j->head;
j->head=p;
}
else
{ p->link=NULL;
q->link=p;
}
这里看不懂,这几段作什么用的?其中for循环让我纳闷,后面也不跟语句就在第三个表达式里做事情,而这个for内的三个表达式我都没理解是分别什么意思?尤其是第二个!
然后if else判断怎么搞的??

-------------------------------
【问题】 装箱问题
问题描述:装箱问题可简述如下:设有编号为0、1、…、n-1的n种物品,体积分别为v0、v1、…、vn-1。将这n种物品装到容量都为V的若干箱子里。约定这n种物品的体积均不超过V,即对于0≤i<n,有0<vi≤V。不同的装箱方案所需要的箱子数目可能不同。装箱问题要求使装尽这n种物品的箱子数要少。
若考察将n种物品的集合分划成n个或小于n个物品的所有子集,最优解就可以找到。但所有可能划分的总数太大。对适当大的n,找出所有可能的划分要花费的时间是无法承受的。为此,对装箱问题采用非常简单的近似算法,即贪婪法。该算法依次将物品放到它第一个能放进去的箱子中,该算法虽不能保证找到最优解,但还是能找到非常好的解。不失一般性,设n件物品的体积是按从大到小排好序的,即有v0≥v1≥…≥vn-1。如不满足上述要求,只要先对这n件物品按它们的体积从大到小排序,然后按排序结果对物品重新编号即可。装箱算法简单描述如下:
{ 输入箱子的容积;
输入物品种数n;
按体积从大到小顺序,输入各物品的体积;
预置已用箱子链为空;
预置已用箱子计数器box_count为0;
for (i=0;i<n;i++)
{ 从已用的第一只箱子开始顺序寻找能放入物品i 的箱子j;
if (已用箱子都不能再放物品i)
{ 另用一个箱子,并将物品i放入该箱子;
box_count++;
}
else
将物品i放入箱子j;
}
}
上述算法能求出需要的箱子数box_count,并能求出各箱子所装物品。下面的例子说明该算法不一定能找到最优解,设有6种物品,它们的体积分别为:60、45、35、20、20和20单位体积,箱子的容积为100个单位体积。按上述算法计算,需三只箱子,各箱子所装物品分别为:第一只箱子装物品1、3;第二只箱子装物品2、4、5;第三只箱子装物品6。而最优解为两只箱子,分别装物品1、4、5和2、3、6。
若每只箱子所装物品用链表来表示,链表首结点指针存于一个结构中,结构记录尚剩余的空间量和该箱子所装物品链表的首指针。另将全部箱子的信息也构成链表。以下是按以上算法编写的程序。
【程序】
# include <stdio.h>
# include <stdlib.h>
typedef struct ele
{ int vno;
struct ele *link;
} ELE;
typedef struct hnode
{ int remainder;
ELE *head;
Struct hnode *next;
} HNODE;

void main()
{ int n, i, box_count, box_volume, *a;
HNODE *box_h, *box_t, *j;
ELE *p, *q;
Printf("输入箱子容积\n");
Scanf("%d",&box_volume);
Printf("输入物品种数\n");
Scanf("%d",&n);
A=(int *)malloc(sizeof(int)*n);
Printf("请按体积从大到小顺序输入各物品的体积:");
For (i=0;i<n;i++) scanf("%d",a+i);
Box_h=box_t=NULL;
Box_count=0;
For (i=0;i<n;i++)
{ p=(ELE *)malloc(sizeof(ELE));
p->vno=i;
for (j=box_h;j!=NULL;j=j->next)
if (j->remainder>=a[i]) break;
if (j==NULL)
{ j=(HNODE *)malloc(sizeof(HNODE));
j->remainder=box_volume-a[i];
j->head=NULL;
if (box_h==NULL) box_h=box_t=j;
else box_t=boix_t->next=j;
j->next=NULL;
box_count++;
}
else j->remainder-=a[i];
for (q=j->next;q!=NULL&&q->link!=NULL;q=q->link);
if (q==NULL)
{ p->link=j->head;
j->head=p;
}
else
{ p->link=NULL;
q->link=p;
}
}
printf("共使用了%d只箱子",box_count);
printf("各箱子装物品情况如下:");
for (j=box_h,i=1;j!=NULL;j=j->next,i++)
{ printf("第%2d只箱子,还剩余容积%4d,所装物品有;\n",I,j->remainder);
for (p=j->head;p!=NULL;p=p->link)
printf("%4d",p->vno+1);
printf("\n");
}
}
...全文
96 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
Begin2008 2003-12-08
  • 打赏
  • 举报
回复
关于装箱算法的详细情况,请你们 http://x-lz.ebigchina.com 去查看,
具体情况,你们就直接和罗详存先生联系
Begin2008 2003-11-01
  • 打赏
  • 举报
回复
我有极优的装箱算法,如果需要的话,请留下你们的联系方式,我会和你联系的。

说明:
用传统的数学技术解决装箱算法,会存在“指数爆炸”问题,速度也很慢,现有一个中科院老数学家提出新的数学模型解决了这一问题。我现在想帮他推广他的数学模型。
luofuliang 2003-08-29
  • 打赏
  • 举报
回复
没错,是这样的。(比我解释的要好很多哦^_^)
Dragon132 2003-08-29
  • 打赏
  • 举报
回复
for (q=j->head;q!=NULL&&q->link!=NULL;q=q->link);
在这里j是放第i个物品的箱子
q=j->head指q指向了j箱子中的物品的首结点,q=q->link是指q指向下一个物品的结点,
q->link!=NULL的意思是找最后一个物品的结点,而q!=NULL是指当箱子中没有物品时q应为空那么根本不存在q->link所以在这里有一个判断,下面有相应的操作即为相应的操作
if (q==NULL)
{ p->link=j->head; 如果q==NULL那么j->head=NULL,则这句相当于p->link=NULL;
j->head=p; p成为j箱子中的首结点
}
else
{ p->link=NULL; 如果q!=NULL则j箱子中有物品将p放在箱子的最后
q->link=p;
}
luofuliang 2003-08-29
  • 打赏
  • 举报
回复
我来补充一下:
刚才看了一下书,好像又明了一点。
是这样的,这个循环语句for (q=j->head;q!=NULL&&q->link!=NULL;q=q->link);的目
的是找出该箱中物品链的链尾(q==null是没物品,q->link==null的话则q是链尾了)
if(q==null)下面的语句是:新启用的箱子
else下面的语句显然是在该箱链尾处链接新物品

如果我那里解释得不对的,请各位指教!
caoyun 2003-08-29
  • 打赏
  • 举报
回复
老兄,这个for循环循环体确实什么都没做,但它确实有作用,就是把p指针指向链表的表尾~~
还有这个链表是一个带有表头结点的指针~~
for语句中的第二个是判断p指针指向的结点是否为空,而且也判断了,p指针指向的结点的link域是否为空~~
atholon 2003-08-29
  • 打赏
  • 举报
回复
for (q=j->head;q!=NULL&&q->link!=NULL;q=q->link);
这句可以看作
for (q=j->head;q!=NULL&&q->link!=NULL;q=q->link)
{
}
是一个不执行任何语句的空循环,当循环结束后。q==NULL或q->link==NULL。
然后在根据q的情况执行下面的条件语句。
luofuliang 2003-08-29
  • 打赏
  • 举报
回复
老兄:
程序有部分代码是:
for (q=j->next;q!=NULL&&q->link!=NULL;q=q->link);
if (q==NULL)
{ p->link=j->head;
j->head=p;
}
else
{ p->link=NULL;
q->link=p;
}

你这句抄错了:for (q=j->next;q!=NULL&&q->link!=NULL;q=q->link);
应:for (q=j->head;q!=NULL&&q->link!=NULL;q=q->link);


我是考中程的,不过我看到这也不太明,帮不了你。

69,369

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧