貪心算法之最優裝載問題
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貪心選擇性質
設集裝箱依其重量從小到大排序,\((x_1,x_2,\ldots,x_n)\)是其最優解,\(x_i=\{0, 1\}\),設\(x_k\)是第一個等於1的。
(1) 如\(k = 1\),則滿足貪心選擇性質
(2) 如\(k \neq 1\),用\(x_1\)替換\(x_k\),構造的新解同原解最優值相同,故也是最優解,滿足貪心選擇性質
該證明方法只證明了任何一個最優解都可以轉換為第一個集裝箱上船的最優解(滿足貪心策略)。此方法對子問題同樣有效,因此可以將一個普通最優解轉化為滿足貪心策略的最優解。如\((0 1 0 1) \Rightarrow (1 1 0 0)\)
2.4.最優子結構性質
最優裝載問題具有最優子結構性質,設1至n個集裝箱裝上船的最大數量為\(T(1, n, w)\),則\(T(1, n, w) = 1 + T(2, n, w - w_1)\);因\(T(1, n, w)\)是最優值,則\(T(2, n, w - w_i)\)一定是最優值,反證法證明之
反證法:
如果\(T(2, n, w - w_1)\)不是該問題的最優解,則存在最優值\(T'(2, n, w - w_1) > T(2, n, w - w_1)\),則\(1 + T'(2, n, w - w_1) = T'(1, n, w) > T(1, n, w)\),這與大前提\(T(1, n, w)\)是最優值相矛盾,故\(T(2, n, w - w_1)\)一定是最優值。