算法0-1背包问题:
2014-04-17 17:50
337 查看
参考博客:
http://blog.csdn.net/livelylittlefish/article/details/2186206 http://www.cnblogs.com/Anker/archive/2013/05/04/3059070.html
结果:
但是发现有错误啊。。
但这段数据测试的时候
weight_str='2 2 6 5 4'
ws=[ int(item) for item in weight_str .split(' ') if item]
value_str='6 3 5 4 6'
我取到的最大值是的4而不是的5.这就是问题所在了。
这是因为,我是在最后对每个重量取得最大价值,
按理而言,应该在遍历things的每一个元素的时候,就对oldresult做一下修理,使得对于每个重量一定取到小于或者等于该重量的价值的最大值。
最后代码如下:
输出结果是:
但是我在用递归法写的时候却出现了问题:
结果却是这个样子:
跟之前的对不上啊,这是怎么回事啊。。为什么会这个样子呢。。真坑啊。
应该是我子结构错了,改下子结构:
结果如下:
最大价值没错,但是索引列表错了啊。这是怎么会事呢
这个为什么是[1,2,3,4,5,8,9]呢,蛋疼啊。
知道为什么会这个样子了。。原来是我对things.sort()进行了排序。。。注销掉那一句就行了。
最终代码为:
运行的结果为:
终于把0-1背包问题解决了,。。弄了两天了。。
http://blog.csdn.net/livelylittlefish/article/details/2186206 http://www.cnblogs.com/Anker/archive/2013/05/04/3059070.html
#coding=utf-8 def domatch(things): """ 把每个重量的最大值保存到weight_value_list weight_value_list:重量:保存在经过所有索引后的(重量,价值)键值对 things:物品,由(重量,价值)构成 """ inthings=things[:]#内部使用的物品 inthings.insert(0,(0,0))#插入初始物品(0,0) weight_value_list=dict() length=len(things) #列表长度 oldresult=[(0,0,[])]#字典 索引:[(重量,价值,索引集合)] for index,(newweight,newvalue) in enumerate(inthings): if index>0: previndex=index-1 newresult=[]#对当前索引的键值对初始化 for weightindex,(weight,value,index_list) in enumerate(oldresult):#取出上一个索引的键值,然后再进行操作 #weight_value_list[index].extend([(weight,value),(weight+newweight,value+newvalue)]) newresult.append((weight,value,index_list)) index_list2=index_list[:] index_list2.append(index) node2=(weight+newweight,value+newvalue,index_list2) newresult.append(node2) del oldresult[:] oldresult=newresult[:] weight_value_dict=dict()#存放重量:[最大价值,索引列表]的键值对 alltuples=newresult for (weight,value,final_list) in alltuples: if weight not in weight_value_dict:#如果重量没有在weight_value_dict中 weight_value_dict[weight]=[value,final_list] elif weight_value_dict[weight][0]<value:#如果weight_value_dict中相对重量的价值小于value weight_value_dict[weight]=[value,final_list] return weight_value_dict #return weight_value_dict def findmaxvalue(inweight,weight_value_dict): """ 查找最大价值 """ return weight_value_dict[inweight]#l输出的结果是[最大价值,索引列表] if __name__=='__main__': weight_str='2 3 4 7' ws=[ int(item) for item in weight_str .split(' ') if item] value_str='1 3 5 9 ' vs=[int(item) for item in value_str.split(' ') if item] things=zip(ws,vs)#(重量,价值) weight_value_dict=domatch(things) print findmaxvalue(10,weight_value_dict) #print things
结果:
但是发现有错误啊。。
但这段数据测试的时候
weight_str='2 2 6 5 4'
ws=[ int(item) for item in weight_str .split(' ') if item]
value_str='6 3 5 4 6'
我取到的最大值是的4而不是的5.这就是问题所在了。
这是因为,我是在最后对每个重量取得最大价值,
按理而言,应该在遍历things的每一个元素的时候,就对oldresult做一下修理,使得对于每个重量一定取到小于或者等于该重量的价值的最大值。
最后代码如下:
#coding=utf-8 def domatch(things): """ 把每个重量的最大值保存到weight_value_list weight_value_list:重量:保存在经过所有索引后的(重量,价值)键值对 things:物品,由(重量,价值)构成 """ inthings=things[:]#内部使用的物品 inthings.insert(0,(0,0))#插入初始物品(0,0) weight_value_list=dict() length=len(things) #列表长度 oldresult=[(0,0,[])]#字典 索引:[(重量,价值,索引集合)] for index,(newweight,newvalue) in enumerate(inthings): if index>0: newresult=[]#对当前索引的键值对初始化 for weightindex,(weight,value,index_list) in enumerate(oldresult):#取出上一个索引的键值,然后再进行操作 #weight_value_list[index].extend([(weight,value),(weight+newweight,value+newvalue)]) newresult.append((weight,value,index_list)) index_list2=index_list[:] index_list2.append(index) node2=(weight+newweight,value+newvalue,index_list2) newresult.append(node2) del oldresult[:] oldresult=newresult[:] #对oldresult作整理,使得对于每个重量的价值取到的一定是小于或者等于该重量的最大价值 weight_value_dict=dict()#存放重量:[最大价值,索引列表]的键值对 alltuples=newresult for (fweight,fvalue,final_list) in alltuples: #如果重量没有在weight_value_dict中 if fweight not in weight_value_dict: weight_value_dict[fweight]=(fvalue,final_list) #如果weight_value_dict中相对重量的价值小于value elif weight_value_dict[fweight][0]<fvalue: weight_value_dict[fweight]=(fvalue,final_list) oldresult=[] for dweight,(dvalue,dlist) in weight_value_dict.iteritems(): oldresult.append((dweight,dvalue,dlist)) oldresult.sort( key=lambda x:x[0])#按照重量排序 for sortedindex,(comweight,comvalue,comli) in enumerate(oldresult): if sortedindex>0: previndex=sortedindex-1 if oldresult[previndex][1]>comvalue: oldresult[sortedindex]=(comweight,)+tuple(oldresult[previndex][1:]) weight_value_dict=dict()#存放重量:[最大价值,索引列表]的键值对 alltuples=newresult for (weight,value,final_list) in alltuples: if weight not in weight_value_dict:#如果重量没有在weight_value_dict中 weight_value_dict[weight]=[value,final_list] elif weight_value_dict[weight][0]<value:#如果weight_value_dict中相对重量的价值小于value weight_value_dict[weight]=[value,final_list] return weight_value_dict #return weight_value_dict def findmaxvalue(inweight,weight_value_dict): """ 查找最大价值 """ return weight_value_dict[inweight]#l输出的结果是[最大价值,索引列表] if __name__=='__main__': weight_str='12 16 24 7 29 32 5 43 31 1' ws=[ int(item) for item in weight_str .split(' ') if item] value_str='11 16 15 9 24 25 3 32 41 7' vs=[int(item) for item in value_str.split(' ') if item] things=zip(ws,vs)#(重量,价值) weight_value_dict=domatch(things) print findmaxvalue(105,weight_value_dict) #print things
输出结果是:
但是我在用递归法写的时候却出现了问题:
#coding=utf-8 def findmaxvalue(weight,things): inthings=things[:] inthings.insert(0,(0,0)) lenofthings=len(inthings) return findmaxvaluebylen(weight,inthings,lenofthings-1,lenofthings-1) known=dict() def findmaxvaluebylen(weight,inthings,index,maxindex): """ weight:要求得最大价值时的重量 inthings:已经被处理过的列表 index:在遍历inthings时的索引 maxindex:inthings的最大索引 """ if index in known: return known[index] else: if index==0: reobject=(weight,0,[])#重量,价值,索引列表 known[index]=reobject return reobject else: nowweight,nowvalue=inthings[index] if nowweight>weight: reobject=findmaxvaluebylen(weight,inthings,index-1,maxindex) known[index]=reobject return reobject else: reobject1=findmaxvaluebylen(weight,inthings,index-1,maxindex)#当前节点不包含在结果中 newweight=weight-nowweight reobject2=findmaxvaluebylen(newweight,inthings,index-1,maxindex)#当前节点包含在结果里 ele_list=reobject2[2][:] ele_list.append(index) reobject2=(weight,reobject2[1]+nowvalue,ele_list) reobject=reobject1 if reobject1[1]<reobject2[1]: reobject=reobject2 known[index]=reobject return reobject if __name__=='__main__': weight_str='12 16 24 7 29 32 5 43 31 1' ws=[ int(item) for item in weight_str .split(' ') if item] value_str='11 16 15 9 24 25 3 32 41 7' vs=[int(item) for item in value_str.split(' ') if item] things=zip(ws,vs)#(重量,价值) things.sort() print findmaxvalue(105,things) #print things
结果却是这个样子:
跟之前的对不上啊,这是怎么回事啊。。为什么会这个样子呢。。真坑啊。
应该是我子结构错了,改下子结构:
结果如下:
#coding=utf-8 def findmaxvalue(weight,things): inthings=things[:] inthings.insert(0,(0,0)) lenofthings=len(inthings) return findmaxvaluebylen(weight,inthings,lenofthings-1,lenofthings-1) known={0:{0:(0,[])}} def findmaxvaluebylen(weight,inthings,index,maxindex): """ weight:要求得最大价值时的重量 inthings:已经被处理过的列表 index:在遍历inthings时的索引 maxindex:inthings的最大索引 """ if index in known: tempdict=known[index] if weight in tempdict: return tempdict[weight] if index==0: reobject=(0,[]) known[index][weight]=reobject return reobject nowweight,nowvalue=inthings[index] reobject=findmaxvaluebylen(weight,inthings,index-1,maxindex) #发现在index==3 and weight==5的时候,reobject=None if nowweight>weight: fixdictbyobject(known,index,weight,reobject) known[index][weight]=reobject return reobject else: newweight=weight-nowweight reobject2=findmaxvaluebylen(newweight,inthings,index-1,maxindex) ele_list=reobject2[1][:] ele_list.append(index) reobject2=(reobject2[0]+nowvalue,ele_list) if reobject[0]<reobject2[0]: reobject=reobject2 fixdictbyobject(known,index,weight,reobject) known[index][weight]=reobject return reobject def fixdictbyobject(known_dict,index,comweight,reobject): """ 整理 known_dict[index] 使得所有重量大于comweight的价值都大于或者等于reobject的价值, """ if index not in known_dict: known_dict[index]=dict() return else: for tempweight,(tempvalue,templist) in known_dict[index].iteritems(): if tempweight>comweight and tempvalue<reobject[0]: known_dict[index][tempweight]=reobject[:] return if __name__=='__main__': weight_str='12 16 24 7 29 32 5 43 31 1' ws=[ int(item) for item in weight_str .split(' ') if item] value_str='11 16 15 9 24 25 3 32 41 7' vs=[int(item) for item in value_str.split(' ') if item] things=zip(ws,vs)#(重量,价值) things.sort() print findmaxvalue(105,things) #print things但是结果还是有问题啊
最大价值没错,但是索引列表错了啊。这是怎么会事呢
这个为什么是[1,2,3,4,5,8,9]呢,蛋疼啊。
知道为什么会这个样子了。。原来是我对things.sort()进行了排序。。。注销掉那一句就行了。
最终代码为:
#coding=utf-8 def findmaxvalue(weight,things): inthings=things[:] inthings.insert(0,(0,0)) lenofthings=len(inthings) return findmaxvaluebylen(weight,inthings,lenofthings-1,lenofthings-1) known={0:{0:(0,[])}} def findmaxvaluebylen(weight,inthings,index,maxindex): """ weight:要求得最大价值时的重量 inthings:已经被处理过的列表 index:在遍历inthings时的索引 maxindex:inthings的最大索引 """ if index in known: tempdict=known[index] if weight in tempdict: return tempdict[weight] if index==0: reobject=(0,[]) known[index][weight]=reobject return reobject nowweight,nowvalue=inthings[index] reobject=findmaxvaluebylen(weight,inthings,index-1,maxindex) if nowweight>weight: fixdictbyobject(known,index,weight,reobject) known[index][weight]=reobject return reobject else: newweight=weight-nowweight reobject2=findmaxvaluebylen(newweight,inthings,index-1,maxindex) ele_list=reobject2[1][:] ele_list.append(index) reobject2=(reobject2[0]+nowvalue,ele_list) if reobject[0]<reobject2[0]: reobject=reobject2 fixdictbyobject(known,index,weight,reobject) known[index][weight]=reobject return reobject def fixdictbyobject(known_dict,index,comweight,reobject): """ 整理 known_dict[index] 使得所有重量大于comweight的价值都大于或者等于reobject的价值, """ if index not in known_dict: known_dict[index]=dict() return else: for tempweight,(tempvalue,templist) in known_dict[index].iteritems(): if tempweight>comweight and tempvalue<reobject[0]: known_dict[index][tempweight]=reobject[:] return if __name__=='__main__': weight_str='12 16 24 7 29 32 5 43 31 1' ws=[ int(item) for item in weight_str .split(' ') if item] value_str='11 16 15 9 24 25 3 32 41 7' vs=[int(item) for item in value_str.split(' ') if item] things=zip(ws,vs)#(重量,价值) #things.sort() print findmaxvalue(105,things) #print things
运行的结果为:
终于把0-1背包问题解决了,。。弄了两天了。。
相关文章推荐
- 算法模板之01背包问题
- 蓝桥杯 算法提高 拿糖果【变形的背包问题】
- 【算法复习三】算法设计技巧与优化----各种背包问题总结
- DP算法入门(1)——多重背包问题(POJ1276题解)
- 算法导论第十六章贪心算法-0-1背包问题
- 果蝇算法--背包问题
- 背包问题的算法
- 【算法】——动态规划之0-1背包问题
- 0-1背包问题经典算法(二维数组实现)
- 【算法】用“0-1背包问题”的观点来解搜狐2012年的那道题
- 算法复习——背包DP问题
- [算法]背包问题的经典算法和贪心算法解答,C语言实现
- 贪心算法----背包问题
- 算法分析与设计-15-背包问题的贪心算法
- 贪心算法——部分背包问题(贪心策略内容)
- 贪心算法-4.2背包问题
- 【算法复习二】0-1背包问题总结
- 数据结构之贪心算法(背包问题的思考)-(十)
- 经典算法(2)——0/1背包问题(动态规划法)(ZZ)
- 【算法题】0-1 背包问题