如何用回溯法实现

hyqryq 2000-12-19 02:23:00
有一批物品共N个,不发生化学反应的可以放在同一个仓库,求一种放物品的方法,
可以用最少的仓库.
...全文
187 9 打赏 收藏 举报
写回复
9 条回复
切换为时间正序
当前发帖距今超过3年,不再开放新的回复
发表回复
hyqryq 2000-12-22
那另一个:hyqryq@163.net
  • 打赏
  • 举报
回复
lu_yb 2000-12-22
lu_yb@163.net
最好不要用263的信箱给我写东西,因为我们这里把263给屏蔽掉了,嘻嘻
  • 打赏
  • 举报
回复
hyqryq 2000-12-22
OK! 多谢多谢!
立即加分!
留个E_mail好吗?有什么问题可以共同探讨嘛!
我的:hyqryq@263.net
  • 打赏
  • 举报
回复
lu_yb 2000-12-22
我程序都给你了,你都不给我分,555555~~~~
"最少"是这样得出来的:如果你遍例的所有的情况,那是不是就知道哪种
最少了.当然是不需要遍例所有的情况的,只要记录一个目前遍例过的
情况中的最小值,然后如果目前在遍例的情况比这个值大的就放弃并
回溯,就可以比较快的得到最小值了.
第一个仓库里有多少物品不能说明任何问题.
  • 打赏
  • 举报
回复
hyqryq 2000-12-22
感谢各位高手的热情帮助!

我也想过这个问题,但我不知道如何才能说明用"最少"的仓库,
可不可能出现5,3,1和4,4这样的情况,虽然第一个仓库装的物品
最多,但能说明总仓库数最少吗?
  • 打赏
  • 举报
回复
lu_yb 2000-12-21
我修改调试了一下,完整程序如下.当然其中的数据你可以自己改的.
#include <stdio.h>

#define N 10

int a[N][N] = { 0,1,1,0,1,0,1,0,0,1,
1,0,0,0,0,1,0,0,0,0,
1,0,0,1,0,0,1,0,1,1,
0,0,1,0,0,0,0,1,0,0,
1,0,0,0,0,1,0,0,0,0,
0,1,0,0,1,1,1,1,1,1,
1,0,1,0,0,1,0,0,0,0,
0,0,0,1,0,1,0,0,1,1,
0,0,1,0,0,1,0,1,0,1,
1,0,1,0,0,1,0,1,1,0
};
int w[N+1][N+1] ;
int minnum = N;
int curnum = 0 ;
void addtowarehouse(int item)
{
int i,j,k1,k2;
for(i=1;i<=curnum;i++)
{
j=0;
while(w[i][j]!=0&&a[w[i][j]-1][item-1]!=1)
j++;
if(w[i][j]==0)
{
if(item==N)
{
minnum = curnum;
w[i][j] = item;
for(k1=1;k1<=curnum;k1++)
{
k2=0;
printf("%d:",k1);
while(w[k1][k2]!=0)
{
printf(" %d ",w[k1][k2]);
k2++;
}
printf("\n");
}
printf("\n");
w[i][j] = 0;
return;
}
else
{
w[i][j] = item;
addtowarehouse(item+1);
}
w[i][j] = 0;
}
}
if(curnum<minnum-1)
{
curnum++;

if(item == N)
{
minnum = curnum;
w[curnum][0]=item;
for(k1=1;k1<=curnum;k1++)
{
k2=0;
printf("%d:",k1);
while(w[k1][k2]!=0)
{
printf(" %d ",w[k1][k2]);
k2++;
}
printf("\n");
}
printf("\n");
w[curnum][0] = 0;
curnum--;
return;
}
else
{
w[curnum][0]=item;
addtowarehouse(item+1);
}
w[curnum][0] = 0;
curnum--;
}
return;
}

int main()
{
w[1][0]=1;
curnum = 1;
addtowarehouse(2);
printf("min number is %d\n",minnum);
}
  • 打赏
  • 举报
回复
lu_yb 2000-12-21
大概算法如此:)
#define N ...;
int a[N+1][N+1] = {...}; //关联矩阵,如果i和j发生反应a[i][j]=1
int w[N][N]; //仓库内容,初始化为全0
int minnum = N; //仓库最小数
int curnum = 0 ; //目前使用仓库数
void addtowarehouse(int item)
{
int i,j;
for(i=1;i<=curnum;i++)
{
j=0; //j代表i仓库中的第j个物品
while(w[i][j]!=0&&a[w[i][j]][item]!=1) //查看i仓库是否能放入item
j++;
if(w[i][j]==0) //如果能放入,则放入i仓库并递进
{
if(item==N)
{
minnum = curnum;
return;
}
else
{
w[i][j] = item;
addtowarehouse(item+1);
}
//如果发生递归,则从仓库中取出item
w[i][j] = 0;
}
}
//到此代表已有的仓库均不能放入item或者已经遍例过放入item的情况
//则加入一个仓库
if(curnum<minnum-1)
{
curnum++;
if(item == N)
{
minnum = curnum;
return;
}
else
{
w[curnum][0]=item;
addtowarehouse(item+1);
}
w[curnum][0] = 0;
curnum--;
}
return;
}

int main()
{
w[1][0]=1;
addwarehouse(2);
printf("min number is %d",minnum);
}
  • 打赏
  • 举报
回复
wistaria 2000-12-19
没有那么简单吧
这可以归成一个图论的问题
假定这N个物品是N个点,如果i,j(i!=j)不发生化学反映
就在i,j中画一条线。
那么如果有s个物品可以放在一个仓库中,那么这s个点
组成一个完全图。
要求的问题就是怎么把这N个点分组最少,而且每个组都是一个
完全图
  • 打赏
  • 举报
回复
eball 2000-12-19
n=1; //仓库数
for(i=1;i<=n;i++){
for(j=1;j<=n;j++){
if (不发生反应){
put;
goto NEXTGOODS;
}
}
n+=1;
put;
NEXTGOODS:
}
  • 打赏
  • 举报
回复
发帖
数据结构与算法
加入

3.2w+

社区成员

数据结构与算法相关内容讨论专区
社区管理员
  • 数据结构与算法社区
申请成为版主
帖子事件
创建了帖子
2000-12-19 02:23
社区公告
暂无公告