日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > python >内容正文

python

python完全背包最优_python 完全背包问题_遗传算法Python实战 009.背包问题

發布時間:2025/3/19 python 15 豆豆
生活随笔 收集整理的這篇文章主要介紹了 python完全背包最优_python 完全背包问题_遗传算法Python实战 009.背包问题 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

原標題:遺傳算法Python實戰 009.背包問題

寫在前面的話

以下部分內容,來自百度

背包問題(Knapsack problem)是一種組合優化的NP完全問題。問題可以描述為:給定一組物品,每種物品都有自己的重量和價格,在限定的總重量內,我們如何選擇,才能使得物品的總價格最高。

問題的名稱來源于如何選擇最合適的物品放置于給定背包中。相似問題經常出現在商業、組合數學,計算復雜性理論、密碼學和應用數學等領域中。也可以將背包問題描述為決定性問題,即在總重量不超過W的前提下,總價值是否能達到V?

背包問題里面可以附加各種限制,比如容器的大小、容量、形狀等等,我們在這里不做特別復雜的設定,僅做重量限制,也就是說可以認為你放進去的物品是可以不受形狀的限制,僅受重量和容積的限制,比如你要放入的是糖或者鹽這類東西。

下面是我們要放入背包中的物品:

物品名稱

價值

重量(kg)

容量(L)

面粉

1680

0.265

0.41

黃油

1440

0.5

0.13

1840

0.441

0.29進入算法實現部分

首先,定義個物品類,用來記錄物品的各種屬性:

cla***esource:

def__init__( self, name, value, weight, volume):

self.Name = name

self.Value = value

self.Weight = weight

self.Volume = volume

然后就可以設定物品信息和條件了:設定背包的最大承載重量為10kg,最大容量為4L

items = [Resource( " 面粉", 1680, 0.265, .41),

Resource( " 黃油", 1440, 0.5, .13),

Resource( " 糖", 1840, 0.441, .29)]

maxWeight = 10

maxVolume = 4

我們的目標是在這些限制條件下,將背包里的東西價值最大化。

我們可以想想,如何通過完成這個目標。

首先我們當然是希望價值與重量比和價值與體積比最優的物品優先——這樣我們可以得到盡可能高的總價值。

當我們不能再把性價比最好的資源塞進去的時候,我們就要考慮用下一個最有價值的資源填滿剩余的空間,以此類推。

一旦背包裝滿了,我們還需要考慮,我們是否可以用其他類型的項目組合來代替一種類型的項目,以便于最大限度的增加背包內物品的總價值。

然后定義一個用于記錄當前背包中資源信息的類:

classItemQuantity:

def__init__( self, item, quantity):

self.Item = item

self.Quantity = quantity

def__eq__( self, other):

returnself.Item == other.Item andself.Quantity == other.Quantity

定義健壯性類:背包算法里面,肯定是輕、小、貴為最優,所以需要重量、容積和價值三個成員變量。在對比的時候,優先對比價值,價值相同的時候情況下,對比重量,最后對比容量。

classFitness:

def__init__( self, totalWeight, totalVolume, totalValue):

self.TotalWeight = totalWeight

self.TotalVolume = totalVolume

self.TotalValue = totalValue

def__gt__( self, other):

ifself.TotalValue != other. TotalValue:

returnself.TotalValue > other.TotalValue

ifself.TotalWeight != other. TotalWeight:

returnself.TotalWeight < other.TotalWeight

returnself.TotalVolume < other.TotalVolume

def__str__( self):

return" 重量: {:0.2f} 容積: {:0.2f} 價值: {}".format(

self.TotalWeight,

self.TotalVolume,

self.TotalValue)

健壯性驗證方法,把里面所有的值都累積起來。

defget_fitness(genes):

totalWeight= 0

totalVolume= 0

totalValue= 0

foriq in genes:

count= iq.Quantity

totalWeight+= iq.Item.Weight * count

totalVolume+= iq.Item.Volume * count

totalValue+= iq.Item.Value * count

returnFitness(totalWeight, totalVolume, totalValue)

我們還需要把每個物品的數量都控制在有效的范圍內:

def max_quantity( item, maxWeight, maxVolume):

returnmin(int(maxWeight / item.Weight)

ifitem.Weight > 0elsesys.maxsize,

int(maxVolume / item.Volume)

ifitem.Volume > 0elsesys.maxsize)

下面這個方法是用來創建初代基因的,在基因里面添加一個ItemQuantity,用來記錄剩余的重量和體積,這樣我們就不會出現超限的問題了。而在創建初代基因的時候,我們盡可能的多選取一些物品,這樣先把我們的背包填滿,如果這些物品效果不好,我們就對他們進行替換。

def create(items, maxWeight, maxVolume):

genes = []

remainingWeight, remainingVolume = maxWeight, maxVolume

fori inrange(random.randrange( 1, len(items))):

newGene= add(genes, items, remainingWeight, remainingVolume)

ifnewGeneis not None:

genes.append( newGene)

remainingWeight -= newGene.Quantity * newGene.Item.Weight

remainingVolume -= newGene.Quantity * newGene.Item.Volume

returngenes

上面的創建初代基因的方法里面的內部方法add,作用就是在往背包里面增加東西的時候,計算背包信息的。里面調用了上面那個max_quantity方法,來控制背包里面的剩余空間,不至于超限。在添加一個物品的時候,盡量去選擇還沒有被加進來,避免同一組物品太多。

defadd(genes,items,maxWeight, maxVolume):

usedItems = {iq. Itemfor iq in genes}

item= random.choice( items)

whileitemin usedItems:

item= random.choice( items)

maxQuantity = max_quantity( item,maxWeight, maxVolume)

return ItemQuantity(item,maxQuantity) ifmaxQuantity > 0elseNone

下面是進化函數:里面代碼的意義,見注釋:

def mutate(genes, items, maxWeight, maxVolume, window):

# 滑動窗口

window.slide

# 首先計算傳入的父本基因的健壯性

fitness = get_fitness(genes)

# 計算本次進化,還可以使用的剩余重量和容積

remainingWeight = maxWeight - fitness.TotalWeight

remainingVolume = maxVolume - fitness.TotalVolume

# 用目前父本基因的數量+10 分之一的概率,來控制是否要進行移動窗口賦值

removing = len(genes) > 1andrandom.randint( 0, 10) == 0

# 如果父本基因數量大于1 ,而且隨機概率90% 的話

# 從父本基因里面隨機挑選一個物品,然后把重量和容積累加給背包剩余的空間

# 接下去把這個物品從基因庫中移除掉

ifremoving:

index = random.randrange( 0, len(genes))

iq = genes[index]

item= iq.Item

remainingWeight += item.Weight * iq.Quantity

remainingVolume += item.Volume * iq.Quantity

del genes[index]

# 如果剩余空間還有,而且基因庫中的物品數量已經等于0

# 或者基因庫中的物品數量小于背包里面的物品數量,

# 并且獲得百分之一的概率

# 這個變量用于控制,是否還要往包里面增加物品的。

adding = (remainingWeight > 0orremainingVolume > 0) and

( len(genes) == 0or

( len(genes) < len( items) andrandom.randint( 0, 100) == 0))

# 如果背包里面還可以塞東西,則直接把物品add 到基因組中

ifadding:

newGene = add(genes, items, remainingWeight, remainingVolume)

ifnewGene is notNone:

genes.append(newGene)

return

# 隨機在基因組里面挑選一件物品,加入到背包中

index = random.randrange( 0, len(genes))

iq = genes[index]

item= iq.Item

remainingWeight += item.Weight * iq.Quantity

remainingVolume += item.Volume * iq.Quantity

# 是否要改變基因庫

# 如果基因組的數量小于基因庫中是數量,而且符合25% 的概率

# 從基因庫里面選擇更多的物品填入背包中

# 此過程主要是控制背包里面盡量所有的物品都要有,而不僅是一個類別的物品

changeItem = len(genes) < len( items) andrandom.randint( 0, 4) == 0

ifchangeItem:

itemIndex = items.index(iq.Item)

start= max( 1, itemIndex - window.Size)

stop= min( len( items) - 1, itemIndex + window.Size)

item= items[ random.randint( start, stop)]

# 計算重量,如果還沒有填滿,則把這個物品加入到背包里面去

# 否則把這個物品從背包里面刪掉。

maxQuantity = max_quantity( item, remainingWeight, remainingVolume)

ifmaxQuantity > 0:

genes[index] = ItemQuantity( item, maxQuantity

ifwindow.Size > 1elserandom.randint( 1, maxQuantity))

else:

del genes[index]

下面是一些初始化方法和內部默認方法:

初始化終止條件(這里已經手動指定終止條件了,實際上你是可以通過代碼修改來實現不同組合的,不過get_fiteness方法也要相應修改)

optimal = get_fitness(

[ItemQuantity( items[ 0], 1),

ItemQuantity( items[ 1], 14),

ItemQuantity( items[ 2], 6)])

構造幾個內部方法,Python支持函數指針,可以把整個方法當成參數傳遞過來:

def _mutate_custom( parent, custom_mutate, get_fitness):

childGenes = parent.Genes [:]

custom _mutate( childGenes)

fitness = get _fitness( childGenes)

return Chromosome( childGenes, fitness)

進化過程:

_get_improvement方法的說明,見上一節魔術方塊。

defget_best(get_fitness, targetLen, optimalFitness, geneSet, display,

custom_mutate=None, custom_create=None, maxAge=None) :

ifcustom_mutate isNone:

deffnMutate(parent):

return_mutate(parent, geneSet, get_fitness)

else:

deffnMutate(parent):

return_mutate_custom(parent, custom_mutate, get_fitness)

ifcustom_create isNone:

deffnGenerateParent:

return_generate_parent(targetLen, geneSet, get_fitness)

else:

deffnGenerateParent:

genes = custom_create

returnChromosome(genes, get_fitness(genes))

forimprovement in_get_improvement(fnMutate, fnGenerateParent, maxAge):

display(improvement)

ifnotoptimalFitness > improvement.Fitness:

returnimprovement

def_get_improvement(new_child, generate_parent, maxAge):

parent = bestParent = generate_parent

yieldbestParent

historicalFitnesses = [bestParent.Fitness]

whileTrue:

child = new_child(parent)

ifparent.Fitness > child.Fitness:

ifmaxAge isNone:

continue

parent.Age += 1

ifmaxAge > parent.Age:

continue

index = bisect_left(historicalFitnesses, child.Fitness, 0,

len(historicalFitnesses))

proportionSimilar = index / len(historicalFitnesses)

ifrandom.random < exp(-proportionSimilar):

parent = child

continue

bestParent.Age = 0

parent = bestParent

continue

ifnotchild.Fitness > parent.Fitness:

child.Age = parent.Age + 1

parent = child

continue

child.Age = 0

parent = child

ifchild.Fitness > bestParent.Fitness:

bestParent = child

yieldbestParent

historicalFitnesses.append(bestParent.Fitness)

執行測試的方法:

這方法里面利用了大量的函數指針,通過封裝內部方法的傳遞的方式,封裝和初始化了大量的默認參數,是Python中的一個特性,大家有興趣的話,請自行了解Python的語法特征deffill_knapsack:

startTime = datetime.datetime.now

window = Window( 1,

max( 1, int(len(items) / 3)),

int(len(items) / 2))

sortedItems = sorted(items, key= lambdaitem: item.Value)

deffnDisplay(candidate):

display(candidate, startTime)

deffnGetFitness(genes):

returnget_fitness(genes)

deffnCreate:

returncreate(items, maxWeight, maxVolume)

deffnMutate(genes):

mutate(genes, sortedItems, maxWeight, maxVolume, window)

best = get_best(fnGetFitness, None, optimal, None,

fnDisplay, fnMutate, fnCreate, maxAge= 50)

執行:

fill_knapsack

輸出:

下面是我的一次執行,可以看見,不管初始化的情況怎么樣,最后都能逼近達到我們給出來的終止條件。13x 糖重量: 5.73容積: 3.77價值: 239200: 00: 00

10x 糖, 2x 面粉, 2x 黃油重量: 5.94容積: 3.98價值: 246400: 00: 00.002989

9x 糖, 6x 黃油重量: 6.97容積: 3.39價值: 252000: 00: 00.004021

9x 糖, 8x 黃油重量: 7.97容積: 3.65價值: 280800: 00: 00.004021

10x 糖, 8x 黃油重量: 8.41容積: 3.94價值: 299200: 00: 00.004984

12x 黃油, 7x 糖重量: 9.09容積: 3.59價值: 301600: 00: 00.004984

13x 黃油, 7x 糖重量: 9.59容積: 3.72價值: 316000: 00: 00.005983

15x 黃油, 4x 糖, 2x 面粉重量: 9.79容積: 3.93價值: 323200: 00: 00.021939

15x 黃油, 5x 糖, 1x 面粉重量: 9.97容積: 3.81價值: 324800: 00: 00.042882

15x 黃油, 5x 糖, 1x 面粉重量: 9.97容積: 3.81價值: 324800: 00: 00.178553

14x 黃油, 6x 糖, 1x 面粉重量: 9.91容積: 3.97價值: 328800: 00: 00.184537

14x 黃油, 6x 糖, 1x 面粉重量: 9.91容積: 3.97價值: 328800: 00: 00.383970

結語

背包問題,應該是我們到現在為止,處理的最復雜的算法問題,因為在背包中的物品,不但可以放入還可以拿出,還需要修改……也就是說我們的基因長度是可以變化的。

另外我們還可以增加其他的條件來增加復雜程度,比如大航海時代的航運問題:船的貨物與食物、淡水和船員的配比問題:

貨物運太少,虧本,運太多占用其他空間

食物不夠,到不了目的地

淡水不夠,雷同食物

船員數量要與貨物數量相關,太少,處理不了貨物,太大又要消耗更多食物淡水。這四種物質相互制約,當然還可以加入航線上哪些地方可以補給食物,可以補給淡水……等等,就更加復雜了。

責任編輯:

與50位技術專家面對面20年技術見證,附贈技術全景圖

總結

以上是生活随笔為你收集整理的python完全背包最优_python 完全背包问题_遗传算法Python实战 009.背包问题的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 亚洲欧美自偷自拍 | 丰满人妻一区二区 | 亚洲人成电影在线 | 国产一区二区三区乱码 | 污漫在线观看 | av大片免费观看 | 最好看的2019年中文视频 | 日韩影视一区二区三区 | 91麻豆视频 | 久久有精品| 色网站在线 | 伊人蕉久影院 | 国产精品一区二区三 | 日韩欧美视频在线 | 激情伊人五月天 | 一级片一区二区三区 | 最近最新中文字幕 | 2019国产精品视频 | 99中文字幕在线观看 | 99一区二区三区 | 青青草成人av | 国产一级淫片a视频免费观看 | 黄色av一区二区三区 | 天堂网在线视频 | 性www| 真实偷拍激情啪啪对白 | 成人午夜免费毛片 | 色屋永久 | 先锋av资源网站 | 狠狠干伊人网 | 亚洲666 | 国产a v一区二区三区 | www成人免费视频 | 成年人小视频在线观看 | 国产亚洲精品久久久久久 | 欧美午夜精品久久久久久浪潮 | 日韩精品色呦呦 | 狂野欧美性猛交xxxxhd | 黄页在线观看 | 黄色网址国产 | 国产同性人妖ts口直男 | 亚洲无限av| 狠狠插综合 | 日韩在线观看视频一区二区 | 色999在线| 中文字幕日韩精品在线观看 | 亚洲aⅴ乱码精品成人区 | 69欧美视频 | 日韩国产欧美综合 | 国产成人无码aa精品一区 | 欧美日韩一区二区区别是什么 | 亚洲人精品午夜射精日韩 | 亚洲国产aⅴ精品一区二区 日韩黄色在线视频 | 久久久久久久麻豆 | av女优天堂在线观看 | 亚洲精品国产福利 | jizz国产在线观看 | 色999在线观看 | 丰满岳跪趴高撅肥臀尤物在线观看 | 三浦惠理子aⅴ一二三区 | 国产欧美日韩精品区一区二污污污 | 精品一区二区三区入口 | jizz免费 | 逼逼av| 黄色国产片 | 亚洲欧洲久久 | 国产一区二区三区四区五区 | 亚洲欧洲在线观看 | 秋霞在线观看视频 | 九九精品国产 | 猛男大粗猛爽h男人味 | 大学生三级中国dvd 日韩欧美一区二区区 | 亚洲美免无码中文字幕在线 | 爱福利视频一区 | 欧美女优视频 | 国产a免费观看 | 国产精品激情 | 九九久久免费视频 | 成人里番精品一区二区 | 91涩| 午夜合集 | 中文字幕狠狠 | 亚洲网站免费观看 | 97视频网址 | 日本精品免费一区二区三区 | 视频一区二区三区四区五区 | 国产精品2 | 日韩三区在线观看 | 午夜在线观看视频 | 国产欧美久久一区二区三区 | 亚洲av无码一区东京热久久 | 欧美亚洲精品天堂 | av男女| 久久大尺度 | 91亚色视频在线观看 | 久久99操 | 亚洲一区二区三区久久久 | 亚洲午夜精品久久久 | av2018|