9动态规划

拥有回忆 提交于 2020-01-09 23:01:39

1.背包问题

音响3000元4斤
笔记本电脑2000元3斤
吉他1500元1斤

1.简单算法

最简单的算法:尝试各种可能的商品组合,并找出价值最高的组合。
缺点:速度非常慢。3种商品需要计算8种组合;4件商品是,需要计算16中组合。每增加一种商品,需要计算的集合数将翻倍。这种算法的运行时间为O(2n)

组合1组合2组合3组合4
吉他音响笔记本电脑
0150030002000
组合5组合6组合7组合8
吉他和音响吉他和笔记本电脑音响和笔记本电脑吉他、音响和笔记本电脑
装不下3500装不下装不下

近似算法可以得到近似解,但不一定是最优解。

2. 动态规划

使用动态规划可以得到最优解。

背包的承重为1斤背包的承重为2斤背包的承重为3斤背包的承重为4斤
吉他1 1500可以放入背包
G 1500
可以放入背包
G 1500
可以放入背包
G 1500
可以放入背包
G 1500
音响4 3000G 1500G 1500G 1500S 3000
笔记本电脑3 2000G 1500G 1500C 20003000 vs (2000+1500) -> 3500

计算公式:
cell[i][j] = cell[i-1][j] vs {当前商品的价值 + 剩余空间的价值 = 当前商品的价值+cell[i-1][j-当前商品的重量]}

实现

bag={
    "computer":{"weight":3,"value":2000},
    "guitar":{"weight":1,"value":1500},
    "sound":{"weight":4,"value":3000}
}
list=[]
goods = []
row=0
def addList(list1,list2):
    for i in list1:
        list2.append(i)
for key in bag.keys():
    sublist=[]
    subGood=[]
    keyWeight = bag.get(key)["weight"]
    keyValue = bag.get(key)["value"]
    for column in range(4):
        sub=[]
        #单元格 = 列的索引+1
        weight = column + 1
        #判断行,行数=0,直接对比;行数大于0,与上一行进行对比
        if(row > 0):
            if(weight < keyWeight):
                sublist.append(list[row-1][column])
                addList(goods[row - 1][column], sub)
            elif(weight == bag.get(key)["weight"]):
                if( list[row-1][column] < keyValue ):
                    sublist.append(keyValue)
                    sub.append(key)
                else:
                    sublist.append(list[row-1][column])
                    addList(goods[row-1][column],sub)
            else:
                #如果单元格重量>商品,就判断商品的权重和同位置大小
                #判断weight-bag.get(key)["weight"]
                if (list[row-1][column] < ( keyValue + list[row-1][weight-keyWeight-1] ) ):
                    sublist.append( keyValue + list[row-1][weight-keyWeight-1])
                    sub.append(key)
                    addList(goods[row - 1][weight-keyWeight-1], sub)
                else:
                    sublist.append(list[row-1][column])
                    addList(goods[row-1][column],sub)
        else:
            #直接判断,单元格 < 物品重量
            if(weight < keyWeight):
                sublist.append(0)
                # sub.append([])
            else:
                sublist.append(keyValue)
                sub.append(key)
        subGood.append(sub)
    list.append(sublist)
    goods.append(subGood)
    row+=1
#最大值肯定在最后一组,获取最大值的索引
print("4斤背包容纳的最大价值组合:%s %s" % (list[-1][max_index],goods[-1][max_index]))    #4斤背包容纳的最大价值组合:3500 ['guitar', 'computer']
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!