以簡單的語言說,就是給定兩艘船,要求一批貨物分別裝入。
這道問題採用「先盡可能以最大載重裝一艘船,再以剩下的貨物裝另一艘」。
這樣,我們就將問題簡化為了0-1揹包問題。採用回溯法構建解空間,之後遍歷即可。思路很簡單,**的注釋我也寫的很詳細了。
def
traceback
(depth)
:global n, goods, ship, best_arrange, now_arrange, best_load, now_load, remain
if depth >= n:
# 遍歷到葉節點,取較大值
if now_load > best_load:
best_arrange = now_arrange
best_load = now_load
return
remain -= goods[depth]
# 將當前處理貨物從剩餘中扣去
if now_load + goods[depth]
<= ship:
# 如果加了這件貨物沒超最大載重
now_arrange[depth]=1
# 那就將這件貨物先記入當前解向量
now_load += goods[depth]
# 並且將貨物重量記為當前載重
traceback(depth+1)
# 繼續向下遍歷
now_load -= goods[depth]
# 遍歷完之後將載重還原
if now_load + remain > best_load:
# 如果不加上當前貨物的重量還有可能在後方有大於最優裝載的可能
now_arrange[depth]=0
# 就不加入當前貨物
traceback(depth+1)
# 進行遍歷 這個if中的思路不是"剪枝",而是多長了乙個有可能的枝條
remain += goods[depth]
defresult_out()
:global best_arrange, best_load, ship, n, goods
l =0for i in
range(0
, n)
:if best_arrange[i]==0
: l += goods[i]
if l > ship:
print
('無法裝載'
)else
:print
('可以裝載'
)print
('第一艘船裝載:'
, end='')
for i in
range(0
, n)
:if best_arrange[i]==1
:print
(i, end=
' ')
print()
print
('第二艘船裝載:'
, end='')
for i in
range(0
, n)
:if best_arrange[i]==0
:print
(i, end=
' ')
if __name__ ==
'__main__'
: n =
3# 貨物數量
goods =[40
,40,10
]# 貨物
ship =
50# 船的最大載重
best_arrange =[0
,0,0
]# 最優解向量
now_arrange =[0
,0,0
]# 遍歷時當前解向量
best_load =
0# 最優解時第一艘船的載重
now_load =
0# 遍歷時當前載重
remain =
sum(goods)
# 剩餘貨物重量
traceback(0)
result_out(
)
最優裝載問題回溯法 貪心選擇之最優裝載問題
有一批貨櫃要裝上一艘載重量為c的輪船。其中貨櫃i的重量為wi。最優裝載問題要求確定在裝載體積不受限制的情況下,將盡可能多的貨櫃裝上輪船。問題可以描述為 該問題可以用貪心演算法求解,要使用貪心演算法解決問題,我們必須先證明 1 該問題具備貪心選擇性質 2 該問題具備最優子結構性質.1 首先先證明貪心選...
裝載問題 回溯法
描述 有一批共n個貨櫃要裝上艘載重量為c的輪船,其中貨櫃i的重量為wi。找出一種最優裝載方案,將輪船盡可能裝滿,即在裝載體積不受限制的情況下,將盡可能重的貨櫃裝上輪船。輸入 由檔案load.in給出輸入資料。第一行有2個正整數n和c。n是貨櫃數,c是輪船的載重量。接下來的1行中有n個正整數,表示貨櫃...
裝載問題 回溯法
有n個貨櫃要裝上2艘載重量分別為c1和c2的輪船,其中貨櫃i的重量為wi,且 問題 是否有乙個合理的裝載方案,可將這n個貨櫃裝上這2艘輪船?如果有,找出一種裝載方案。例如 當n 3,c1 c2 50 1 若w 10,40,40 可將貨櫃1和貨櫃2裝上第一艘輪船,而將貨櫃3裝上第二艘輪船 2 如果w ...