裝載問題 回溯法

2021-10-07 05:00:49 字數 2426 閱讀 6097

有n個貨櫃要裝上2艘載重量分別為c1和c2的輪船,其中貨櫃i的重量為wi,且

問題:

是否有乙個合理的裝載方案,可將這n個貨櫃裝上這2艘輪船?如果有,找出一種裝載方案。

例如:當n=3, c1=c2=50

(1)若w=[10, 40, 40]

可將貨櫃1和貨櫃2裝上第一艘輪船,而將貨櫃3裝上第二艘輪船;

(2)如果w=[20, 40, 40]

則無法將這3個貨櫃都裝上船;

已證明,如果乙個給定裝載問題有解,則採用下面的策略可得到最優裝載方案。

1.首先將第一艘輪船盡可能裝滿;

2.將剩餘的貨櫃裝上第二艘輪船。

將第一艘輪船盡可能裝滿等價於選取全體貨櫃的乙個子集,使該子集中貨櫃重量之和最接近c1。由此可知,裝載問題等價於以下特殊的0-1揹包問題。

表示解空間,則解為n元向量, xi∈ 。

約束條件

當前搜尋的層i <= n時,當前擴充套件結點z為子集樹的內部結點,僅當滿足cw+w[i] <= c時進入左子樹,x[i]=1; 當cw+w[i] > c,在以結點z為根的子樹中所有結點都不滿足約束條件,因而該子樹中解都是不可行解,因而將在該子樹刪去。

限界函式

由於是最優化問題, 可利用最優解性質進一步剪去不含最優解的子樹:

設z是解空間樹第i層上的當前擴充套件結點。

設     bestw: 當前最優載重量,

cw : 當前擴充套件結點z的載重量 ;

r : 剩餘貨櫃的重量;

在以z為根的子樹中任意葉結點所相應的載重量不超過cw + r。因此,當cw + r (限界函式) ≤ bestw時,可將z的右子樹剪去。即:cw + r > bestw 時搜尋右子樹,x[i]=0;

演示分析過程

;//搜尋子樹

if(cw+w[i]

<=c)

if(cw+r > bestw)

r+=w[i]

#include using namespace std;

int n; //貨櫃數

int cw; // 當前載重量, current weight

int bestw; //最優載重重量

int r; //剩餘貨櫃重量

int c1; //第一艘輪船的載重量

int c2; //第二艘輪船的載重量

int x[100]; //當前解

int bestx[100]; //當前最優解

int w[100]; //貨櫃重量陣列

void output()

return;

}r -= w[i];

if(cw + w[i] <= c1) //約束條件

if(cw + r > bestw) //限界函式

r += w[i];

}void initialize()

void input()

int main()

輸入請輸入箱子個數:4

請輸入兩艘船的最大載重量:100 100

請輸入箱子的重量:90 10 80 10

輸出

船1裝入的貨物為: 1 2

船2裝入的貨物為: 3 4

輸入

請輸入箱子個數:4

請輸入兩艘船的最大載重量:100 100

請輸入箱子的重量:90 20 90 10

輸出

不能裝入

裝載問題 回溯法

描述 有一批共n個貨櫃要裝上艘載重量為c的輪船,其中貨櫃i的重量為wi。找出一種最優裝載方案,將輪船盡可能裝滿,即在裝載體積不受限制的情況下,將盡可能重的貨櫃裝上輪船。輸入 由檔案load.in給出輸入資料。第一行有2個正整數n和c。n是貨櫃數,c是輪船的載重量。接下來的1行中有n個正整數,表示貨櫃...

回溯法 裝載問題

有n個貨櫃要裝上載重量為w的輪船,其中貨櫃i的重量為wi。不考慮貨櫃體積的限制,現在要將若干貨櫃裝上輪船,使他們的總重量為w,如果總重量相同要盡可能的使用少的貨櫃。有n個貨櫃要裝上載重量為c1 c2的輪船,其中貨櫃i的重量為wi。問兩艘輪船能否裝下所有貨櫃。深搜所有情況,重點是要剪枝。題目一剪枝條件...

裝載問題 回溯法

有一批共 n n n 個貨櫃要裝上艘載重量為 c c c 的輪船,其中貨櫃 i i i 的重量為 w i wi wi。找出一種最優裝載方案,將輪船盡可能裝滿,即在裝載體積不受限制的情況下,將盡可能重的貨櫃裝上輪船。第一行有 2 個正整數 n n n 和 c c c。n n n 是貨櫃數,c c c ...