最优装载问题
2014-11-02 23:32
337 查看
问题描述:给定一艘容量为C的船,给定一批货物,货物i的重量是wi,要求在船不超重的前提下,将尽可能多的货物装上船。
此题的解法较多,可以采取暴力搜索,也可以采取回溯法。从本质上讲,二者的基本思路是一样的,只不过对于问题的表现形式不同。
1、采用回溯法
2、加上限制,并输出最优解。限制的条件是如果可能取得最优解,进入右子树,否则不进入
3、非递归迭代回溯
4、暴力搜索
#include <stdio.h>
#include <math.h>
int main()
{
int i,j,num;
int max,temp;
int *w;
int n,c;
printf("input the number of boxes and the volume of the ship:");
scanf("%d%d",&n,&c);
w=new int
;
printf("input the weights of each box:");
for(i=0;i<n;i++)
scanf("%d",w+i);
max=0;
for(num=0;num<pow(2,n);num++)
{
temp=0; j=num;
for(i=0;i<n;i++)
{
if(j%2)
temp=temp+w[i];
j=j/2;
}
if(temp>max && temp<=c)
max=temp;
}
printf("the result is %d.\n",max);
return 0;
}
此题的解法较多,可以采取暴力搜索,也可以采取回溯法。从本质上讲,二者的基本思路是一样的,只不过对于问题的表现形式不同。
1、采用回溯法
#include <stdio.h> int n, c,cw, bestw; int *w; void backtrack(int i) { if (i>n) { if(bestw<cw) bestw=cw; return; } if(cw+w[i-1]<=c) { cw+=w[i-1]; backtrack(i+1); cw=cw-w[i-1]; } backtrack(i+1); } int main() { int i; printf("input the number of boxes and the volume of the ship:"); scanf("%d%d",&n,&c); w=new int ; printf("input the weights of each box:"); for(i=0;i<n;i++) scanf("%d",w+i); backtrack(1); printf("the result is %d.\n",bestw); return 0; }
2、加上限制,并输出最优解。限制的条件是如果可能取得最优解,进入右子树,否则不进入
#include <stdio.h> int n, c,cw, bestw, rest; int *w,*x; void backtrack(int i) { int j; if (i>n) { if(bestw<cw){ bestw=cw; for(j=0;j<n;j++) printf("%d ",x[j]); printf("\n"); } return; } rest=rest-w[i-1]; if(cw+w[i-1]<=c) { x[i-1]=1; cw+=w[i-1]; backtrack(i+1); cw=cw-w[i-1]; } if(cw+rest>bestw){ //利用当前的剪枝策略进行处理,如果加上所有剩余的有可能超过当前的最优,搜索右子树 x[i-1]=0; backtrack(i+1); } rest=rest+w[i-1]; } int main() { int i; printf("input the number of boxes and the volume of the ship:"); scanf("%d%d",&n,&c); rest=0; w=new int ; x=new int ; printf("input the weights of each box:"); for(i=0;i<n;i++){ x[i]=0; scanf("%d",w+i); rest=rest+*(w+i); } backtrack(1); printf("the result is %d.\n",bestw); return 0; }
3、非递归迭代回溯
//非递归迭代回溯 #include <stdio.h> int main() { int i,j,k; int n, c,cw=0, bestw=0, rest=0; int *w,*x,*bestx; printf("input the number of boxes and the volume of the ship:"); scanf("%d%d",&n,&c); w=new int ; x=new int ; bestx=new int ; printf("input the weights of each box:"); for(i=0;i<n;i++){ x[i]=0; scanf("%d",w+i); rest=rest+*(w+i); } i=1; while(true){ while(i<=n && cw+w[i-1]<=c){ rest=rest-w[i-1]; cw=cw+w[i-1]; x[i-1]=1; i++; } if(i>n) { for(j=0;j<n;j++) bestx[j]=x[j]; bestw=cw; } else{ rest=rest-w[i-1]; x[i-1]=0; i++; } while(cw+rest<=bestw){ i--; while(i>0 && !x[i-1]){ rest=rest+w[i-1]; i--; } if(i==0){ printf("the best result is %d\n",bestw); for(j=0;j<n;j++) printf("%d ",bestx[j]); putchar('\n'); break; } x[i-1]=0; cw=cw-w[i-1]; i++; } } return 0; }
4、暴力搜索
#include <stdio.h>
#include <math.h>
int main()
{
int i,j,num;
int max,temp;
int *w;
int n,c;
printf("input the number of boxes and the volume of the ship:");
scanf("%d%d",&n,&c);
w=new int
;
printf("input the weights of each box:");
for(i=0;i<n;i++)
scanf("%d",w+i);
max=0;
for(num=0;num<pow(2,n);num++)
{
temp=0; j=num;
for(i=0;i<n;i++)
{
if(j%2)
temp=temp+w[i];
j=j/2;
}
if(temp>max && temp<=c)
max=temp;
}
printf("the result is %d.\n",max);
return 0;
}
相关文章推荐
- 分支界定法:最大装载问题,获得最优路径(使用FIFO),深刻学习指针的引用的本质
- 回溯法解最优装载问题
- 最优装载问题_贪心算法
- 最优装载问题 回溯算法
- 最优装载问题
- 贪心算法之最优装载问题
- 悼念512汶川大地震遇难同胞――老人是真饿了(最优装载问题)
- 算法java实现--贪心算法--最优装载问题
- 贪心-最优装载问题
- Java语言描述:回溯法之最优装载问题
- 回溯法解最优装载问题
- 0034算法笔记——【分支限界法】最优装载问题
- hdu 2187 悼念512汶川大地震遇难同胞——老人是真饿了 贪心算法 之 最优装载问题
- 算法java实现--分支限界法--最优装载问题
- 回溯法最优装载问题(java)
- 贪心算法-最优装载问题
- 0022算法笔记——【贪心算法】背包问题,最优装载问题
- 使用STL处理分支限界法处理最优装载问题
- 贪心算法一:最优装载问题
- 回溯算法之最优装载问题