(二) 創(chuàng)建類型
本節(jié)將展示如何通過creator創(chuàng)建類型以及如何使用toolbox進(jìn)行初始化所宰。
1绒尊、Fitness
已經(jīng)提供的Fitness類是一個(gè)抽象類,它需要weight來使得它成為一個(gè)函數(shù)仔粥。一個(gè)最小化的適應(yīng)度是通過負(fù)權(quán)重構(gòu)建的婴谱,而一個(gè)最大化適應(yīng)度則需要正權(quán)重。例如躯泰,下面的代碼使用creator創(chuàng)建了一個(gè)單目標(biāo)最小化適應(yīng)度函數(shù)——FitnessMin
creator.create("FitnessMin",base.Fitness,weights=(-1.0,))
creat()函數(shù)至少需要兩個(gè)元素谭羔,一個(gè)名稱是新創(chuàng)建的類和它基于的類(在上例中為“FitnessMin”和“base.Fitness”)。任何序列元素都會(huì)對(duì)類的屬性產(chǎn)生影響麦向。在具體的Fitness文檔中瘟裸,weights屬性一定是一個(gè)元組,這樣才可以使得多目標(biāo)和單目標(biāo)適應(yīng)度可以保持一致诵竭。(我認(rèn)為使用元組的原因在于元組中的元素是不可修改的话告,因此在不同類型的優(yōu)化問題中,可以始終保持優(yōu)化目標(biāo)與實(shí)際一致——Min&NegativeWeights以及Max&PositiveWeights卵慰?)一個(gè)FitnessMulti可以使用相似的方法進(jìn)行設(shè)置
creator.create("FitnessMin",base.Fitness,weights=(-1.0,1.0))
這串代碼是對(duì)第一個(gè)目標(biāo)求最小值沙郭,對(duì)第二個(gè)目標(biāo)求最大值。它的權(quán)重也可以被用于衡量?jī)蓚€(gè)目標(biāo)的重要程度裳朋。這意味著權(quán)重可以使任何實(shí)數(shù)并且只有一個(gè)標(biāo)志決定最大化與最小化的完成(實(shí)現(xiàn)優(yōu)化目標(biāo))病线。在NSGA-II算法(一種高效的多目標(biāo)遺傳算法)中密集的距離排列里可以體現(xiàn)權(quán)重的作用。
2、Individual
通過簡(jiǎn)單地思考不同的演化算法的風(fēng)格(GA\GP\ES\PSO\DE....)送挑,我們發(fā)現(xiàn)個(gè)體間存在極大不同是有可能的绑莺,這就驗(yàn)證了所有的類型都不是可以被開發(fā)的假設(shè)。這里有一個(gè)教程說明如何使用creator創(chuàng)建一些個(gè)體并且使用Toolbox對(duì)它們進(jìn)行初始化让虐。
2.1紊撕、 List of Floats
我們要?jiǎng)?chuàng)建的第一個(gè)個(gè)體將是一個(gè)簡(jiǎn)單的包含float的list。為了去產(chǎn)生這種個(gè)體赡突,我們需要?jiǎng)?chuàng)建一個(gè)Individual class对扶,使用creator將會(huì)與標(biāo)準(zhǔn)list類型建立聯(lián)系(creator.create里面會(huì)有l(wèi)ist?)惭缰,并且將會(huì)與fitness建立聯(lián)系(每個(gè)individual對(duì)應(yīng)其fitness)浪南。
下面介紹一個(gè)新的register對(duì)象,它用于將deap包中所帶方法與要編寫的演化算法進(jìn)行“固定”(包括初始化漱受、操作方法以及適應(yīng)度函數(shù)的計(jì)算)络凿。register存在于base.Toolbox中。因此在使用時(shí)首先要調(diào)用base.Toolbox()昂羡,然后再對(duì)register進(jìn)行調(diào)用絮记。
register()至少需要兩個(gè)參數(shù),一個(gè)alias和一個(gè)分配到alias的函數(shù)虐先。任何的序列參數(shù)會(huì)被叫做functools.partial()進(jìn)行傳遞到函數(shù)當(dāng)中怨愤。C2P2中的代碼在toolbox中創(chuàng)造了兩個(gè)alias,第一個(gè)重定向到random.random()函數(shù)蛹批,第二個(gè)是一個(gè)initRepeat()函數(shù)撰洗,將它容器中的元素填充到creator.Individual class中,它對(duì)toolbox.attr_float()函數(shù)的func參數(shù)根據(jù)IND_SIZE(這里的n)進(jìn)行重復(fù)腐芍。
現(xiàn)在差导,叫做toolbox.individual()將會(huì)使用設(shè)置好的參數(shù)調(diào)用initRepeat(),并且會(huì)返回到一個(gè)完成的creator.Individual中猪勇,這個(gè)creator.Individual是由IND_SIZE的浮點(diǎn)數(shù)和最大化單目標(biāo)優(yōu)化適應(yīng)度信息fitness組成设褐。(即在本例中,individual是由十個(gè)隨機(jī)地folat類型的數(shù)構(gòu)成埠对,并且它們的適應(yīng)值是一個(gè)最大適應(yīng)值络断?individual(number, fitness)?)
這種類型的變化同樣也可以與array.array聯(lián)系,numpy.ndarray聯(lián)系项玛,代碼樣式如下
creator.create('Individual', array.array, typecode = 'd', fitness = creator.FitnessMax)
creator.create('Individual', numpy.ndarray, fitness = creator.FitnessMax)
從arrays類型繼承的初始化與之前的一致貌笨。
2.2、Permutation(排列)
排列表示的個(gè)體幾乎與一般列表個(gè)體相似襟沮。事實(shí)上他們都是從list繼承而來的锥惋。唯一的不同在于permutation使用的是一個(gè)通過一些了float對(duì)list進(jìn)行填充昌腰。我們需要產(chǎn)生一串隨機(jī)地排列并且向個(gè)體提供這個(gè)排列。
第一個(gè)注冊(cè)的函數(shù)indices重指向random.sample()函數(shù)膀跌,數(shù)目為IND_SIZE遭商。(類似于之前的attr_float,將隨機(jī)生成的方式進(jìn)行確定捅伤,同時(shí)對(duì)生成的list進(jìn)行限定劫流?)第二個(gè)注冊(cè)的函數(shù)individual是一個(gè)initIterate()函數(shù)的調(diào)用,它的存儲(chǔ)器參數(shù)設(shè)定為creator.Individual類以及它的generator參數(shù)會(huì)被設(shè)定到toolbox.indice()。
調(diào)用toolbox.individual()可以通過填充參數(shù)并返回完整的creator.Individual來調(diào)用intiIterate(),組成一個(gè)最小化的單目標(biāo)優(yōu)化fitness序列怠晴。
這樣看來,上述操作的主要目的就在于使用不同的隨機(jī)方法生成個(gè)體數(shù)組可很,random.random為float類型(實(shí)驗(yàn)結(jié)果顯示均為0-1之間的數(shù)),float.sample為int類型凰浮。
2.3我抠、Arithmetic Expression
下一個(gè)個(gè)體是通常使用一個(gè)前綴樹{?Trie樹,即字典樹袜茧,又稱單詞查找樹或鍵樹菜拓,是一種樹形結(jié)構(gòu),是一種哈希樹的變種笛厦。典型應(yīng)用是用于統(tǒng)計(jì)和排序大量的字符串(但不僅限于字符串)尘惧,所以經(jīng)常被搜索引擎系統(tǒng)用于文本詞頻統(tǒng)計(jì)。它的優(yōu)點(diǎn)是:最大限度地減少無(wú)謂的字符串比較递递,查詢效率比哈希表高。}來進(jìn)行數(shù)學(xué)表達(dá)的啥么。在現(xiàn)在登舞,一個(gè)PrimitiveSet必須被定義,它包括我們的個(gè)體將會(huì)可能用到的所有數(shù)學(xué)運(yùn)算符悬荣。這里菠秒,這個(gè)集合被叫做MAIN并,它包括所有的單目運(yùn)算符氯迂。二目運(yùn)算符add()践叠,sub()和mul()被添加到primitive set。接下來嚼蚀,Individual類被創(chuàng)建禁灼,在這之前添加到靜態(tài)屬性(?)pest的東西將會(huì)記憶全局的primitive set(原始集合)。現(xiàn)在轿曙,個(gè)體的內(nèi)容將會(huì)通過genHalfAndHalf()函數(shù)生成弄捕,這個(gè)函數(shù)將會(huì)使用一個(gè)基于斜坡程序(???ramped list)的list產(chǎn)生樹僻孝。再一次的,個(gè)體將會(huì)通過initIterate()函數(shù)進(jìn)行初始化守谓,并且把完整生成的迭代信息給到個(gè)體類當(dāng)中穿铆。(意思是通過下面的操作,可以將數(shù)字與運(yùn)算符結(jié)合斋荞,構(gòu)成表達(dá)式樹荞雏?話不多說看代碼)
使用toolbox.individual()將會(huì)返回一個(gè)完整的個(gè)體,這個(gè)個(gè)體是通過一個(gè)計(jì)算表達(dá)式表達(dá)的平酿,它的目標(biāo)是一個(gè)最小單目標(biāo)凤优。
簡(jiǎn)單來說,上述步驟使用內(nèi)置的GP模塊完成了對(duì)表達(dá)式樹的創(chuàng)建染服,參數(shù)范圍應(yīng)該是(1,2)别洪。總結(jié)一下,創(chuàng)建個(gè)體(字符串個(gè)體和表達(dá)式樹個(gè)體)的主要步驟柳刮,首先來說字符串個(gè)體:
1挖垛、設(shè)置等長(zhǎng)字符串個(gè)體的長(zhǎng)度(IND_SIZE);
2秉颗、設(shè)置優(yōu)化目標(biāo)(最大or最小痢毒,單目標(biāo)or多目標(biāo));
3蚕甥、創(chuàng)建個(gè)體的list哪替,并與設(shè)定好的優(yōu)化目標(biāo)相對(duì)應(yīng);
4菇怀、使用toolbox工具設(shè)定(register)隨機(jī)數(shù)生成方式(int or float)及長(zhǎng)度(IND_SIZE)凭舶;
5、使用toolbox工具設(shè)定個(gè)體的生成方式(tools.initIterate or tools.initRepeat等)爱沟,不同的生成方式所需參數(shù)不一帅霜。
接下來是表達(dá)式樹個(gè)體:
1、設(shè)定perimitiveSet(調(diào)用GP包呼伸,設(shè)定‘MAIN’為單目運(yùn)算符)身冀,同時(shí)再向pset中加入一些多目運(yùn)算符,包括add()\sub()\mul()等括享。命令為pset.addPrimitive(operator.name, 'arity number')搂根;
2、創(chuàng)建目標(biāo)函數(shù)(同字符串個(gè)體一致)與個(gè)體(GP的Primitive樹而不是隨機(jī)數(shù)铃辖,同時(shí)要聲明pset剩愧,其余與字符串類似);
3澳叉、使用toolbox工具將表達(dá)式與個(gè)體進(jìn)行設(shè)定隙咸。
2.4沐悦、Evolution Strategy
個(gè)體的演化策略根據(jù)它們生成的list有輕微的不同,一個(gè)是對(duì)個(gè)體本身進(jìn)行五督,另一個(gè)是對(duì)它們進(jìn)行變異操作〔胤瘢現(xiàn)在,我們將會(huì)使用array.array繼承個(gè)體與策略充包,而不是使用一個(gè)基于類的list實(shí)現(xiàn)演化策略副签。因?yàn)闆]有任何的幫助函數(shù)在單目標(biāo)優(yōu)化問題中可以產(chǎn)生兩個(gè)不同的向量,我們必須自己去定義這些函數(shù)基矮。initES()函數(shù)接收兩種類(個(gè)體+策略淆储?),同時(shí)實(shí)例化它們將會(huì)為自己產(chǎn)生隨機(jī)數(shù)家浇,這些隨機(jī)數(shù)都是根據(jù)設(shè)定好的個(gè)體大小以及個(gè)體數(shù)目確定的本砰。
調(diào)用toolbox.individual()將會(huì)返回一個(gè)完整的演化策略,有一個(gè)策略向量以及一個(gè)最小值目標(biāo)函數(shù)钢悲。
不是特別明白它這個(gè)“EVOLUTION STRATEGY”是干嘛的点额,輸出結(jié)果是一個(gè)雙精度浮點(diǎn)型array,范圍(|x| > 1 && |x| < 5)莺琳。
2.5还棱、Particle
一個(gè)Particle是另一個(gè)特殊類型的個(gè)體,這是因?yàn)橥ǔG闆r下它有一個(gè)速度惭等,并且有一個(gè)最優(yōu)的位置需要去記憶珍手。這種類型個(gè)體的創(chuàng)建與通過list創(chuàng)建類似。現(xiàn)在辞做,speed, best和速度限制將會(huì)加入到一個(gè)目標(biāo)中琳要。再一次的,一個(gè)初始化函數(shù)initParticle()函數(shù)也同時(shí)可以被注冊(cè)并產(chǎn)生接受一些參數(shù)秤茅,包括Particle的個(gè)體焙蹭、大小、領(lǐng)域和速度限制等嫂伞。
調(diào)用toolbox.individual()將會(huì)容易地返回帶有speed向量和最大雙目標(biāo)優(yōu)化適應(yīng)度的particle。這個(gè)運(yùn)行報(bào)錯(cuò)(原因是139行的register為‘particle’拯钻,調(diào)用的卻是individual帖努,更改后即可使用),這個(gè)應(yīng)該是PSO初始化要用的東西粪般,不過PSO很簡(jiǎn)單拼余,不一定非要用它的包,MATLAB也就五六十行代碼自己寫寫就行了亩歹。
2.6匙监、A Funky One
假設(shè)你的問題有著極其特別的需求凡橱,你同樣可以輕松建立一個(gè)定制化的個(gè)體。下一個(gè)個(gè)體的創(chuàng)建是一個(gè)可以改變的整數(shù)和浮點(diǎn)數(shù)組成的list亭姥,使用initCycle()函數(shù)
調(diào)用toolbox.individual()將會(huì)返回由四個(gè)整型和四個(gè)浮點(diǎn)型組成的list稼钩,它們的順序是[int float int float int float... int float]。目標(biāo)有兩個(gè)达罗,均為最大目標(biāo)坝撑。
這個(gè)初始化方法看起來在混合規(guī)劃問題中很好用,但美中不足在于看起來像一個(gè)整數(shù)對(duì)應(yīng)一個(gè)浮點(diǎn)數(shù)這樣子粮揉。
3 Population
種群與個(gè)體非常類似巡李。它們不是用屬性初始化,而是充滿了個(gè)體扶认、策略以及粒子(針對(duì)不同方法采取不同的種群)侨拦。
3.1 Bag
一個(gè)種群的包是最常用的類型。它沒有特殊的排序辐宾,盡管這通常會(huì)使用list來實(shí)現(xiàn)狱从。由于包沒有特殊的屬性,它不需要任何特殊的類螃概。種群的初始化是通過使用toolbox中的initRepeat()函數(shù)直接實(shí)現(xiàn)的矫夯。
toolbox.register('population', tools.initRepeat, list, toolbox.individual)
調(diào)用toolbox.population(populationsize = n)就會(huì)返回一個(gè)種群數(shù)目為n的種群,例如2.6中的size為8的個(gè)體吊洼,使用上述命令即可生成100個(gè)這樣不同的個(gè)體训貌。
3.2 Grid
一個(gè)網(wǎng)格類型的種群時(shí)一種特殊結(jié)構(gòu)的種群,在這個(gè)種群中冒窍,相鄰個(gè)體相互之間是有直接地影響的递沪。個(gè)體在散布到網(wǎng)格的時(shí)候,每一個(gè)網(wǎng)格將會(huì)具有一個(gè)單獨(dú)的個(gè)體(類似于矩陣這樣)综液。然而款慨,它的實(shí)施與Bag的list實(shí)現(xiàn)不同之處在于,它是由多個(gè)list的個(gè)體構(gòu)成的谬莹。(多個(gè)list合成一個(gè)矩陣)
N_COL = 4
N_ROW = 4
toolbox.register('row', tools.initRepeat, list, toolbox.individual, n = N_COL)
toolbox.register('population', tools.initRepeat, list, toolbox.individual, n = N_ROW)
調(diào)用toolbox.population()就可以實(shí)現(xiàn)生成一個(gè)網(wǎng)格類型的種群檩奠。例如上面實(shí)現(xiàn)了一個(gè)雖然想要生成4x4的“矩陣”,但是由于每一個(gè)個(gè)體是一個(gè)1x8的向量附帽,因此實(shí)際的矩陣是一個(gè)4x8的埠戳。簡(jiǎn)單來說,就是如果產(chǎn)生的是單獨(dú)個(gè)體蕉扮,那么矩陣的大小是可以自己設(shè)置的整胃。但如果是類似于2.6中這樣的向量,那么如果維度超出你所設(shè)定的范圍喳钟,計(jì)算機(jī)會(huì)自動(dòng)擴(kuò)充矩陣屁使。
3.3 Swarm
一個(gè)Swarm是用在PSO中的在岂。它的不同之處在于它在某種意義上存在著一種交流網(wǎng)絡(luò)。最簡(jiǎn)單的網(wǎng)絡(luò)是全連接網(wǎng)絡(luò)蛮寂,就是每一個(gè)particle(2.5的 speed+position)都知道其它個(gè)體所到達(dá)的最好位置蔽午。這通常由復(fù)制全局最優(yōu)解gbest和全局最優(yōu)適應(yīng)度gbestfit實(shí)現(xiàn)。
creator.create('Swarm', list, gbest = None, gbestfit = creator.FitnessMax)
toolbox.register('swarm', tools.initRepeat, creator.Swarm, toolbox.particle)
調(diào)用toolbox.swarm(population_num = n)即可生成n個(gè)確定范圍(2.5Particle)不同位置和速度的粒子共郭。在計(jì)算gbest和gbestfit之后祠丝,就可以找到這代個(gè)體中的最佳粒子。
3.4 Demes(這是啥玩意兒除嘹?翻譯都沒有)
一個(gè)Deme是一個(gè)子種群(包含于種群中)写半。Demes是僅有的子種群,實(shí)際上與種群并沒有什么不同尉咕,除了名字(意思就是一個(gè)拷貝叠蝇?)。這里年缎,我們創(chuàng)建了一個(gè)包含三個(gè)Demes的種群悔捶,每一個(gè)都有不同樹木的個(gè)體,你可以通過使用在initRepeat()函數(shù)中的n參數(shù)對(duì)它進(jìn)行調(diào)節(jié)单芜。
toolbox.register('demes', tools.initRepeat, list, toolbox.individual)
DEME_SIZE = 10, 50, 100
populatiopn = [toolbox.demes(n = i) for i in DEME_SIZE]
這可以生成不同規(guī)模的種群蜕该,調(diào)用時(shí)候可以采取索引population[0],得到一個(gè)擁有十個(gè)個(gè)體的種群洲鸠。
3.5 Seedling a Population
一些時(shí)候堂淡,一個(gè)首先猜想種群(???first guess population)可以用于初始化一個(gè)演化算法。這種初始化種群的關(guān)鍵點(diǎn)在于沒有任何的隨機(jī)個(gè)體是要去擁有一個(gè)個(gè)體初始化函數(shù)扒腕。(也就是說沒有必要去先初始化個(gè)體然后不斷initRepeat绢淀?)
種群將會(huì)從文件my_guess.json初始化,將會(huì)包含一個(gè)擁有第一猜想的列表瘾腰。這種初始化方法可以與常規(guī)初始化方法相結(jié)合皆的,這樣就可以擁有部分隨機(jī)個(gè)體和部分非隨機(jī)個(gè)體。記住initIndividual()和individual_guess()是可以選擇的蹋盆,這是因?yàn)樗鼈兊哪J(rèn)結(jié)構(gòu)是相似的费薄。你可以移除212行使用217行的代碼代替。
總的來說栖雾,3.5的方法提供了一種手動(dòng)初始化的情況义锥,可以通過猜想來對(duì)數(shù)據(jù)初始化,一定程度上可以加快收斂岩灭,并且也提供了不完全隨機(jī)的生成方法。
4 總結(jié)
第二部分首先講了優(yōu)化目標(biāo)的選擇——其實(shí)很簡(jiǎn)單赂鲤,最大與最小噪径,單目標(biāo)與多目標(biāo)柱恤,在creator中的weights里面可以非常簡(jiǎn)單地設(shè)定。
接下來對(duì)個(gè)體的生成方法進(jìn)行了詳細(xì)的介紹找爱,包括浮點(diǎn)型list梗顺,整型序列(Permutation),數(shù)值表達(dá)式(AE)车摄,演化策略(ES)寺谤,粒子群(Particle)和混合個(gè)體(包含整型和浮點(diǎn)型,AFO)的生成吮播。AE的生成方式是表達(dá)式樹的生成变屁,與其他的部分是不同的。但總體上看意狠,都是首先確定優(yōu)化目標(biāo)粟关,接下來創(chuàng)建個(gè)體,最后使用toolbox對(duì)之前標(biāo)定的生成方法(隨機(jī)方法以及數(shù)據(jù)結(jié)構(gòu):樹or列表环戈?)以及個(gè)體進(jìn)行register闷板,最后使用toolbox.register_name生成個(gè)體。
種群的生成本質(zhì)上是多個(gè)個(gè)體的重復(fù)生成院塞。這里介紹了包(Bag)遮晚、網(wǎng)格(Grid),粒子群種群(Swarm)拦止,子(多)種群(Demes)以及非隨機(jī)種群(SaP)的生成县遣。不同類型的種群可以應(yīng)用到不同的算法當(dāng)中。
2018.09.03
?8.28pm