python遞迴-揹包
阿新 • • 發佈:2020-07-22
遞迴程式碼Ⅰ:
w = [0, 2, 3, 4, 5, 9] v = [0, 3, 4, 8, 8, 10] max_W = 20 sum = {(i, w1):0 for i in range(len(w)) for w1 in range(max_W+1)} # python對資料操作的實現很容易 def m(i, W): # 第i個物品怎麼放 if i == 0: sum[(i, W)] = 0 return 0 elif W == 0: sum[(i, W)] = 0 return 0 elif sum[(i, W)] != 0: return sum[(i, W)] elif w[i] > W: sum[(i, W)] = m(i-1, W) return sum[(i, W)] else: sum[(i, W)] = max(m(i-1, W), v[i] + m(i-1, W-w[i])) return sum[(i, W)] for i in range(1, len(w)): # 填滿記憶陣列 for j in range(1, max_W+1): m(i, j) for i in range(1, len(w)): for j in range(1, max_W+1): print(i, '-', j, ':', sum[(i, j)]) print(sum[(len(w)-1, max_W)]) # 注意索引
遞迴程式碼Ⅱ:
tr = {(2, 3), (3, 4), (4, 8), (5, 8), (9, 10)} val = {} def thief(tr, m): if tr == set() or m == 0: val[(tuple(tr), m)] = 0 return 0 elif (tuple(tr), m) in val: # 記憶 return val[(tuple(tr), m)] else: vmax = 0 for t in tr: # 取出一個合適的寶物再求處剩下寶物的最大值 if t[0] <= m: vmax = max(vmax, t[1] + thief(tr-{t}, m-t[0])) val[(t, m)] = vmax return vmax # 秀 print(thief(tr, 20))
迭代
# 從小到大討論 tr = [None, {'w':2, 'v':3}, {'w':3, 'v':4}, {'w':4, 'v':8}, {'w':5, 'v':8}, {'w':9, 'v':10}] max_m = 20 val = {(i, w):0 for i in range(len(tr)) for w in range(max_m+1)} for i in range(1, len(tr)): # 從小到大遞推,由於tr的第一項是None,因此得從第一項開始,range[1, len(tr)] for w in range(1, max_m+1): if tr[i]['w'] > w: # 注意:這裡不是max_m val[(i, w)] = val[(i-1), w] else: val[(i, w)] = max(val[(i-1), w], tr[i]['v'] + val[(i-1), w-tr[i]['w']]) print(val[(len(tr)-1, max_m)])