0-1背包問題的三種解法


0-1背包問題

給定n個重量為w1​, w2​, w3​,…, wn​,價值為 v1​, v2​, v3​,… vn​的物品和容量為C的背包,物品選擇取與不取,且只能取一次。求這個物品中一個最有價值的子集,使得在滿足背包的容量的前提下,包內的總價值最大。

w=[2,2,6,5,4]  #物品i的重量   i對應物品下標   [2,2,6,5,4]
v=[6,3,5,4,6]  #物品i的價值    i對應物品下標   [6,3,5,4,6]
C=10   #背包容量為10
x=[0,0,0,0,0]   #物品i裝入背包的份額 0表示物品不裝入背包  1表示完全裝入背包

三種算法

1.貪心算法_單位最大價值優先

#將物品按單位價值從大到小排序  返回數組y:元素為排序后的物品下標
def Sort():
    vi={}
    for i in range(len(w)):
        vi[i]=v[i]/w[i]
    vi=sorted(vi.items(), key=lambda kv: (kv[1], kv[0]),reverse=True)
    result=[]
    for key,value in vi:
        result.append(key)
    return result

#貪心算法_最大單位價值優先
def Func_Greedy():
    vi=Sort()
    remain_c=C
    value_sum=0
    for i in vi:
        if(w[vi[i]]<=remain_c):
            x[vi[i]]=1
            value_sum+=v[vi[i]]
            remain_c-=w[vi[i]]
    return value_sum

2.分治法

#分治法_遞歸
def Func_3(i,c):
    if(i==-1 or c==0):
        return 0
    if(c<w[i]):
        return Func_3(i-1,c)
    else:
        tmp1=Func_3(i-1,c)
        tmp2=Func_3(i-1,c-w[i])+v[i]
        return max(tmp1,tmp2)

3.動態規划

#動態規划
def Func_2():
    m=[[0 for i in range(11)]for i in range(5)]  #創建一個4*10的數組  列對應物品   行對應背包容量
    for i in range(1,C+1):#背包裝入第一件物品  初始化第一行
        if(i>=w[0]):
            m[0][i]=v[0]

    for i in range(1,5):#第一行已初始化,從第二行開始
        for j in range(1,11):#第一列意思是背包容量等於0, 從第二列開始
            if(j<w[i]):
                m[i][j]=m[i-1][j]
            else:
                if(m[i-1][j-w[i]]+v[i]>m[i-1][j]):
                    m[i][j]=m[i-1][j-w[i]]+v[i]
                else:
                    m[i][j]=m[i-1][j]
    return m[len(w)-1][C]

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM