有n個貨櫃要裝上一艘載重量為w的輪船,其中貨櫃i(1≤i≤n)的重量為wi。不考慮貨櫃的體積限制,現要從這些貨櫃中選出重量和小於等於w並且盡可能大的若干裝上輪船。
例如,n=5,w=10,w=時,其最佳裝載方案是(1,1,0,0,1)或者(0,0,1,1,0),maxw=10。
採用帶剪枝的回溯法求解。問題的表示如下:
int w=; //各貨櫃重量,不用下標0的元素
int n=5,w=10;
求解的結果表示如下:
int maxw=0; //存放最優解的總重量
int x[maxn]; //存放最優解向量
將上述資料設計為全域性變數。
求解演算法如下:
void dfs(int i,int tw,int rw,int op)
其中引數i表示考慮的貨櫃i,tw表示選擇的貨櫃重量和,rw表示剩餘貨櫃的重量和(初始時為全部貨櫃重量和),op表示乙個解,即對應乙個裝載方案。
最優解:x,maxw
左剪枝:僅僅擴充套件tw+w[i]≤w的左孩子結點
右剪枝:僅僅擴充套件tw+rw-w[i]>maxw的右孩子結點
int w=
;int n =
5, w =10;
int maxw =0;
int x[max]
;//存放最優解
void
dfs(
int i,
int tw,
int rw,
int op)
}else
if(tw + rw - w[i]
> maxw)
//右剪枝
}}
有一批共n個貨櫃要裝上兩艘載重量分別為c1和c2的輪船,其中貨櫃i的重量為wi,且w1+w2+…+wn≤c1+c2。
裝載問題要求確定是否有乙個合理的裝載方案可將這些貨櫃裝上這兩艘輪船。如果有,找出一種裝載方案。
例如:n=3,c1=c2=50,w=時,可以將貨櫃1和2裝到第一艘輪船上,而將貨櫃3裝到第二艘輪船上。
n=3,c1=c2=50,w=,則無法將這3個貨櫃都裝上輪船。
如果乙個給定的複雜裝載問題有解,則可以採用如下方式得到乙個裝載方案:
首先將第一艘輪船盡可能裝滿,然後將剩餘的貨櫃裝在第二艘輪船上。
可以用反證法證明其正確性。
如果這樣做得不到乙個裝載方案,說明該複雜裝載問題沒有解!
演算法思路(輸入為w1,w2,…,wn,c1,c2):
(1)將盡可能多的貨櫃裝到第一艘輪船上,得到解向量x。
(2)累計第一艘輪船裝完後剩餘的貨櫃重量sum。
(3)若sum<=c2,表示第二艘輪船可以裝完,返回true;否則表示第二艘輪船不能裝完,返回false。
int w=
;int n =3;
int c1 =
50, c2 =50;
int maxw =0;
//存放第一艘輪船的最優總重量
int x[max]
;//存放第一艘輪船的最優解向量
void
dfs(
int i,
int tw,
int rw,
int op)
}else
if(tw + rw - w[i]
> maxw)
//右剪枝}}
bool
solve()
回溯法解裝載問題
遞迴解法 include using namespace std int bestw 0 int cw 0 int num 3 int r 46 int bestx 3 void load int w,int c,int n,int x r w n int main void int x load ...
回溯法,回溯法解裝載問題
利用回溯法解問題時一般按以下三步驟 1 定義問題的解空間 2 確定易於搜尋的解空間結構 3 以深度優先策略搜尋解空間,並在搜尋過程中用剪枝函式避免無效搜尋 二 回溯法應用 裝載問題 一批貨櫃共n個要裝上2艘載重量分別為c1和c2的輪船,其中貨櫃i的重量為wi且w1 w2 wn c1 c2 試確定乙個...
回溯法求解裝載問題(DFS 剪枝策略)
參考 問題描述 有n個貨櫃要裝上2艘載重量分別為c1和c2的輪船,其中貨櫃i的重量為wi,且 問是否有乙個合理的裝載方案,可將這n個貨櫃裝上這2艘輪船。如果有,找出一種裝載方案。問題分析 如果乙個給定裝載問題有解,則採用下面的策略可得到最優裝載方案。1 首先將第一艘輪船盡可能裝滿 2 將剩餘的貨櫃裝...