装载问题
1. 问题描述
问题:
有n个集装箱,需要装上两艘载重分别为
c
1
c_{1}
c1和
c
2
c_{2}
c2的轮船。
w
i
w_{i}
wi为第
i
i
i个集装箱的重量,且
w
1
+
w
2
+
.
.
.
.
+
w
n
<
=
c
1
+
c
2
w_{1}+w_{2}+....+w_{n}<= c_{1}+c_{2}
w1+w2+....+wn<=c1+c2。问:是否存在一个合理的装载方法把这
n
n
n个集装箱装上船?如果有,请给出一种方案。
实例:
W
=
<
90
,
80
,
20
,
12
,
10
,
30
,
40
>
W = <90,80,20,12,10,30,40>
W=<90,80,20,12,10,30,40>
c
1
=
152
,
c
2
=
130
c_1=152,c_2=130
c1=152,c2=130
解:
1
,
3
,
6
,
7
1,3,6,7
1,3,6,7装第一艘船,其余第2艘船
2. 求解思路
输入:
W
=
<
w
1
,
w
2
,
.
.
.
.
,
w
n
>
W=<w_1,w_2,....,w_n>
W=<w1,w2,....,wn>为集装箱重量,
c
1
c_1
c1和
c
2
c_2
c2为船的最大重量
算法思想:
令第一艘船的装入量为
W
1
W_1
W1,
1.用回溯算法求使得
c
1
−
W
1
c_1-W_1
c1−W1达到最小值的装载方案
2.若满足
w
1
+
w
2
+
.
.
.
.
+
w
n
−
W
1
<
=
c
2
w_{1}+w_{2}+....+w_{n}-W_1<=c_2
w1+w2+....+wn−W1<=c2
则回答‘Yes’,否则回答‘No’
3. 伪代码
- 算法 L o a d i n g ( W , c 1 ) Loading(W, c_1) Loading(W,c1)
- S o r t ( W ) Sort(W) Sort(W);
- B ← c 1 ; b e s t ← c 1 ; i ← 1 ; B \leftarrow c_1;best \leftarrow c_1; i \leftarrow 1; B←c1;best←c1;i←1;
- while i ≤ n i \leq n i≤n do
- if 装入 i i i后重量不超过 c 1 c_1 c1
- then B ← B − w i ; x [ i ] ← 1 ; i ← i + 1 ; B\leftarrow B-w_i; x[i] \leftarrow 1;i \leftarrow i+1; B←B−wi;x[i]←1;i←i+1;
- else x [ i ] ← 0 ; i ← i + 1 ; x[i] \leftarrow 0;i \leftarrow i+1; x[i]←0;i←i+1;
- if B < b e s t B<best B<best then记录解 ; ; ; b e s t ← B ; best \leftarrow B; best←B;
- B a c k t r a c k ( i ) ; Backtrack(i); Backtrack(i);
- if i = 1 i=1 i=1 then return 最优解
- else goto 4.