如果有一艘船,载重量为
m
m
m,有
n
n
n个货物重量为
w
1
,
w
2
,
.
.
.
.
.
.
,
w
n
w_1, w_2, ...... ,w_n
w1,w2,......,wn
请问这艘船最大可以承载多少重量的货物,请给出一个最优的装载方案。
下面用一个具体例子解决此问题。
令 m = 66, n = 7, w = [10,20,30,50,50,70,40]
运行结果:
0表示不装,1表示装
可以使用分支限界算法
解决此问题, 代码如下:
#include <iostream>
#include <queue>
#include <string>
#define MAX_V 256
using namespace std;
struct Node{
int l; //树中的层次
int p; //堆中的位置
int w; //已经累积的重量
Node(int l = 0, int p = 1, int w = 0){
this->l = l;
this->p = p;
this->w = w;
}
};
/* 最大装载问题
* ws : 各货物重量
* n : 货物个数
* m : 最大装载量
* */
Node maxLoading(int ws[], int n, int m){
queue<Node> q; //初始化队列
Node solve; //最优解
//算法开始
q.push(solve);
while(!q.empty()){
Node node = q.front();
q.pop();
if(node.l == n){
if(node.w > solve.w){
solve = node;
}
continue;
}
int extra = 0;
for(int i = node.l - 1; i < n; i++){
extra += ws[i];
}
if(node.w + extra > solve.w){ // 剪枝 (如果加上剩下所有都不能比当前解大, 则剪去)
//左边(总是可行)
q.push(Node(node.l + 1, node.p * 2, node.w));
//右边
int weight = node.w + ws[node.l];
if(weight <= m) { //剪枝(如果重量过大,则剪去右边)
q.push(Node(node.l + 1, node.p * 2 + 1, weight));
}
}
}
return solve;
}
//构造最优解(不是重点)
void traceback(int s){
string str = "";
while(s > 1){
if(s % 2 == 0){
str += "0";
}else{
str += "1";
}
s /= 2;
}
for(int i = str.size() - 1; i >= 0; i--){
cout << str[i] << " ";
}
}
int main(){
int ws[] = {10,20,30,50,50,70,40};
Node solve = maxLoading(ws, 7, 66);
cout << "max load = "<< solve.w << endl;
cout << "sovle: ";
traceback(solve.p);
return 0;
}