Matlab實(shí)現(xiàn)遺傳算法的示例詳解
這篇文章用了大量篇幅講解了如何從零開(kāi)始自己寫一個(gè)遺傳算法函數(shù),主要是為了應(yīng)對(duì)學(xué)生作業(yè)等情況,或者讓大家對(duì)遺傳算法有更充分的理解,如果要用于學(xué)術(shù)研究,最好還是使用自帶遺傳算法,之后可能會(huì)推出更多自帶遺傳算法工具箱的使用。
1 算法講解
1.1 何為遺傳算法
遺傳、突變、自然選擇、雜交,遺傳算法是一種借鑒了進(jìn)化生物學(xué)各類現(xiàn)象的進(jìn)化算法。
看到一個(gè)很形象的比喻來(lái)描述各類進(jìn)化算法的區(qū)別:
- 爬山算法:一只袋鼠朝著比現(xiàn)在高的地方跳去。它找到了不遠(yuǎn)處的最高的山峰。但是這座山不一定是最高峰。這就是爬山算法,它不能保證局部最優(yōu)值就是全局最優(yōu)值。
- 模擬退火:袋鼠喝醉了。它隨機(jī)地跳了很長(zhǎng)時(shí)間。這期間,它可能走向高處,也可能踏入平地。但是,它漸漸清醒了并朝最高峰跳去。這就是模擬退火算法。
- 遺傳算法:有很多袋鼠,它們降落到喜瑪拉雅山脈的任意地方。這些袋鼠并不知道它們的任務(wù)是尋找珠穆朗瑪峰。但每過(guò)幾年,就在一些海拔高度較低的地方射殺一些袋鼠。于是,不斷有袋鼠死于海拔較低的地方,而越是在海拔高的袋鼠越是能活得更久,也越有機(jī)會(huì)生兒育女。就這樣經(jīng)過(guò)許多年,這些袋鼠們竟然都不自覺(jué)地聚攏到了一個(gè)個(gè)的山峰上,可是在所有的袋鼠中,只有聚攏到珠穆朗瑪峰的袋鼠被帶回了美麗的澳洲。
1.2 遺傳算法流程描述
我們先隨機(jī)生成幾個(gè)個(gè)體(數(shù)值)。
計(jì)算這幾個(gè)個(gè)體是否適合當(dāng)前環(huán)境(帶入某個(gè)評(píng)價(jià)函數(shù)后結(jié)果大不大)
記錄一下最好的一個(gè)個(gè)體(記錄一下局部最優(yōu)解)。
依據(jù)適應(yīng)度選入、淘汰一些個(gè)體(結(jié)果越好的數(shù)值有越大的概率不被扔掉,但是怕局部最優(yōu)解所以還有有一定概率要被扔)。
交叉互換的方式進(jìn)行變異(轉(zhuǎn)換為十進(jìn)制語(yǔ)言來(lái)說(shuō),例如我有兩個(gè)數(shù)值13和15都還可以,新的兩個(gè)數(shù)值我要在11-17區(qū)間內(nèi)選倆)。
基因突變的方式進(jìn)行變異(在范圍內(nèi)變異固然好,但是怕陷入局部最優(yōu)解我還是要偶爾搞點(diǎn)大變異,哪怕是壞的變異) 。
進(jìn)入下一輪循環(huán),重新計(jì)算對(duì)當(dāng)前環(huán)境適應(yīng)程度繼續(xù)前面的一系列步驟。
好多好多代后(迭代次數(shù)大于我們的設(shè)定)后,輸出記錄的每一輪最優(yōu)解里面最好的一個(gè)。
1.3 關(guān)于為什么要用二進(jìn)制碼表示個(gè)體信息
這部分其實(shí)是借鑒了等位基因的概念,我們認(rèn)為不同二進(jìn)制碼相同位置的數(shù)值為等位基因。兩個(gè)二進(jìn)制碼鏈條相同位置交換我們可以看作交叉互換。
同時(shí)用二進(jìn)制碼還有可控變異的特點(diǎn):假如我們有個(gè)二進(jìn)制序列1111,轉(zhuǎn)換為十進(jìn)制就是15
若是我們將其變?yōu)?110,十進(jìn)制變?yōu)?4
若是我們將其變?yōu)?101,十進(jìn)制變?yōu)?3
變?yōu)?011,十進(jìn)制變?yōu)?1
變?yōu)?111,十進(jìn)制變?yōu)?
也就是說(shuō),我們可以在大部分位置數(shù)據(jù)信息不變的情況下,各種幅度的改變我們的二進(jìn)制序列代表的十進(jìn)制信息。
1.4 目標(biāo)函數(shù)值與適應(yīng)值區(qū)別
適應(yīng)值=目標(biāo)函數(shù)值-f(x)下限 為了方便求概率才多了個(gè)這么個(gè)操作, 舉幾個(gè)例子:
- 假設(shè)f(x)范圍是[0,3] 那么三個(gè)個(gè)體函數(shù)值為[1,2,3],那么每個(gè)個(gè)體被取到的概率很自然我們就想到設(shè)置為[1,2,3]/(1+2+3)=[1/6,1/3,1/2],數(shù)值越大取到概率越大很正常。
- 假設(shè)f(x)范圍為[10,10.1] 三個(gè)個(gè)體函數(shù)值為[10.01,10.05,10.03],算出其概率為[0.3327,0.3340,0.3333]非常的接近,這是因?yàn)?.幾的數(shù)對(duì)比與10太小了,因而減去10非常有必要。
- 假設(shè)f(x)范圍為[-1,1] 萬(wàn)一有個(gè)體數(shù)值為負(fù)數(shù)總不能搞個(gè)負(fù)數(shù)概率叭,所以-(-1)也是很有必要的。
綜上我們看出Fmin的設(shè)置也需要有一定講究,不能使適應(yīng)值出現(xiàn)負(fù)數(shù),也最好能使數(shù)據(jù)具有區(qū)分度,當(dāng)然如果有更加合適的映射來(lái)代替線性映射也是極好(例如機(jī)器學(xué)習(xí)就常用sigmod函數(shù)來(lái)映射)。
1.5 關(guān)于如何將二進(jìn)制碼轉(zhuǎn)化為變量數(shù)值
假設(shè)我們有一個(gè)長(zhǎng)度為4的二進(jìn)制碼,則其取值范圍為0000至1111即[0,15];同時(shí)我們知道最優(yōu)解范圍是[2,3],我們只需要將二進(jìn)制碼轉(zhuǎn)化為十進(jìn)制,并且映射到最優(yōu)解取值范圍就好啦, 例如1011轉(zhuǎn)換為十進(jìn)制為11,從區(qū)間[0,15]映射到[2,3]即為, (11-0)/(15-0)*(3-2)+2=2.7333, 從這個(gè)轉(zhuǎn)換方式我們可以看出:
二進(jìn)制碼越長(zhǎng),其可取值也就越多也就能把最優(yōu)解區(qū)間劃分的越細(xì),也就能使結(jié)果越精確,(當(dāng)然我們可以依據(jù)我們想要的精確度大體設(shè)置二進(jìn)制碼長(zhǎng)度)
最優(yōu)解區(qū)間范圍一定要有?。《乙粋€(gè)好的最優(yōu)解區(qū)間能夠讓我們?cè)谌≥^短的二進(jìn)制碼時(shí)依舊可以得到較為精確的結(jié)果。
1.6 關(guān)于代碼改進(jìn)
雖然肯定比不上MATLAB自帶的函數(shù),但是對(duì)于各種自行構(gòu)造的遺傳算法代碼,很多很多老版代碼各種循環(huán),這里能用向量運(yùn)算就用向量運(yùn)算,增加量程序的整潔度和速度。
2 MATLAB自帶ga函數(shù)
2.1 問(wèn)題描述
這里先講解一個(gè)簡(jiǎn)單的問(wèn)題,之后可能會(huì)講解遺傳算法更詳細(xì)應(yīng)用。
2.2 自帶函數(shù)使用
這里ga求的是最小值,因此我們?nèi)€(gè)相反數(shù)。
tic f=@(x)-(x+10*sin(5*x)+7*cos(4*x)); x=ga(f,1,[],[],[],[],0,9) -f(x) toc
x = 7.8568
ans = 24.8554
歷時(shí) 0.072996 秒。
3 自編遺傳算法各部分代碼及使用
3.1代碼使用
使用代碼:
tic [Count,Result,BestMember]=Genetic1(24,6,@(x)x+10*sin(5*x)+7*cos(4*x),0,9,15,0.9,200) toc
參數(shù):
- 24,二進(jìn)制碼長(zhǎng)度為24
- 6,個(gè)體數(shù)目為6
- @(x)x+10sin(5x)+7cos(4x),評(píng)價(jià)函數(shù)
- 0,x取值下限
- 9,x取值上限
- 15,f(x)下限,低于這個(gè)的我們認(rèn)為這個(gè)個(gè)體完全不適合在該環(huán)境下生存
- 0.9,突變概率為了防止陷入局部最優(yōu)這里數(shù)值設(shè)的其實(shí)有點(diǎn)大,大家用的時(shí)候設(shè)置小點(diǎn)就好
- 200,迭代代數(shù)
關(guān)于各個(gè)參數(shù)更詳細(xì)的說(shuō)明往后看。
計(jì)算結(jié)果:
Count =200
Result =
7.8401,7.8048,7.8443,7.8403,7.8574,8.9649
24.8050,24.3683 ,24.8271,24.8066,11.1532,14.5649
BestMember =
7.8574
24.8553
歷時(shí) 0.117459 秒。
即時(shí)取最大值,和自帶函數(shù)算的也差不多。雖然結(jié)果不如自帶函數(shù)穩(wěn)定。畫(huà)個(gè)圖看看:
注:遺傳算法畢竟是智能算法,算出的值并不一定是最優(yōu)解,因而可以調(diào)整迭代次數(shù)的大小,變異概率,二進(jìn)制串長(zhǎng)度,個(gè)體數(shù)量等一系列數(shù)據(jù)來(lái)調(diào)整,正因?yàn)楦鱾€(gè)變量比較難以說(shuō)明為何這樣設(shè)置,所以各種建模比賽還是盡量少用這樣的智能算法。
3.2 Genetic1--主函數(shù)
function?[Count,Result,BestMember]=Genetic1(MumberLength,MemberNumber,FunctionFitness,MinX,MaxX,Fmin,MutationProbability,Gen) %?參數(shù)解釋:? %?參數(shù)名????????????????參數(shù)類型??????????參數(shù)含義 %?========================================================================= %?MumberLength?????? |??數(shù)值??|?表示一個(gè)染色體位串的二進(jìn)制長(zhǎng)度 %?MemberNumber?????? |??數(shù)值??|?表示群體中染色體個(gè)數(shù) %?FunctionFitness????|??字符串|?表示目標(biāo)函數(shù) %?MinX?????????????? |??數(shù)值??|?變量區(qū)間的下限 %?MaxX?????????????? |??數(shù)值??|?變量區(qū)間的上限 %?Fmin?????????????? |??數(shù)值??|?適應(yīng)函數(shù)過(guò)程中給出目標(biāo)函數(shù)可能最小值 %?MutationProbability|??數(shù)值??|?變異概率 %?Gen????????????????|??數(shù)值??|??遺傳代數(shù) %?------------------------------------------------------------------------- %?Count????????????? |??數(shù)值??|?遺傳代數(shù) %?Result?????????????|??數(shù)值??|?計(jì)算結(jié)果 %?BestMember?????????|??數(shù)值??|??最優(yōu)個(gè)體及其適應(yīng)值 global?Count;Count=1;%?在之后的版本中可能會(huì)不支持函數(shù)輸出作為全局變量(建議在改進(jìn)工作中修改) global?CurrentBest;??%?聲明全局變量Count(代數(shù))和CurrentBest(當(dāng)前代數(shù)下的最優(yōu)染色體) %?隨機(jī)地產(chǎn)生一個(gè)初始群體。 Population=PopulationInitialize(MumberLength,MemberNumber);?PopulationCode=Population; %?計(jì)算群體中每一個(gè)染色體的目標(biāo)函數(shù)值,適應(yīng)函數(shù)值,入選概率 PopulationFitness=Fitness(PopulationCode,FunctionFitness,MinX,MaxX,MumberLength); PopulationFitnessF=FitnessF(PopulationFitness,Fmin); PopulationProbability=Probability(PopulationFitnessF); %?依據(jù)入選概率保留個(gè)體并記錄最優(yōu)個(gè)體 [Population,CurrentBest,EachGenMaxFitness]=Elitist(PopulationCode,PopulationFitness,MumberLength); EachMaxFitness(Count)=EachGenMaxFitness; MaxFitness(Count)=CurrentBest(MumberLength+1); while?Count<Gen ????%?通過(guò)入選概率將入選概率大的個(gè)體選入種群,淘汰概率小的個(gè)體形成新群體 ????NewPopulation=Select(Population,PopulationProbability,MemberNumber); ????Population=NewPopulation; ???? ????%?通過(guò)交叉互換形成新群體; ????NewPopulation=Crossing(Population); ????Population=NewPopulation; ???? ????%?通過(guò)變異形成新群體 ????NewPopulation=Mutation(Population,MutationProbability); ????Population=NewPopulation; ???? ????%?計(jì)算新群體中每一染色體的目標(biāo)函數(shù)值并借此計(jì)算出適應(yīng)值與入選概率 ????PopulationFitness=Fitness(Population,FunctionFitness,MinX,MaxX,MumberLength); ????PopulationFitnessF=FitnessF(PopulationFitness,Fmin); ????PopulationProbability=Probability(PopulationFitnessF); ????Count=Count+1; ???? ????%?替換當(dāng)前最優(yōu)個(gè)體并將最劣個(gè)體用最優(yōu)個(gè)體替換 ????[NewPopulation,CurrentBest,EachGenMaxFitness]=Elitist(Population,PopulationFitness,MumberLength); ???? ????% EachMaxFitness,記錄了第Count代中最優(yōu)個(gè)體所對(duì)應(yīng)的目標(biāo)函數(shù)值; ????% MaxFitness,前Count代中最優(yōu)個(gè)體所對(duì)應(yīng)的目標(biāo)函數(shù)值; ????EachMaxFitness(Count)=EachGenMaxFitness; ????MaxFitness(Count)=CurrentBest(MumberLength+1); ????Population=NewPopulation;???? end %?數(shù)據(jù)整理 Dim=size(Population); Result=ones(2,Dim(1)); for?ii=1:Dim(1) ????Result(1,ii)=Translate(Population(ii,:),MinX,MaxX,MumberLength); end Result(2,:)=Fitness(Population,FunctionFitness,MinX,MaxX,MumberLength); BestMember(1,1)=Translate(CurrentBest(1:MumberLength),MinX,MaxX,MumberLength); BestMember(2,1)=CurrentBest(MumberLength+1); %?繪圖 close?all subplot(2,1,1) plot(EachMaxFitness); subplot(2,1,2) plot(MaxFitness); end
3.3 PI(PopulationInitialize)--產(chǎn)生初始種群
功能: 隨機(jī)地產(chǎn)生一個(gè)初始群體。
輸入變量:
- MemberNumber代表染色體個(gè)數(shù);
- MumberLength代表每個(gè)染色體上含有MumberLength個(gè)基因(即編碼長(zhǎng)度);
輸出變量: Poplation表示第一代群體。
原理: 生成MemberNumber個(gè)長(zhǎng)度為MumberLength的0-1向量。
function?Population=PopulationInitialize(MumberLength,MemberNumber) Temporary=rand(MemberNumber,MumberLength); Population=Temporary>=0.5; %?Population是一個(gè)邏輯矩陣(0-1矩陣,這么寫為了方便), %?在此函數(shù)中表示第一代群體,Population的每一行表示一個(gè)染色體 end
3.4 Fitness--計(jì)算目標(biāo)函數(shù)值
功能: 計(jì)算群體中每一個(gè)染色體的目標(biāo)函數(shù)值。
輸入?yún)?shù):
- PopulationCode表示用二進(jìn)制代碼表示的群體;
- FunctionFitness表示目標(biāo)函數(shù);
- MinX,MaxX分別表示變量區(qū)間的下限和上限;
- MumberLength代表一個(gè)染色體位串的二進(jìn)制長(zhǎng)度;
輸出變量:PopulationFitness表示每一染色體對(duì)應(yīng)的目標(biāo)函數(shù)值
原理:這部分就是把各個(gè)二進(jìn)制碼轉(zhuǎn)換為十進(jìn)制數(shù)(區(qū)間范圍內(nèi)),然后再帶入到目標(biāo)函數(shù)中算出數(shù)值。
說(shuō)明: 由于懶,這里把網(wǎng)上大部分代碼中的Translate函數(shù)和Transfer函數(shù)也合了進(jìn)去,沒(méi)必要為了兩行運(yùn)算多開(kāi)倆函數(shù)吧。。。
function?PopulationFitness=Fitness(PopulationCode,FunctionFitness,MinX,MaxX,MumberLength) Dim=size(PopulationCode); PopulationFitness=zeros(1,Dim(1)); for?i=1:Dim(1) ?%?轉(zhuǎn)換為10進(jìn)制 ????PopulationData=sum(PopulationCode(i,:).*(2.^(MumberLength-1:-1:0))); ????%?映射到x取值范圍 ????PopulationData=MinX+PopulationData*(MaxX-MinX)/(2^Dim(2)-1); ????%?計(jì)算對(duì)應(yīng)f(x)數(shù)值 ????PopulationFitness(i)=FunctionFitness(PopulationData); end end
3.5 FitnessF--計(jì)算適應(yīng)值
功能: 計(jì)算每個(gè)染色體的適應(yīng)函數(shù)值。
輸入?yún)?shù):PopulationFitness表示目標(biāo)函數(shù)值;Fmin表示目標(biāo)函數(shù)的可能的最小值;
輸出參數(shù): PopulationFitnessF表示每一染色體的適應(yīng)函數(shù)值。
function?PopulationFitnessF=FitnessF(PopulationFitness,Fmin) %?若某一染色體的目標(biāo)函數(shù)值大于Fmin,則置其適應(yīng)函數(shù)值為其目標(biāo)函數(shù)值-Fmin %?若某一染色體的目標(biāo)函數(shù)值小于Fmin,則置其適應(yīng)函數(shù)值為0 PopulationFitnessF=PopulationFitness-Fmin; PopulationFitnessF(PopulationFitnessF<0)=0; end
3.6 Translate--將二進(jìn)制碼轉(zhuǎn)換
這部分代碼已經(jīng)包含在Fitness函數(shù)內(nèi)了,再寫一遍是專門用來(lái)服務(wù)于最后的結(jié)果輸出的。
function?PopulationData=Translate(PopulationCode,MinX,MaxX,MumberLength) ????Dim=size(PopulationCode); ????PopulationData=sum(PopulationCode.*(2.^(MumberLength-1:-1:0))); ????PopulationData=MinX+PopulationData*(MaxX-MinX)/(2^Dim(2)-1); end
3.7 Probability--染色體入選概率
就是將適應(yīng)值轉(zhuǎn)換為概率,其方法就是除以所有適應(yīng)值的和。
function?PopulationProbability=Probability(PopulationFitnessF) ????PopulationProbability=PopulationFitnessF./sum(PopulationFitnessF); end
3.8 Select--個(gè)體選擇
根據(jù)入選概率在群體中按比例選擇部分染色體組成種群。
function?NewPopulation=Select(Population,PopulationProbability,MemberNumber)??????? ????%?概率密度轉(zhuǎn)換為概率分布 ????CProbability=PopulationProbability(1); ????for?i=2:MemberNumber ????????CProbability(i)=CProbability(i-1)+PopulationProbability(i); ????end ???????? ????%?搖隨機(jī)數(shù)并依據(jù)隨機(jī)數(shù)和概率選擇個(gè)體 ????pmat=rand([MemberNumber,1]); ????index=sum((pmat>=CProbability),2)+1; ????NewPopulation=Population(index,:); end
3.9 Crossing--交叉互換
群體中的交叉并產(chǎn)生新群體,原理描述如下:
我們每次都是兩個(gè)相鄰的進(jìn)行交叉,這樣如果個(gè)體數(shù)為奇數(shù),則最后一個(gè)個(gè)體則一直無(wú)法參與互換,因此我們每次都將倒數(shù)第一和倒數(shù)第二個(gè)體換位置,這樣倒數(shù)第一位和倒數(shù)第二位就能夠輪流參與交叉互換。(當(dāng)然其實(shí)直接整體全部交換順序也可以)。
function?NewPopulation=Crossing(Population) Dim=size(Population); if?Dim(1)>=3 ????Population([Dim(1),Dim(1)-1],:)=Population([Dim(1)-1,Dim(1)],:); ?%?若群體中個(gè)體數(shù)大于等于3,則將最后一個(gè)個(gè)體與倒數(shù)第二個(gè)個(gè)體基因型互換; ????%?目的是防止有個(gè)體從始至終未參與交叉。 end for?i=1:2:Dim(1)-1 ????%?相鄰的倆個(gè)體交叉互換 ????Site=randi(Dim(2)); ????Population([i,i+1],1:Site)=Population([i+1,i],1:Site); end NewPopulation=Population; end
想改成全部互換則可寫做:
function?NewPopulation=Crossing(Population) Dim=size(Population); Population(1:Dim,:)=Population(randperm(Dim(1)),:); for?i=1:2:Dim(1)-1 ????Site=randi(Dim(2)); ????Population([i,i+1],1:Site)=Population([i+1,i],1:Site); end NewPopulation=Population; end
3.10 Mutation--基因突變
為每個(gè)個(gè)體搖個(gè)隨機(jī)數(shù),如果隨機(jī)數(shù)符合變異概率,就隨機(jī)將該個(gè)體其中一個(gè)0變?yōu)?或?qū)?變?yōu)?。
function?NewPopulation=Mutation(Population,MutationProbability) Dim=size(Population); for?i=1:Dim(1) ????Probability=rand(1); ????Site=randi(Dim(2)); ????if?Probability<MutationProbability ????????Population(i,Site)=mod(Population(i,Site)+1,2); ????end end NewPopulation=Population; end
3.11 Elitist--最優(yōu)個(gè)體記錄與最劣個(gè)體淘汰
功能: 如果當(dāng)前序列中有個(gè)體優(yōu)于歷史最優(yōu)則更新歷史最優(yōu),同時(shí)將當(dāng)前個(gè)體組中最差個(gè)體用歷史最優(yōu)代替。
輸入變量:
- Population 表示當(dāng)前群體;
- PopulationFitness 表示當(dāng)前群體的目標(biāo)函數(shù)值;
- MumberLength 表示一個(gè)染色體位串的二進(jìn)制長(zhǎng)度;
輸出變量:
- NewPopulationIncludeMax 表示包含歷史最優(yōu)個(gè)體的新一代群體;
- CurrentBest 所有代中最優(yōu)個(gè)體(當(dāng)前歷史最優(yōu)個(gè)體);
- EachGenMaxFitness,這一帶種群中最優(yōu)個(gè)體;
function?[NewPopulationIncludeMax,NewCurrentBest,EachGenMaxFitness]=... ????Elitist(Population,PopulationFitness,MumberLength) ???? %?找到當(dāng)前種群最優(yōu)和最差個(gè)體 [~,MinSite]=min(PopulationFitness); [MaxFitnesstemp,MaxSite]=max(PopulationFitness); EachGenMaxFitness=MaxFitnesstemp; %?更新歷史最優(yōu) if?Count==1 ????CurrentBest(1:MumberLength)=Population(MaxSite,:); ????CurrentBest(MumberLength+1)=PopulationFitness(MaxSite); else ????if?CurrentBest(MumberLength+1)<MaxFitnesstemp ????????CurrentBest(1:MumberLength)=Population(MaxSite,:); ????????CurrentBest(MumberLength+1)=PopulationFitness(MaxSite); ????end ?%?當(dāng)前種群最差用歷史最優(yōu)代替 ????Population(MinSite,:)=CurrentBest(1:MumberLength); end NewPopulationIncludeMax=Population; NewCurrentBest=CurrentBest; end
3.12完整代碼
把所有代碼合在了一起:
function?[Count,Result,BestMember]=Genetic1(MumberLength,MemberNumber,FunctionFitness,MinX,MaxX,Fmin,MutationProbability,Gen) %?參數(shù)解釋:? %?參數(shù)名????????????????參數(shù)類型??????????參數(shù)含義 %?========================================================================= %?MumberLength?????? |??數(shù)值??|?表示一個(gè)染色體位串的二進(jìn)制長(zhǎng)度 %?MemberNumber?????? |??數(shù)值??|?表示群體中染色體個(gè)數(shù) %?FunctionFitness????|??字符串|?表示目標(biāo)函數(shù) %?MinX?????????????? |??數(shù)值??|?變量區(qū)間的下限 %?MaxX?????????????? |??數(shù)值??|?變量區(qū)間的上限 %?Fmin?????????????? |??數(shù)值??|?適應(yīng)函數(shù)過(guò)程中給出目標(biāo)函數(shù)可能最小值 %?MutationProbability|??數(shù)值??|?變異概率 %?Gen????????????????|??數(shù)值??|??遺傳代數(shù) %?------------------------------------------------------------------------- %?Count????????????? |??數(shù)值??|?遺傳代數(shù) %?Result?????????????|??數(shù)值??|?計(jì)算結(jié)果 %?BestMember?????????|??數(shù)值??|??最優(yōu)個(gè)體及其適應(yīng)值 global?Count;Count=1;%?在之后的版本中可能會(huì)不支持函數(shù)輸出作為全局變量(建議在改進(jìn)工作中修改) global?CurrentBest;??%?聲明全局變量Count(代數(shù))和CurrentBest(當(dāng)前代數(shù)下的最優(yōu)染色體) %?隨機(jī)地產(chǎn)生一個(gè)初始群體。 Population=PopulationInitialize(MumberLength,MemberNumber);?PopulationCode=Population; %?計(jì)算群體中每一個(gè)染色體的目標(biāo)函數(shù)值,適應(yīng)函數(shù)值,入選概率 PopulationFitness=Fitness(PopulationCode,FunctionFitness,MinX,MaxX,MumberLength); PopulationFitnessF=FitnessF(PopulationFitness,Fmin); PopulationProbability=Probability(PopulationFitnessF); %?依據(jù)入選概率保留個(gè)體并記錄最優(yōu)個(gè)體 [Population,CurrentBest,EachGenMaxFitness]=Elitist(PopulationCode,PopulationFitness,MumberLength); EachMaxFitness(Count)=EachGenMaxFitness; MaxFitness(Count)=CurrentBest(MumberLength+1); while?Count<Gen ????%?通過(guò)入選概率將入選概率大的個(gè)體選入種群,淘汰概率小的個(gè)體形成新群體 ????NewPopulation=Select(Population,PopulationProbability,MemberNumber); ????Population=NewPopulation; ???? ????%?通過(guò)交叉互換形成新群體; ????NewPopulation=Crossing(Population); ????Population=NewPopulation; ???? ????%?通過(guò)變異形成新群體 ????NewPopulation=Mutation(Population,MutationProbability); ????Population=NewPopulation; ???? ????%?計(jì)算新群體中每一染色體的目標(biāo)函數(shù)值并借此計(jì)算出適應(yīng)值與入選概率 ????PopulationFitness=Fitness(Population,FunctionFitness,MinX,MaxX,MumberLength); ????PopulationFitnessF=FitnessF(PopulationFitness,Fmin); ????PopulationProbability=Probability(PopulationFitnessF); ????Count=Count+1; ???? ????%?替換當(dāng)前最優(yōu)個(gè)體并將最劣個(gè)體用最優(yōu)個(gè)體替換 ????[NewPopulation,CurrentBest,EachGenMaxFitness]=Elitist(Population,PopulationFitness,MumberLength); ???? ????% EachMaxFitness,記錄了第Count代中最優(yōu)個(gè)體所對(duì)應(yīng)的目標(biāo)函數(shù)值; ????% MaxFitness,前Count代中最優(yōu)個(gè)體所對(duì)應(yīng)的目標(biāo)函數(shù)值; ????EachMaxFitness(Count)=EachGenMaxFitness; ????MaxFitness(Count)=CurrentBest(MumberLength+1); ????Population=NewPopulation;???? end %?數(shù)據(jù)整理 tDim=size(Population); Result=ones(2,tDim(1)); for?ii=1:tDim(1) ????Result(1,ii)=Translate(Population(ii,:),MinX,MaxX,MumberLength); end Result(2,:)=Fitness(Population,FunctionFitness,MinX,MaxX,MumberLength); BestMember(1,1)=Translate(CurrentBest(1:MumberLength),MinX,MaxX,MumberLength); BestMember(2,1)=CurrentBest(MumberLength+1); %?繪圖 close?all subplot(2,1,1) plot(EachMaxFitness); subplot(2,1,2) plot(MaxFitness); %子函數(shù)部分 %========================================================================== %PopulationInitialize:用于產(chǎn)生一個(gè)初始群體,這個(gè)初始群體含有MemberNumber %個(gè)染色體,每個(gè)染色體含有MumberLength個(gè)基因。 ????function?Population=PopulationInitialize(MumberLength,MemberNumber) ????????Temporary=rand(MemberNumber,MumberLength); ????????Population=Temporary>=0.5; ????end %Fitness:?用于計(jì)算群體中每一個(gè)染色體的目標(biāo)函數(shù)值 ????function?PopulationFitness=Fitness(PopulationCode,FunctionFitness,MinX,MaxX,MumberLength) ????????Dim=size(PopulationCode); ????????PopulationFitness=zeros(1,Dim(1)); ????????for?i=1:Dim(1) ????????????PopulationData=sum(PopulationCode(i,:).*(2.^(MumberLength-1:-1:0))); ????????????PopulationData=MinX+PopulationData*(MaxX-MinX)/(2^Dim(2)-1); ????????????PopulationFitness(i)=FunctionFitness(PopulationData); ????????end ????end %FitnessF:?用于計(jì)算每個(gè)染色體適應(yīng)值 ????function?PopulationFitnessF=FitnessF(PopulationFitness,Fmin) ????????PopulationFitnessF=PopulationFitness-Fmin; ????????PopulationFitnessF(PopulationFitnessF<0)=0; ????end %Translate ????function?PopulationData=Translate(PopulationCode,MinX,MaxX,MumberLength) ????????Dim=size(PopulationCode); ????????PopulationData=sum(PopulationCode.*(2.^(MumberLength-1:-1:0))); ????????PopulationData=MinX+PopulationData*(MaxX-MinX)/(2^Dim(2)-1); ????end %Probability:?用于計(jì)算每個(gè)染色體入選概率 ????function?PopulationProbability=Probability(PopulationFitnessF) ????????PopulationProbability=PopulationFitnessF./sum(PopulationFitnessF); ????end %Elitist:?使用最佳個(gè)體保存法,輸入?yún)?shù)為: %Population?群體 %PopulationFitness?目標(biāo)函數(shù)值 %MutationProbability?變異概率 ????function?[NewPopulationIncludeMax,NewCurrentBest,EachGenMaxFitness]=... ????????????Elitist(Population,PopulationFitness,MumberLength) ????????[~,MinSite]=min(PopulationFitness); ????????[MaxFitnesstemp,MaxSite]=max(PopulationFitness); ????????EachGenMaxFitness=MaxFitnesstemp; ????????if?Count==1 ????????????CurrentBest(1:MumberLength)=Population(MaxSite,:); ????????????CurrentBest(MumberLength+1)=PopulationFitness(MaxSite); ????????else ????????????if?CurrentBest(MumberLength+1)<MaxFitnesstemp ????????????????CurrentBest(1:MumberLength)=Population(MaxSite,:); ????????????????CurrentBest(MumberLength+1)=PopulationFitness(MaxSite); ????????????end?????? ????????????Population(MinSite,:)=CurrentBest(1:MumberLength); ????????end ????????NewPopulationIncludeMax=Population;?? ????????NewCurrentBest=CurrentBest; ????end?????? %Select:?根據(jù)入選概率,在群體中按比例選擇部分染色體組成種群 ????function?NewPopulation=Select(Population,PopulationProbability,MemberNumber)??????? ????????%?概率密度轉(zhuǎn)換為概率分布 ????????CProbability=PopulationProbability(1); ????????for?i=2:MemberNumber ????????????CProbability(i)=CProbability(i-1)+PopulationProbability(i); ????????end ???????? ????????%?搖隨機(jī)數(shù)并依據(jù)隨機(jī)數(shù)和概率選擇個(gè)體 ????????pmat=rand([MemberNumber,1]); ????????index=sum((pmat>=CProbability),2)+1; ????????NewPopulation=Population(index,:); ????end %Crossing:?用于群體中的交叉并產(chǎn)生新群體 ????function?NewPopulation=Crossing(Population) ????????Dim=size(Population); ???????? ????????Population(1:Dim,:)=Population(randperm(Dim(1)),:); %?????????if?Dim(1)>=3 %?????????????Population([Dim(1),Dim(1)-1],:)=Population([Dim(1)-1,Dim(1)],:); %?????????end ????????for?i=1:2:Dim(1)-1 ????????????Site=randi(Dim(2)); ????????????Population([i,i+1],1:Site)=Population([i+1,i],1:Site); ????????end ????????NewPopulation=Population; ????end %Mutation:?用于群體中少量個(gè)體變量并產(chǎn)生新的群體 ????function?NewPopulation=Mutation(Population,MutationProbability) ????????Dim=size(Population); ????????for?i=1:Dim(1) ????????????Probability=rand(1); ????????????Site=randi(Dim(2)); ????????????if?Probability<MutationProbability ????????????????Population(i,Site)=mod(Population(i,Site)+1,2); ????????????end ????????end ????????NewPopulation=Population; ????end end
以上就是Matlab實(shí)現(xiàn)遺傳算法的示例詳解的詳細(xì)內(nèi)容,更多關(guān)于Matlab遺傳算法的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
C語(yǔ)言求兩個(gè)正整數(shù)的最大公約數(shù)示例代碼
在C語(yǔ)言中求兩個(gè)數(shù)的最大公約數(shù)是學(xué)習(xí)循環(huán)語(yǔ)句的非常經(jīng)典的問(wèn)題,下面這篇文章主要給大家介紹了關(guān)于C語(yǔ)言求兩個(gè)正整數(shù)的最大公約數(shù)的相關(guān)資料,需要的朋友可以參考下2021-12-12線程崩潰不會(huì)導(dǎo)致?JVM?崩潰的原因解析
網(wǎng)上看到一個(gè)很有意思的據(jù)說(shuō)是美團(tuán)的面試題:為什么線程崩潰崩潰不會(huì)導(dǎo)致?JVM?崩潰,這個(gè)問(wèn)題我看了不少回答,但都沒(méi)答到根本原因,所以決定答一答,相信大家看完肯定會(huì)有收獲,本文分以下幾節(jié)來(lái)探討,需要的朋友可以參考下2022-06-06Visual?Studio2022的完全卸載及安裝到D盤的操作方法
這篇文章主要介紹了Visual?Studio2022的完全卸載以及完全安裝到D盤,因?yàn)閂S如果隨便寫在會(huì)有很多很多的亂七八糟的東西掉出來(lái),所以我們選擇制式一點(diǎn)的卸載方式,需要的朋友可以參考下2022-09-09編譯錯(cuò)誤error: stray ‘\343’in program的解決方法
以下是對(duì)編譯錯(cuò)誤error: stray ‘\343’in program的解決方法進(jìn)行了詳細(xì)的分析介紹,如遇此問(wèn)題的朋友們可以過(guò)來(lái)參考下2013-07-07詳解C語(yǔ)言快速排序三種方法的單趟實(shí)現(xiàn)
本文將通過(guò)圖片重點(diǎn)為大家介紹一下C語(yǔ)言中快速排序三種方法的單趟實(shí)現(xiàn):分別是hoare法、挖坑法、雙指針?lè)ǎ闹惺纠a講解詳細(xì),感興趣的可以了解一下2022-06-06C++實(shí)現(xiàn)簡(jiǎn)單酒店管理系統(tǒng)
這篇文章主要為大家詳細(xì)介紹了C++實(shí)現(xiàn)簡(jiǎn)單酒店管理系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-08-08OpenCV透視變換應(yīng)用之書(shū)本視圖矯正+廣告屏幕切換
透視變換是指利用透視中心、像點(diǎn)、目標(biāo)點(diǎn)三點(diǎn)共線的條件,按透視旋轉(zhuǎn)定律使承影面繞跡線旋轉(zhuǎn)某一角度,破壞原有的投影光線束,仍能保持承影面上投影幾何圖形不變的變換。本文將為大家介紹兩個(gè)OpenCV透視變換應(yīng)用,需要的可以參考一下2022-08-08c語(yǔ)言實(shí)現(xiàn)的hashtable分享
哈希表效率高,眾所周知。應(yīng)用廣泛,php中大部分存儲(chǔ)使用的都是hashtable,包括變量,數(shù)組…如何使用c語(yǔ)言實(shí)現(xiàn)hashtable呢,現(xiàn)提供自己的思路,如有不妥之處,敬請(qǐng)賜教2014-01-01