装载问题 回溯法java,回溯法解决装载问题

#include

#include

using namespace std;

typedef int* pointer;

template

class Loding{

friend Type MaxLoding(Type [],Type,int,int[]);

private:

void Backtrack(int i);

int n,//集装箱数

*x,//当前解

*bestx;//当前最优解

Type *w,//集装箱重量数组

c,//第一艘船的载重量

cw,//当前载重量

bestw,//当前最优载重量

r;//剩余集装箱重量

};

template

void Loding::Backtrack(int i)

{//搜索第i层节点

if(i > n){//到达叶节点

if(cw > bestw){

for(int j = 1;j <= n;j++)

bestx[j] = x[j];

bestw = cw;

}

return;

}

//搜索子树

r -= w[i];

if(cw + w[i] <= c){//搜索左子树

x[i] = 1;

cw += w[i];

Backtrack(i + 1);

cw -= w[i];

}

if(cw + r > bestw){//搜索右子树

x[i] = 0;

Backtrack(i+1);

}

r += w[i];

}

template

Type MaxLoding(Type w[],Type c,int n,int bestx[]){

//返回最优载重量

Loding X;

//初始化X

X.x = (int*)malloc( (n+1) * sizeof(int) );

X.w = w;

X.c = c;

X.n = n;

X.bestx = bestx;

X.bestw = 0;

X.cw = 0;

//初始化r

X.r = 0;

for(int i = 1;i <= n;i++)

X.r += w[i];

X.Backtrack(1);

delete []X.x;

return X.bestw;

}

template

void solveLoading(Type C2,int bestx[],int n,Type w[]){

int Weight = 0;//集装箱的总重量

int weightC1 = 0;//第一艘船上的集装箱的重量和

for(int i = 1;i <= n;i++){

Weight += w[i];

if(bestx[i]==1)

weightC1 += w[i];

}

if((Weight - weightC1) > C2)

printf("该装载问题无解!\n");

else

{

printf("装在第一艘船上的集装箱为:");

for(int i = 1;i <= n;i++){

if(bestx[i]==1)

printf("%d   ",i);

}

printf("\n装在第二艘船上的集装箱为:");

for(  i = 1;i <= n;i++){

if(0==bestx[i])

printf("%d     ",i);

}

}

}

void main(){

int C1,C2;//两艘船各自的载重量

printf("输入两艘船各自的载重量:");

scanf("%d %d",&C1,&C2);

int num;//集装箱数目

printf("\n输入集装箱数量:");

scanf("%d",&num);

int *x = (int*)malloc( (num+1) * sizeof(int) );//集装箱是否放入的记录

int *w = (int*)malloc( (num+1) * sizeof(int) );//每个集装箱的重量

printf("依次输入每个集装箱的重量:\n");

for(int i = 1;i <= num;i++)

scanf("%d",w+i);

MaxLoding(w,C1,num,x);

solveLoading(C2,x,num,w);

delete []x;

delete []w;

}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值