有一批集装箱,要装上一艘载重量为c的轮船。其中集装箱i的重量为wi。
最优装载问题要求确定在装载体积不受限制的情况下,将尽可能多的集装箱装上轮船。
最优装载问题问题的形式描述:
•问题的形式描述是:给定c>0,wi>0,1≤i≤n,求n元0-1向量
(x1, x2, …, xn),使得
输入:集装箱的数目n,船的载重量c,集装箱i的重量为wi。
输出:集装箱i是否装船,是的话输出1,反之输出0.
运行结果:
最优装载问题可用贪心算法求解。采用重量最轻者先装的贪心选择策略,可产生最优装载问题的最优解。
根据w从小到大排序,t中保存数组下标,用的是简单的冒泡排序。
template <class Type>
void Sort(Type *w, Type *t, int n)
{
int i, j;
for(i = 1; i <= n; i++)
t[i] = i;
for(i = 1; i <= n; i++)
for(j = i+1; j <= n; j++)
if(w[t[i]] > w[t[j]])
swap(t[i], t[j]);
}
主要计算量为按照重量从小到大排序,算法时间复杂度O(nlogn).
template <class Type>
void Loading(int *x, Type *w, Type c, int n)
{
int *t, i;
t = new int[n+1];
for(i = 1; i <= n; i++) //初值
x[i] = 0;
Sort(w, t, n); //t按重量排序的数组下标
for(i = 1; i <= n && w[t[i]] <= c; i++)
{
x[t[i]] = 1;
c -= w[t[i]];
}
}
贪心选择性质:
设集装箱已按其重量由小到大排序, (x1, x2, …, xn)是最优装载问题的一个最优解. 令
若给定最优装载问题有解, 则1≤k ≤n.
(1) 当k=1时, (x1, x2, …, xn)是一个满足贪心选择性质的最优解;
(2) 当k>1时, 取y1=1, yk=0, yi=xi, 1<i≤n, i≠k, 则
故(y1, y2, …, yn)是所给最优装载问题的一个可行解.
而由(y1+ y2+ … + yn)= (x1+ x2+ …+ xn)知, (y1, y2, …, yn)是一个满足贪心选择性质的最优解.
最优装载问题具有贪心选择性质。
最优子结构性质:
若(x1, x2, …, xn)是最优装载问题的一个满足贪心选择性质的最优解, 则有x1=1。
(x2, …, xn)是轮船载重量为c-w1且待装集装箱为{2, 3, …, n}时, 相应最优装载问题的一个最优解.
最优装载问题具有最优子结构性质。
由最优装载问题的贪心选择性质和最优子结构性质,容易证明算法loading的正确性。
算法loading的主要计算量在于将集装箱依其重量从小到大排序,故算法所需的计算时间为 O(nlogn)。