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