9动态规划

1.背包问题

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

1.简单算法

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

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

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

2. 动态规划

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

背包的承重为1斤 背包的承重为2斤 背包的承重为3斤 背包的承重为4斤
吉他1 1500 可以放入背包
G 1500
可以放入背包
G 1500
可以放入背包
G 1500
可以放入背包
G 1500
音响4 3000 G 1500 G 1500 G 1500 S 3000
笔记本电脑3 2000 G 1500 G 1500 C 2000 3000 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']

猜你喜欢

转载自www.cnblogs.com/csj2018/p/12173574.html