0-1背包问题优化算法详解
★代碼實現(python):
#-*- coding:utf-8 -*-
from copy import copy
def add(p,x,c): #對應元素分別相加,p中每個元素都是元組,x也是一個元組
????resultlist=[(i[0]+x[0],i[1]+x[1]) for i in p if i[0]+x[0]<=c]
????return resultlist
def union(p,q): #求并集,同時刪除壞點
????pp=copy(p)
????qq=copy(q)
????delelement=[]
????for i in pp:
????????for j in qq:
????????????if(i[0]>=j[0] and i[1]<=j[1]):
????????????????delelement.append(i)
????????????????break
????????????if(i[0]<=j[0] and i[1]>=j[1]):
????????????????delelement.append(j)
????????????????break
????for i in delelement:
????????if i in pp:
????????????pp.remove(i)
????????else:
????????????qq.remove(i)
????qq.extend(pp)
????qq.sort()
????return qq
def package2(w,v,c,n):#動態規劃主函數
????p=[[]]*(n+2)
????p[n+1]=[(0,0)]
????q= [[]] * (n + 2)
????for i in range(n+1,1,-1):
????????q[i]=add(p[i],(w[i-2],v[i-2]),c)
????????p[i-1] = union(p[i], q[i])
????return p,q
def out(w,v,p,q,n): ??#構造最優解
????maxpoint=p[1][-1]
????choose=[]
????for i in range(1,n+1):
????????if((maxpoint in q[i+1]) and (maxpoint not in p[i+1])):
????????????choose.append(True)
????????????maxpoint=(maxpoint[0]-w[i-1],maxpoint[1]-v[i-1])
????????else:
????????????choose.append(False)
????print 'max weight and value:', p[1][-1]
????print 'choose or not:', choose
if __name__=='__main__':
????w=[2,2,6,5,4]
????v=[6,3,5,4,6]
????p,q=package2(w, v, 10, 5)
????out(w,v,p,q,5)
★結果輸出:
max weight and value: (8, 15)
choose or not: [True, True, False, False, True]
★復雜度分析
從之前的分析過程可以看出,每一個物品都存在選或者不選,如果沒有刪除壞點,
則要計算的轉折點個數為2^n個,即指數級的,但是正是因為中間過程刪除了很多
的壞點,因此實際復雜度并不是很高。
和前一篇最直接的動態規劃相比,如果背包容量和物品重量的量級相差不大而
物品選擇很多時,用直接動態規劃方法效果可能更好。
而如果出現入本文開頭引入的情況,即背包容量量級很大,而可選物品很少時,
用優化算法要快很多。因此,具體哪種好要視情況而定。
因為博客園編輯公式不太方便,因此寫好了文檔再截屏的。?以上內容為原創,希望能幫到大家。
?
轉載于:https://www.cnblogs.com/xiaotan-code/p/6674902.html
總結
以上是生活随笔為你收集整理的0-1背包问题优化算法详解的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 面试题 02.03. 删除中间节点
- 下一篇: 博客园设置代码样式