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