最优装载问题
贪心算法之最优装载问题

贪⼼算法之最优装载问题1. 问题描述: 给出n个物体,第i个物体的重量是Wi,选择尽量多的物体,使得总重量不超过C.2. 问题分析: 这是⼀个很典型的⽤贪⼼算法的题⽬.要想让装的物体越多,⾃然装的最轻的物体就越多.因此可以对物体的重量由⼩到⼤进⾏排序,然后依次装载即可.这就体现了贪⼼算法只顾眼前,但却可以得到最优解.3. 解决问题: 代码如下4. 1 #include <stdio.h>2 #include <stdlib.h>3 #include <string.h> //为了引⼊memcpy4/* 最有最优装载问题:5给出n个物体,第i个物体的重量为Wi,选择更多的物体,是物体的总量不超过C6*/7void swap(int *a,int *b)8 {9int temp;10 temp = *a;11 *a = *b;12 *b = temp;13 }14// 采⽤选择法对重量进⾏排序,t中记录的是从⼩到⼤的包的索引15void sortweight(int *w,int *t,int n)16 {17int i,j,temp;18int *w1 = malloc(sizeof(int)*n);19for(i =0; i < n; ++i)20 {21 t[i] = i;22 w1[i] = w[i];23 }24for(i = 0; i < n; ++i)25 {26 temp = i;27for(j = i+1; j < n; ++j)28 {29if(w1[j] < w1[temp])30 temp = j;31 }32if(temp != i)33 {34 swap(&w1[i],&w1[temp]); // 这个数据交换是必须的35 swap(&t[i],&t[temp]);36 }37 }38 }39int main()40 {41int n,weight_max,i;42int *w,*ind,*res;4344 printf("请输⼊商品的数量和商品的总载量\n");45 scanf("%d %d",&n,&weight_max);4647 w = malloc(sizeof(int)*n);48 ind = malloc(sizeof(int)*n);49 res = malloc(sizeof(int)*n);5051 printf("请依次输⼊商品的重量\n");52for(i = 0; i < n; ++i)53 scanf("%d",&w[i]);5455 sortweight(w,ind,n);5657for(i = 0; i < n && w[ind[i]] <= weight_max; ++i)58 {59 res[ind[i]] = 1;60 weight_max -= w[ind[i]];61 }62 printf("贪⼼算法求解后的结果是:\n");63for(i = 0; i < n; ++i)64 {65 printf("%d ",res[i]);66 }67 printf("\n");68return0;69 }4. 程序分析: 由于不要改变原始物体重量的值,所以在排序的时候要另外再开辟⼀个数组存储重量.并且另外开辟ind[]存放索引记录装载的顺序.ind[]存放的是重量数组中每个元素在这组数组中⼤⼩的顺序(索引).怎样在排序时记录索引需要在练习排序的时候注意下.。
装载问题5种项目解决方案

.. . .. . ..算法分析与设计2016/2017(2)实验题目装载问题5种解法学生姓名学生学号. 专业学习资料... . .. . ..学生班级任课教师提交日期2017计算机科学与技术学目录一问题定义 (4)二解决方案 (4)1优先队列式分支限界法求解 (4)1.1算法分析 (4)1.2代码 (4)1.3运行结果 (17)2队列式分支限界法求解 (17)2.1算法分析 (17)2.2代码 (18)2.3测试截图 (30)3回朔法-迭代 (30)3.1算法分析 (30)3.2代码 (30)3.3测试截图 (35)4回朔法-递归 (35)4.1算法分析 (35)4.2代码 (35). 专业学习资料... . .. . ..4.3测试截图 (41)5贪心算法 (42)5.1算法分析 (42)5.2代码 (42)5.3测试截图 (46). 专业学习资料.一问题定义有一批共有n 个集装箱要装上两艘载重量分别为c1 和c2 的轮船,其中集装箱i 的重量为w[i], 且重量之和小于(c1 + c2)。
装载问题要求确定是否存在一个合理的装载方案可将这n 个集装箱装上这两艘轮船。
如果有,找出一种装载方案。
二解决方案1优先队列式分支限界法求解1.1算法分析活结点x在优先队列中的优先级定义为从根结点到结点x的路径所相应的载重量再加上剩余集装箱的重量之和。
优先队列中优先级最大的活结点成为下一个扩展结点。
以结点x为根的子树中所有结点相应的路径的载重量不超过它的优先级。
子集树中叶结点所相应的载重量与其优先级相同。
在优先队列式分支限界法中,一旦有一个叶结点成为当前扩展结点,则可以断言该叶结点所相应的解即为最优解。
此时可终止算法。
1.2代码1.2-1////MaxHeap.htemplate<class T>class MaxHeap{public:MaxHeap(int MaxHeapSize = 10);~MaxHeap() {delete [] heap;}int Size() const {return CurrentSize;}T Max(){ //查找if (CurrentSize == 0){throw OutOfBounds();}return heap[1];}MaxHeap<T>& Insert(const T& x); //增MaxHeap<T>& DeleteMax(T& x); //删void Initialize(T a[], int size, int ArraySize);private:int CurrentSize, MaxSize;T *heap; // element array};template<class T>MaxHeap<T>::MaxHeap(int MaxHeapSize){// Max heap constructor.MaxSize = MaxHeapSize;heap = new T[MaxSize+1];CurrentSize = 0;}template<class T>MaxHeap<T>& MaxHeap<T>::Insert(const T& x){// Insert x into the max heap.if (CurrentSize == MaxSize){cout<<"no space!"<<endl;return *this;}// 寻找新元素x的位置// i——初始为新叶节点的位置,逐层向上,寻找最终位置int i = ++CurrentSize;while (i != 1 && x > heap[i/2]){// i不是根节点,且其值大于父节点的值,需要继续调整heap[i] = heap[i/2]; // 父节点下降i /= 2; // 继续向上,搜寻正确位置}heap[i] = x;return *this;}template<class T>MaxHeap<T>& MaxHeap<T>::DeleteMax(T& x){// Set x to max element and delete max element from heap. // check if heap is emptyif (CurrentSize == 0){cout<<"Empty heap!"<<endl;return *this;}x = heap[1]; // 删除最大元素// 重整堆T y = heap[CurrentSize--]; // 取最后一个节点,从根开始重整// find place for y starting at rootint i = 1, // current node of heapci = 2; // child of iwhile (ci <= CurrentSize){// 使ci指向i的两个孩子中较大者if (ci < CurrentSize && heap[ci] < heap[ci+1]){ci++;}// y的值大于等于孩子节点吗?if (y >= heap[ci]){break; // 是,i就是y的正确位置,退出}// 否,需要继续向下,重整堆heap[i] = heap[ci]; // 大于父节点的孩子节点上升i = ci; // 向下一层,继续搜索正确位置ci *= 2;}heap[i] = y;return *this;}template<class T>void MaxHeap<T>::Initialize(T a[], int size,int ArraySize){// Initialize max heap to array a.delete [] heap;heap = a;CurrentSize = size;MaxSize = ArraySize;// 从最后一个内部节点开始,一直到根,对每个子树进行堆重整 for (int i = CurrentSize/2; i >= 1; i--){T y = heap[i]; // 子树根节点元素// find place to put yint c = 2*i; // parent of c is target// location for ywhile (c <= CurrentSize){// heap[c] should be larger siblingif (c < CurrentSize && heap[c] < heap[c+1]) {c++;}// can we put y in heap[c/2]?if (y >= heap[c]){break; // yes}// noheap[c/2] = heap[c]; // move child upc *= 2; // move down a level}heap[c/2] = y;}}1.2-2///6d3-2.cpp//装载问题优先队列式分支限界法求解#include "stdafx.h"#include "MaxHeap.h"#include <iostream>using namespace std;const int N = 4;class bbnode;template<class Type>class HeapNode{template<class Type>friend void AddLiveNode(MaxHeap<HeapNode<Type>>& H,bbnode *E,Type wt,bo ol ch,int lev);template<class Type>friend Type MaxLoading(Type w[],Type c,int n,int bestx[]);public:operator Type() const{return uweight;}private:bbnode *ptr; //指向活节点在子集树中相应节点的指针Type uweight; //活节点优先级(上界)int level; //活节点在子集树中所处的层序号};class bbnode{template<class Type>friend void AddLiveNode(MaxHeap<HeapNode<Type>>& H,bbnode *E,Type wt,bo ol ch,int lev);template<class Type>friend Type MaxLoading(Type w[],Type c,int n,int bestx[]);friend class AdjacencyGraph;private:bbnode *parent; //指向父节点的指针bool LChild; //左儿子节点标识};template<class Type>void AddLiveNode(MaxHeap<HeapNode<Type>>& H,bbnode *E,Type wt,bool ch,int l ev);template<class Type>Type MaxLoading(Type w[],Type c,int n,int bestx[]);int main(){float c = 70;float w[] = {0,20,10,26,15};//下标从1开始int x[N+1];float bestw;cout<<"轮船载重为:"<<c<<endl;cout<<"待装物品的重量分别为:"<<endl;for(int i=1; i<=N; i++){cout<<w[i]<<" ";}cout<<endl;bestw = MaxLoading(w,c,N,x);cout<<"分支限界选择结果为:"<<endl;for(int i=1; i<=4; i++){cout<<x[i]<<" ";}cout<<endl;cout<<"最优装载重量为:"<<bestw<<endl;return 0;}//将活节点加入到表示活节点优先队列的最大堆H中template<class Type>void AddLiveNode(MaxHeap<HeapNode<Type>>& H,bbnode *E,Type wt,bool ch,int l ev){bbnode *b = new bbnode;b->parent = E;b->LChild = ch;HeapNode<Type> N;N.uweight = wt;N.level = lev;N.ptr = b;H.Insert(N);}//优先队列式分支限界法,返回最优载重量,bestx返回最优解template<class Type>Type MaxLoading(Type w[],Type c,int n,int bestx[]){//定义最大的容量为1000MaxHeap<HeapNode<Type>> H(1000);//定义剩余容量数组Type *r = new Type[n+1];r[n] = 0;for(int j=n-1; j>0; j--){r[j] = r[j+1] + w[j+1];}//初始化int i = 1;//当前扩展节点所处的层bbnode *E = 0;//当前扩展节点Type Ew = 0; //扩展节点所相应的载重量//搜索子集空间树while(i!=n+1)//非叶子节点{//检查当前扩展节点的儿子节点if(Ew+w[i]<=c){AddLiveNode(H,E,Ew+w[i]+r[i],true,i+1); }//右儿子节点AddLiveNode(H,E,Ew+r[i],false,i+1);//取下一扩展节点HeapNode<Type> N;H.DeleteMax(N);//非空i = N.level;E = N.ptr;Ew = N.uweight - r[i-1];}//构造当前最优解for(int j=n; j>0; j--){bestx[j] = E->LChild;E = E->parent;}return Ew;}1.3运行结果2队列式分支限界法求解2.1算法分析在算法的循环体中,首先检测当前扩展结点的左儿子结点是否为可行结点。
最佳装载问题的证明

x y
i 1 i i 1
最佳装载问题的证明
贪心算法一定能求得问题的最优解的例子。 设某邮政车的载重量为 c ,有 n 件邮包,每件入车内, 装载的总重量不能超过邮政车的载重 量,最佳装载要求所装入邮包的数量最大(设邮政车的容积足够大) 。
证明:令 x [ x1 ,, xn ] 为贪心算法获得的解,其中 x i =1 表示装载, 为 x i =0 表示不装载,类似的令 y 需要证明
i 1 i i 1
n
n
i
。若存在这样的 j ,则 j k ,否则 y 就不是一个可
行解。因为 x j
y j , x j 1 ,所以 y j 0 。这样的话,令 y j 1 ,若得到的
y 不是可行解,则在 j 1, n 范围内必有一个 l 使得 yl 1 。令 yl 0 ,由于
[ y1 ,, yn ] 为任意一个可行解,只
x y
i 1 i i 1
n
n
i
。不失一般性,可以假设邮包都排好序了,即
wi wi 1 1 i n ,然后分几步将 y 转化为 x ,转化过程中每一步都
产生一个可行的新 y ,且 明
y 大于等于未转化前的值,最后便可以证
n
n
i
,证明完毕。
i 1 i
n
x y
i 1 i i 1
n
n
i
最优装载问题

3基于背包和装载数量限制分类类
4基于所装物品的依赖性分类
001 基于背包的限制条件分类
···
002 基于待选择装载物品的数量分类
···
003 基于背包和装载数量限制分类
···
004 基于所装物品的依赖性分类
···
根据所装物品的依赖性,可将最优装载问题分为“分组的最优转载 问题”和“有依赖的最优装载问题”
必需品编号
1
2
3
4
5
6
7
体积(升)
4
3
1.5
2.5
4.5
7.6
1.9
1 可选带物品编号
2
3
4
5
6
7
8
体积(升) 2.5 4
5.5
4.8
3.7
1.6
7.5
4.5
价格(元) 20 50 105
75
55
80
200 100
最优装载问题的数学抽象就是著名的背包问题
案例 2
货轮装载问题:有一艘货轮分为前、中、后三个舱位,其容积与最大允
“分组的最优装载问题”就是把待装物品分为若干组,每组中至多 选一件装载;
“有依赖的最优装载问题”就是选择某一待装载物品,必须选择另 一个物品装载。
小结 最优装载问题不同类型之间的组合情况
···
分组问题 二维费用问题
0-1问题 完全装载 多重装载
分组问题
二维费用问题
0-1问题 完全装载 多重装载
分组问题
3 最优装载问题的MATLAB求解
···
3 最优装载问题的MATLAB求解
···
标题4 案 例 模型
1
算法中的最优装载问题

算法中的最优装载问题问题描述有n个集装箱要装上1艘载重量分别为c的轮船,其中第i个集装箱的重量为wi。
最优装载问题要求确定在装载体积不受限制的情况下,将尽可能多的集装箱装上轮船,并找出一种装载方案其中@w #集装箱的重量数组@c #货船的最大载重量@n #集装箱的个数@r #未被装载的货物重量@cw #当前货船上的载重@i #搜索树的层数@bestw #最优值@bestx #最优解class Loadingdef initialize(weight,cont)@w,@c,@n=weight,cont,weight.length@r,@cw,@i,@bestw=0,0,0,0@x=Array.new@bestx=Array.newfor j in 0..@n-1@r=@r+@w[j];@bestx[j],@x[j]=0,0endprint \\"集装箱的总重量为 #@r,\\n\\"enddef MaxLoadingwhile truewhile @i<=(@n-1) and (@cw+@w[@i]<@c)@r-=@w[@i]@cw+=@w[@i]@x[@i]=1print \\"在左子树中\\",@x[@i],\\"\\n\\"@i+=1endif @i>@n-1for j in 0..@n-1@bestx[j]=@x[@i]print \'到达叶子节点\',j,\\"\\t @bestx[j]\\",@bestx[j],\\"\\n\\" end@bestw=@cwelse@r-=@w[@i];@x[@i]=0;print \'在右子树中\',@x[@i],\\"\\n\\" @i+=1endwhile @cw+@r<=@bestw@i-=1while @i>=0 and (@x[@i]==0)@r+=@w[@i];@i-=1endif @i==-1 thenprint \\"@bestw:\\",@bestwreturnend@x[@i]=0@cw-=@w[@i]@i+=1endendendendweight=[30,10,10]cont=35s=Loading.new(weight,cont)s.MaxLoading运行的结果如下:集装箱的总重量为 50,在左子树中1在右子树中0在右子树中0到达叶子节点0 @bestx[j]nil到达叶子节点1 @bestx[j]nil到达叶子节点2 @bestx[j]nil@bestw:30>Exit code: 0。
贪心算法之最优装载问题

贪⼼算法之最优装载问题贪⼼算法之最优装载问题1. 问题描述有⼀批集装箱要装上⼀艘重量为c的轮船,其中集装箱i的重量为W i。
最优装载问题要求确定在装载体积不受限制的情况下,将尽可能多的集装箱装上轮船。
2. 问题分析2.1确定贪⼼策略采⽤重量最轻者先装的贪⼼选择策略,可产⽣该问题的最优解。
2.2代码求解/*** x[] 保存最优解路径数组* w[] 集装箱重量数组* c 船的载重量* n 集装箱的数量**/void Loading(int x[], int w[], int c, int n) {// 按照集装箱重量从⼩到⼤排序sort(w, n);for (int i = 1; i <= n; i++)x[i] = 0;for (int i = 1; i <= n && w[i] <= c; i++) {x[i] = 1;c -= w[i];}}2.3贪⼼选择性质设集装箱依其重量从⼩到⼤排序,(x1,x2,…,x n)是其最优解,x i={0,1},设x k是第⼀个等于1的。
(1) 如k=1,则满⾜贪⼼选择性质(2) 如k≠1,⽤x1替换x k,构造的新解同原解最优值相同,故也是最优解,满⾜贪⼼选择性质该证明⽅法只证明了任何⼀个最优解都可以转换为第⼀个集装箱上船的最优解(满⾜贪⼼策略)。
此⽅法对⼦问题同样有效,因此可以将⼀个普通最优解转化为满⾜贪⼼策略的最优解。
如(0101)⇒(1100)2.4.最优⼦结构性质最优装载问题具有最优⼦结构性质,设1⾄n个集装箱装上船的最⼤数量为T(1,n,w),则T(1,n,w)=1+T(2,n,w−w1);因T(1,n,w)是最优值,则T(2,n,w−w i)⼀定是最优值,反证法证明之反证法:如果T(2,n,w−w1)不是该问题的最优解,则存在最优值T′(2,n,w−w1)>T(2,n,w−w1),则1+T′(2,n,w−w1)=T′(1,n,w)>T(1,n,w),这与⼤前提T(1,n,w)是最优值相⽭盾,故T(2,n,w−w1)⼀定是最优值。
最优装载问题

for(int j=n-1;j>0;j--)
r[j]=r[j+1]+w[j+1];
int i=1;
bbnode *E=0;
int Ew=0;
b->Lchild=ch; //cout<<"b->Lchild"<<b->Lchild<<endl;
HeapNode N;
N.uweight=wt;
N.level=lev;
};
//template <class int>
class MaxHeap{
friend void AddLiveNode(MaxHeap&,bbnode *,int,int,int );
friend int Maxloading(int*,int,int,int*);
// template<class int>
int MaxLoading(int w[],int c,int n,int bestw[])
{
MaxHeap H(20);
int *r=new int[n+1];
return N;
}
};
////////////////////////////////////////////////////////////////////
// template<class int> //将活节点加入到最大堆H中
}
AddLiveNode(H,E,Ew+r[i],0,i+1); // 右儿子节点
HeapNode N;
英语 算法 -回复

英语算法-回复如何使用贪心算法(Greedy Algorithm)解决最优装载问题(Knapsack Problem)。
【引言】贪心算法是一种基于局部最优选择的算法思想,可用于解决最优装载问题,即在给定容量的背包中,如何选择物品使其总价值最大。
本文将介绍如何使用贪心算法逐步解决最优装载问题,帮助读者更好地理解和应用贪心算法。
【步骤一:问题描述】首先,让我们明确最优装载问题的具体要求。
给定一个背包的容量C和N 个物品,每个物品有自己的重量w和价值v。
我们的目标是在不超过背包容量的情况下,选择物品放入背包,使得放入背包的物品的总价值最大。
【步骤二:贪心选择策略】贪心算法的核心思想是进行局部最优选择,以期望最终得到整体最优解。
对于最优装载问题,我们可以采用“单位重量价值最大”的贪心选择策略。
即优先选择单位重量价值最大的物品放入背包中,直至背包无法再放入物品。
【步骤三:算法实现】基于贪心选择策略,我们可以使用如下步骤实现算法:1. 根据物品的重量w和价值v,计算每个物品的单位重量价值vu = v / w。
2. 按照单位重量价值vu从大到小对物品进行排序。
3. 初始化当前背包的总价值val = 0和当前背包的剩余容量rc = C。
4. 逐个遍历排序后的物品列表:a. 如果当前物品的重量小于等于当前背包的剩余容量,则将该物品放入背包中,更新当前背包的总价值val和剩余容量rc。
b. 如果当前物品的重量大于当前背包的剩余容量,则放弃该物品,继续遍历下一个物品。
5. 返回最终的背包总价值val作为最优装载问题的解。
【步骤四:算法示例】接下来,我们通过一个简单的例子演示如何使用贪心算法解决最优装载问题。
假设背包容量C为10,有以下4个物品可供选择:物品1:重量w1 = 2,价值v1 = 5物品2:重量w2 = 3,价值v2 = 8物品3:重量w3 = 4,价值v3 = 9物品4:重量w4 = 5,价值v4 = 10按照贪心选择策略,首先计算每个物品的单位重量价值vu:物品1:vu1 = v1 / w1 = 5 / 2 = 2.5物品2:vu2 = v2 / w2 = 8 / 3 ≈2.67物品3:vu3 = v3 / w3 = 9 / 4 = 2.25物品4:vu4 = v4 / w4 = 10 / 5 = 2.0然后,按照单位重量价值vu从大到小对物品进行排序:物品2 > 物品1 > 物品3 > 物品4接下来,我们按照步骤三中的算法实现进行装载:初始化当前背包的总价值val = 0和剩余容量rc = 10。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
代码实现
编号为6,2,5,7,3,0的集装箱总重量为 390单位且已被装载,剩余的装载容量为10个 单位,小于剩余任一集装箱的重量。问题结束。 在这个贪心解决算法中通过flag数组中的结果 可以得到 [x0,x1,…,x7]=[1,0,1,1,0,1,1,1],且∑xi = 6, i = 0 to 7 总的时间复杂度为O(n2)+c*O(n),即O(n2)
实现原理
每次选择时,从剩下的集装箱中,选择重量最 小的集装箱。通过这样的选择可以保证已经选 出来的集装箱总重量最小,装载的集装箱数量 最多,直到船只不能再继续装载为止。
证明
考虑任意装载容量为K的非空子问题Sk,令am 是Sk中重量最小的集装箱,则am在Sk的某个 集装箱装载数量最多且总重量最少的最优子集 中。 证明:令Ak是Sk的一个最优子集,且aj是Ak中 重量最小的集装箱。若aj=am,则证明am在Sk 的某个最优子集中。若aj≠am,则将Ak中的aj替 换为am得到Ak’,am<=aj。由于|Ak’| = |Ak|,所 以Ak’也是Sk的一个集装箱装载数量最多的的 最优子集,且它包含am。
([W0,W2,…,W7] = [100,200,50,90,150,50,20,80], 船只载重c=400)
代码实现—截图
致谢
感谢刘东林老师给予这次讲课机会 感谢邵舒迪同志的帮助 Thanks for your attentions
参考: 《算法导论》第三版 十六章 定理16.1; 互联网:/p-422844096.html ;
贪心性质
通过上述证明我们可以知道,每次比较计算得 到最小的集装箱,它在最优解中,选出来之后, 对余下的集装箱(子问题)采取同样的策略选 取最轻的集装箱,放入最优解当中,得到局部 最优解,这样逐步缩小问题规模即缩小剩余载 重量。最终得到全局最优解。
代码实现
系统环境: Win7操作系统 开发平台: DEV-C++ 4.9.9.1
代码实现
//累加重量 计算可装载集装箱数量 maxLoad = 500; countLoad = 0; quantity = 0; for(i=0;i<8;i++){ //如果还能继续装载 if(boxes[i].weight <= maxLoad - countLoad){ countLoad = countLoad + boxes[i].weight; //计算最大装载数量quantity quantity ++; //获取装载标记 flag[boxes[i].index] = 1;}} 时间复杂度O(n)
代码实现
问题实例 假设集装箱数量n=8, 八个集装箱的重量是 [W0,W2,…,W7]= [100,200,50,90,150,50,20,80], 船只载重c=400。 求该条件下的最优装载问题。
代码实现—数据结构
// 集装箱 结构体 typedef struct box{ int weight;//重量 int index; //初始序号 };
代码实现
//比较子函数 int cmp (const void *a, const void *b){ if(((struct box*)a)->weight > ((struct box*)b)->weight) return 1; else return 0; } //按集装箱重量对集装箱进行快速排序 qsort(boxes,8,sizeof(struct box),cmp); 时间复杂度为O(n2)
简介
问题描述 实现原理 贪心性质 代码实现 致谢
问题描述
Байду номын сангаас
有一批集装箱要装上一艘载重量为 c的轮船。 第 i个集装箱的重量为 Wi。 最优装载问题要求在装载体积不受限制的情况 下,将尽可能多的集装箱装上轮船。
问题描述
问题可形式化描述为: 设: xi表示第i个集装箱是否装载, xi = 0 or 1, i = 1 to n; 求: Max(x1+x2+…+xn) 约束条件: W1*x1 + W2*x2 + … + Wn*xn <= c