遺傳演算法n皇後
A. 遺傳演算法
遺傳演算法實例:
也是自己找來的,原代碼有少許錯誤,本人都已更正了,調試運行都通過了的。
對於初學者,尤其是還沒有編程經驗的非常有用的一個文件
遺傳演算法實例
% 下面舉例說明遺傳演算法 %
% 求下列函數的最大值 %
% f(x)=10*sin(5x)+7*cos(4x) x∈[0,10] %
% 將 x 的值用一個10位的二值形式表示為二值問題,一個10位的二值數提供的解析度是每為 (10-0)/(2^10-1)≈0.01 。 %
% 將變數域 [0,10] 離散化為二值域 [0,1023], x=0+10*b/1023, 其中 b 是 [0,1023] 中的一個二值數。 %
% %
%--------------------------------------------------------------------------------------------------------------%
%--------------------------------------------------------------------------------------------------------------%
% 編程
%-----------------------------------------------
% 2.1初始化(編碼)
% initpop.m函數的功能是實現群體的初始化,popsize表示群體的大小,chromlength表示染色體的長度(二值數的長度),
% 長度大小取決於變數的二進制編碼的長度(在本例中取10位)。
%遺傳演算法子程序
%Name: initpop.m
%初始化
function pop=initpop(popsize,chromlength)
pop=round(rand(popsize,chromlength)); % rand隨機產生每個單元為 {0,1} 行數為popsize,列數為chromlength的矩陣,
% roud對矩陣的每個單元進行圓整。這樣產生的初始種群。
% 2.2 計算目標函數值
% 2.2.1 將二進制數轉化為十進制數(1)
%遺傳演算法子程序
%Name: decodebinary.m
%產生 [2^n 2^(n-1) ... 1] 的行向量,然後求和,將二進制轉化為十進制
function pop2=decodebinary(pop)
[px,py]=size(pop); %求pop行和列數
for i=1:py
pop1(:,i)=2.^(py-i).*pop(:,i);
end
pop2=sum(pop1,2); %求pop1的每行之和
% 2.2.2 將二進制編碼轉化為十進制數(2)
% decodechrom.m函數的功能是將染色體(或二進制編碼)轉換為十進制,參數spoint表示待解碼的二進制串的起始位置
% (對於多個變數而言,如有兩個變數,採用20為表示,每個變數10為,則第一個變數從1開始,另一個變數從11開始。本例為1),
% 參數1ength表示所截取的長度(本例為10)。
%遺傳演算法子程序
%Name: decodechrom.m
%將二進制編碼轉換成十進制
function pop2=decodechrom(pop,spoint,length)
pop1=pop(:,spoint:spoint+length-1);
pop2=decodebinary(pop1);
% 2.2.3 計算目標函數值
% calobjvalue.m函數的功能是實現目標函數的計算,其公式採用本文示例模擬,可根據不同優化問題予以修改。
%遺傳演算法子程序
%Name: calobjvalue.m
%實現目標函數的計算
function [objvalue]=calobjvalue(pop)
temp1=decodechrom(pop,1,10); %將pop每行轉化成十進制數
x=temp1*10/1023; %將二值域 中的數轉化為變數域 的數
objvalue=10*sin(5*x)+7*cos(4*x); %計算目標函數值
% 2.3 計算個體的適應值
%遺傳演算法子程序
%Name:calfitvalue.m
%計算個體的適應值
function fitvalue=calfitvalue(objvalue)
global Cmin;
Cmin=0;
[px,py]=size(objvalue);
for i=1:px
if objvalue(i)+Cmin>0
temp=Cmin+objvalue(i);
else
temp=0.0;
end
fitvalue(i)=temp;
end
fitvalue=fitvalue';
% 2.4 選擇復制
% 選擇或復制操作是決定哪些個體可以進入下一代。程序中採用賭輪盤選擇法選擇,這種方法較易實現。
% 根據方程 pi=fi/∑fi=fi/fsum ,選擇步驟:
% 1) 在第 t 代,由(1)式計算 fsum 和 pi
% 2) 產生 {0,1} 的隨機數 rand( .),求 s=rand( .)*fsum
% 3) 求 ∑fi≥s 中最小的 k ,則第 k 個個體被選中
% 4) 進行 N 次2)、3)操作,得到 N 個個體,成為第 t=t+1 代種群
%遺傳演算法子程序
%Name: selection.m
%選擇復制
function [newpop]=selection(pop,fitvalue)
totalfit=sum(fitvalue); %求適應值之和
fitvalue=fitvalue/totalfit; %單個個體被選擇的概率
fitvalue=cumsum(fitvalue); %如 fitvalue=[1 2 3 4],則 cumsum(fitvalue)=[1 3 6 10]
[px,py]=size(pop);
ms=sort(rand(px,1)); %從小到大排列
fitin=1;
newin=1;
while newin<=px
if(ms(newin))<fitvalue(fitin)
newpop(newin)=pop(fitin);
newin=newin+1;
else
fitin=fitin+1;
end
end
% 2.5 交叉
% 交叉(crossover),群體中的每個個體之間都以一定的概率 pc 交叉,即兩個個體從各自字元串的某一位置
% (一般是隨機確定)開始互相交換,這類似生物進化過程中的基因分裂與重組。例如,假設2個父代個體x1,x2為:
% x1=0100110
% x2=1010001
% 從每個個體的第3位開始交叉,交又後得到2個新的子代個體y1,y2分別為:
% y1=0100001
% y2=1010110
% 這樣2個子代個體就分別具有了2個父代個體的某些特徵。利用交又我們有可能由父代個體在子代組合成具有更高適合度的個體。
% 事實上交又是遺傳演算法區別於其它傳統優化方法的主要特點之一。
%遺傳演算法子程序
%Name: crossover.m
%交叉
function [newpop]=crossover(pop,pc)
[px,py]=size(pop);
newpop=ones(size(pop));
for i=1:2:px-1
if(rand<pc)
cpoint=round(rand*py);
newpop(i,:)=[pop(i,1:cpoint),pop(i+1,cpoint+1:py)];
newpop(i+1,:)=[pop(i+1,1:cpoint),pop(i,cpoint+1:py)];
else
newpop(i,:)=pop(i);
newpop(i+1,:)=pop(i+1);
end
end
% 2.6 變異
% 變異(mutation),基因的突變普遍存在於生物的進化過程中。變異是指父代中的每個個體的每一位都以概率 pm 翻轉,即由「1」變為「0」,
% 或由「0」變為「1」。遺傳演算法的變異特性可以使求解過程隨機地搜索到解可能存在的整個空間,因此可以在一定程度上求得全局最優解。
%遺傳演算法子程序
%Name: mutation.m
%變異
function [newpop]=mutation(pop,pm)
[px,py]=size(pop);
newpop=ones(size(pop));
for i=1:px
if(rand<pm)
mpoint=round(rand*py);
if mpoint<=0
mpoint=1;
end
newpop(i)=pop(i);
if any(newpop(i,mpoint))==0
newpop(i,mpoint)=1;
else
newpop(i,mpoint)=0;
end
else
newpop(i)=pop(i);
end
end
% 2.7 求出群體中最大得適應值及其個體
%遺傳演算法子程序
%Name: best.m
%求出群體中適應值最大的值
function [bestindivial,bestfit]=best(pop,fitvalue)
[px,py]=size(pop);
bestindivial=pop(1,:);
bestfit=fitvalue(1);
for i=2:px
if fitvalue(i)>bestfit
bestindivial=pop(i,:);
bestfit=fitvalue(i);
end
end
% 2.8 主程序
%遺傳演算法主程序
%Name:genmain05.m
clear
clf
popsize=20; %群體大小
chromlength=10; %字元串長度(個體長度)
pc=0.6; %交叉概率
pm=0.001; %變異概率
pop=initpop(popsize,chromlength); %隨機產生初始群體
for i=1:20 %20為迭代次數
[objvalue]=calobjvalue(pop); %計算目標函數
fitvalue=calfitvalue(objvalue); %計算群體中每個個體的適應度
[newpop]=selection(pop,fitvalue); %復制
[newpop]=crossover(pop,pc); %交叉
[newpop]=mutation(pop,pc); %變異
[bestindivial,bestfit]=best(pop,fitvalue); %求出群體中適應值最大的個體及其適應值
y(i)=max(bestfit);
n(i)=i;
pop5=bestindivial;
x(i)=decodechrom(pop5,1,chromlength)*10/1023;
pop=newpop;
end
fplot('10*sin(5*x)+7*cos(4*x)',[0 10])
hold on
plot(x,y,'r*')
hold off
[z index]=max(y); %計算最大值及其位置
x5=x(index)%計算最大值對應的x值
y=z
【問題】求f(x)=x 10*sin(5x) 7*cos(4x)的最大值,其中0<=x<=9
【分析】選擇二進制編碼,種群中的個體數目為10,二進制編碼長度為20,交叉概率為0.95,變異概率為0.08
【程序清單】
%編寫目標函數
function[sol,eval]=fitness(sol,options)
x=sol(1);
eval=x 10*sin(5*x) 7*cos(4*x);
%把上述函數存儲為fitness.m文件並放在工作目錄下
initPop=initializega(10,[0 9],'fitness');%生成初始種群,大小為10
[x endPop,bPop,trace]=ga([0 9],'fitness',[],initPop,[1e-6 1 1],'maxGenTerm',25,'normGeomSelect',...
[0.08],['arithXover'],[2],'nonUnifMutation',[2 25 3]) %25次遺傳迭代
運算借過為:x =
7.8562 24.8553(當x為7.8562時,f(x)取最大值24.8553)
註:遺傳演算法一般用來取得近似最優解,而不是最優解。
遺傳演算法實例2
【問題】在-5<=Xi<=5,i=1,2區間內,求解
f(x1,x2)=-20*exp(-0.2*sqrt(0.5*(x1.^2 x2.^2)))-exp(0.5*(cos(2*pi*x1) cos(2*pi*x2))) 22.71282的最小值。
【分析】種群大小10,最大代數1000,變異率0.1,交叉率0.3
【程序清單】
%源函數的matlab代碼
function [eval]=f(sol)
numv=size(sol,2);
x=sol(1:numv);
eval=-20*exp(-0.2*sqrt(sum(x.^2)/numv)))-exp(sum(cos(2*pi*x))/numv) 22.71282;
%適應度函數的matlab代碼
function [sol,eval]=fitness(sol,options)
numv=size(sol,2)-1;
x=sol(1:numv);
eval=f(x);
eval=-eval;
%遺傳演算法的matlab代碼
bounds=ones(2,1)*[-5 5];
[p,endPop,bestSols,trace]=ga(bounds,'fitness')
註:前兩個文件存儲為m文件並放在工作目錄下,運行結果為
p =
0.0000 -0.0000 0.0055
大家可以直接繪出f(x)的圖形來大概看看f(x)的最值是多少,也可是使用優化函數來驗證。matlab命令行執行命令:
fplot('x 10*sin(5*x) 7*cos(4*x)',[0,9])
evalops是傳遞給適應度函數的參數,opts是二進制編碼的精度,termops是選擇maxGenTerm結束函數時傳遞個maxGenTerm的參數,即遺傳代數。xoverops是傳遞給交叉函數的參數。mutops是傳遞給變異函數的參數。
【問題】求f(x)=x+10*sin(5x)+7*cos(4x)的最大值,其中0<=x<=9
【分析】選擇二進制編碼,種群中的個體數目為10,二進制編碼長度為20,交叉概率為0.95,變異概率為0.08
【程序清單】
%編寫目標函數
function[sol,eval]=fitness(sol,options)
x=sol(1);
eval=x+10*sin(5*x)+7*cos(4*x);
%把上述函數存儲為fitness.m文件並放在工作目錄下
initPop=initializega(10,[0 9],'fitness');%生成初始種群,大小為10
[x endPop,bPop,trace]=ga([0 9],'fitness',[],initPop,[1e-6 1 1],'maxGenTerm',25,'normGeomSelect',...
[0.08],['arithXover'],[2],'nonUnifMutation',[2 25 3]) %25次遺傳迭代
運算借過為:x =
7.8562 24.8553(當x為7.8562時,f(x)取最大值24.8553)
註:遺傳演算法一般用來取得近似最優解,而不是最優解。
遺傳演算法實例2
【問題】在-5<=Xi<=5,i=1,2區間內,求解
f(x1,x2)=-20*exp(-0.2*sqrt(0.5*(x1.^2+x2.^2)))-exp(0.5*(cos(2*pi*x1)+cos(2*pi*x2)))+22.71282的最小值。
【分析】種群大小10,最大代數1000,變異率0.1,交叉率0.3
【程序清單】
%源函數的matlab代碼
function [eval]=f(sol)
numv=size(sol,2);
x=sol(1:numv);
eval=-20*exp(-0.2*sqrt(sum(x.^2)/numv)))-exp(sum(cos(2*pi*x))/numv)+22.71282;
%適應度函數的matlab代碼
function [sol,eval]=fitness(sol,options)
numv=size(sol,2)-1;
x=sol(1:numv);
eval=f(x);
eval=-eval;
%遺傳演算法的matlab代碼
bounds=ones(2,1)*[-5 5];
[p,endPop,bestSols,trace]=ga(bounds,'fitness')
註:前兩個文件存儲為m文件並放在工作目錄下,運行結果為
p =
0.0000 -0.0000 0.0055
大家可以直接繪出f(x)的圖形來大概看看f(x)的最值是多少,也可是使用優化函數來驗證。matlab命令行執行命令:
fplot('x+10*sin(5*x)+7*cos(4*x)',[0,9])
evalops是傳遞給適應度函數的參數,opts是二進制編碼的精度,termops是選擇maxGenTerm結束函數時傳遞個maxGenTerm的參數,即遺傳代數。xoverops是傳遞給交叉函數的參數。mutops是傳遞給變異函數的參數。
打字不易,如滿意,望採納。
B. 遺傳演算法的運算過程
遺傳操作是模擬生物基因遺傳的做法。在遺傳演算法中,通過編碼組成初始群體後,遺傳操作的任務就是對群體的個體按照它們對環境適應度(適應度評估)施加一定的操作,從而實現優勝劣汰的進化過程。從優化搜索的角度而言,遺傳操作可使問題的解,一代又一代地優化,並逼近最優解。
遺傳操作包括以下三個基本遺傳運算元(genetic operator):選擇(selection);交叉(crossover);變異(mutation)。這三個遺傳運算元有如下特點:
個體遺傳運算元的操作都是在隨機擾動情況下進行的。因此,群體中個體向最優解遷移的規則是隨機的。需要強調的是,這種隨機化操作和傳統的隨機搜索方法是有區別的。遺傳操作進行的高效有向的搜索而不是如一般隨機搜索方法所進行的無向搜索。
遺傳操作的效果和上述三個遺傳運算元所取的操作概率,編碼方法,群體大小,初始群體以及適應度函數的設定密切相關。 從群體中選擇優勝的個體,淘汰劣質個體的操作叫選擇。選擇運算元有時又稱為再生運算元(reproction operator)。選擇的目的是把優化的個體(或解)直接遺傳到下一代或通過配對交叉產生新的個體再遺傳到下一代。選擇操作是建立在群體中個體的適應度評估基礎上的,目前常用的選擇運算元有以下幾種:適應度比例方法、隨機遍歷抽樣法、局部選擇法。
其中輪盤賭選擇法 (roulette wheel selection)是最簡單也是最常用的選擇方法。在該方法中,各個個體的選擇概率和其適應度值成比例。設群體大小為n,其中個體i的適應度為,則i 被選擇的概率,為遺傳演算法
顯然,概率反映了個體i的適應度在整個群體的個體適應度總和中所佔的比例。個體適應度越大。其被選擇的概率就越高、反之亦然。計算出群體中各個個體的選擇概率後,為了選擇交配個體,需要進行多輪選擇。每一輪產生一個[0,1]之間均勻隨機數,將該隨機數作為選擇指針來確定被選個體。個體被選後,可隨機地組成交配對,以供後面的交叉操作。 在自然界生物進化過程中起核心作用的是生物遺傳基因的重組(加上變異)。同樣,遺傳演算法中起核心作用的是遺傳操作的交叉運算元。所謂交叉是指把兩個父代個體的部分結構加以替換重組而生成新個體的操作。通過交叉,遺傳演算法的搜索能力得以飛躍提高。
交叉運算元根據交叉率將種群中的兩個個體隨機地交換某些基因,能夠產生新的基因組合,期望將有益基因組合在一起。根據編碼表示方法的不同,可以有以下的演算法:
a)實值重組(real valued recombination)
1)離散重組(discrete recombination)
2)中間重組(intermediate recombination)
3)線性重組(linear recombination)
4)擴展線性重組(extended linear recombination)。
b)二進制交叉(binary valued crossover)
1)單點交叉(single-point crossover)
2)多點交叉(multiple-point crossover)
3)均勻交叉(uniform crossover)
4)洗牌交叉(shuffle crossover)
5)縮小代理交叉(crossover with reced surrogate)。
最常用的交叉運算元為單點交叉(one-point crossover)。具體操作是:在個體串中隨機設定一個交叉點,實行交叉時,該點前或後的兩個個體的部分結構進行互換,並生成兩個新個體。下面給出了單點交叉的一個例子:
個體A:1 0 0 1 ↑1 1 1 → 1 0 0 1 0 0 0 新個體
個體B:0 0 1 1 ↑0 0 0 → 0 0 1 1 1 1 1 新個體 變異運算元的基本內容是對群體中的個體串的某些基因座上的基因值作變動。依據個體編碼表示方法的不同,可以有以下的演算法:
a)實值變異
b)二進制變異。
一般來說,變異運算元操作的基本步驟如下:
a)對群中所有個體以事先設定的變異概率判斷是否進行變異
b)對進行變異的個體隨機選擇變異位進行變異。
遺傳演算法引入變異的目的有兩個:一是使遺傳演算法具有局部的隨機搜索能力。當遺傳演算法通過交叉運算元已接近最優解鄰域時,利用變異運算元的這種局部隨機搜索能力可以加速向最優解收斂。顯然,此種情況下的變異概率應取較小值,否則接近最優解的積木塊會因變異而遭到破壞。二是使遺傳演算法可維持群體多樣性,以防止出現未成熟收斂現象。此時收斂概率應取較大值。
遺傳演算法中,交叉運算元因其全局搜索能力而作為主要運算元,變異運算元因其局部搜索能力而作為輔助運算元。遺傳演算法通過交叉和變異這對相互配合又相互競爭的操作而使其具備兼顧全局和局部的均衡搜索能力。所謂相互配合.是指當群體在進化中陷於搜索空間中某個超平面而僅靠交叉不能擺脫時,通過變異操作可有助於這種擺脫。所謂相互競爭,是指當通過交叉已形成所期望的積木塊時,變異操作有可能破壞這些積木塊。如何有效地配合使用交叉和變異操作,是目前遺傳演算法的一個重要研究內容。
基本變異運算元是指對群體中的個體碼串隨機挑選一個或多個基因座並對這些基因座的基因值做變動(以變異概率P.做變動),(0,1)二值碼串中的基本變異操作如下:
基因位下方標有*號的基因發生變異。
變異率的選取一般受種群大小、染色體長度等因素的影響,通常選取很小的值,一般取0.001-0.1。 當最優個體的適應度達到給定的閾值,或者最優個體的適應度和群體適應度不再上升時,或者迭代次數達到預設的代數時,演算法終止。預設的代數一般設置為100-500代。
C. 遺傳演算法的基本原理
遺傳演算法通常的實現方式,就是用程序來模擬生物種群進化的過程。對於一個求專最優解的問題,我屬們可以把一定數量的候選解(稱為個體)抽象地表示為染色體,使種群向更好的解來進化。大家知道,使用演算法解決問題的時候,解通常都是用數據或者字元串等表示的,而這個數據或字元串對應到生物中就是某個個體的「染色體」。進化從完全隨機個體的種群開始,之後一代一代發生。在每一代中評價其在整個種群的適應度,從當前種群中隨機地選擇多個個體(基於它們的適應度),通過自然選擇和突變產生新的種群,該種群在演算法的下一次迭代中成為當前種群。其具體的計算步驟如下:
編碼:將問題空間轉換為遺傳空間;
生成初始種群:隨機生成P個染色體;
種群適應度計算:按照確定的適應度函數,計算各個染色體的適應度;
選擇:根據染色體適應度,按照選擇運算元進行染色體的選擇;
交叉:按照交叉概率對被選擇的染色體進行交叉操作,形成下一代種群;
突變:按照突變概率對下一代種群中的個體進行突變操作;
返回第3步繼續迭代,直到滿足終止條件。
D. 用C語言編寫三個演算法,BFS或DFS,爬山演算法,遺傳演算法實現八皇後問題
網路演算法名,加上八皇後
比如
BFS 八皇後問題 C語言。
或者
遺傳演算法 八皇後問題 C語言
然後根據搜索結果 就可以得到演算法和代碼了。
E. 求遺傳演算法(GA)C語言代碼
.----來個例子,大家好理解..--
基於遺傳演算法的人工生命模擬
#include<stdio.h>
#include<stdlib.h>
#include<graphics.h>
#include<math.h>
#include<time.h>
#include<string.h>
#include "graph.c"
/* 宏定義 */
#define TL1 20 /* 植物性食物限制時間 */
#define TL2 5 /* 動物性食物限制時間 */
#define NEWFOODS 3 /* 植物性食物每代生成數目 */
#define MUTATION 0.05 /* 變異概率 */
#define G_LENGTH 32 /* 個體染色體長度 */
#define MAX_POP 100 /* 個體總數的最大值 */
#define MAX_FOOD 100 /* 食物總數的最大值 */
#define MAX_WX 60 /* 虛擬環境的長度最大值 */
#define MAX_WY 32 /* 虛擬環境的寬度最大值 */
#define SX1 330 /* 虛擬環境圖左上角點x坐標 */
#define SY1 40 /* 虛擬環境圖左上角點y坐標 */
#define GX 360 /* 個體數進化圖形窗口的左上角點X坐標 */
#define GY 257 /* 個體數進化圖形窗口的左上角點Y坐標 */
#define GXR 250 /* 個體數進化圖形窗口的長度 */
#define GYR 100 /* 個體數進化圖形窗口的寬度 */
#define GSTEP 2 /* 個體數進化圖形窗口的X方向步長 */
#define R_LIFE 0.05 /* 初期產生生物數的環境比率 */
#define R_FOOD 0.02 /* 初期產生食物數的環境比率 */
#define SL_MIN 10 /* 個體壽命最小值 */
/* 全局變數 */
unsigned char gene[MAX_POP][G_LENGTH]; /* 遺傳基因 */
unsigned char iflg[MAX_POP]; /* 個體死活狀態標志變數 */
F. 遺傳演算法的基本原理是什麼
遺傳演算法的基本原理和方法
一、編碼
編碼:把一個問題的可行解從其解空間轉換到遺傳演算法的搜索空間的轉換方法。
解碼(解碼):遺傳演算法解空間向問題空間的轉換。
二進制編碼的缺點是漢明懸崖(Hamming Cliff),就是在某些相鄰整數的二進制代碼之間有很大的漢明距離,使得遺傳演算法的交叉和突變都難以跨越。
格雷碼(Gray Code):在相鄰整數之間漢明距離都為1。
(較好)有意義的積木塊編碼規則:所定編碼應當易於生成與所求問題相關的短距和低階的積木塊;最小字元集編碼規則,所定編碼應採用最小字元集以使問題得到自然的表示或描述。
二進制編碼比十進制編碼搜索能力強,但不能保持群體穩定性。
動態參數編碼(Dynamic Paremeter Coding):為了得到很高的精度,讓遺傳演算法從很粗糙的精度開始收斂,當遺傳演算法找到一個區域後,就將搜索現在在這個區域,重新編碼,重新啟動,重復這一過程,直到達到要求的精度為止。
編碼方法:
1、 二進制編碼方法
缺點:存在著連續函數離散化時的映射誤差。不能直接反映出所求問題的本身結構特徵,不便於開發針對問題的專門知識的遺傳運算運算元,很難滿足積木塊編碼原則
2、 格雷碼編碼:連續的兩個整數所對應的編碼之間僅僅只有一個碼位是不同的,其餘碼位都相同。
3、 浮點數編碼方法:個體的每個基因值用某一范圍內的某個浮點數來表示,個體的編碼長度等於其決策變數的位數。
4、 各參數級聯編碼:對含有多個變數的個體進行編碼的方法。通常將各個參數分別以某種編碼方法進行編碼,然後再將他們的編碼按照一定順序連接在一起就組成了表示全部參數的個體編碼。
5、 多參數交叉編碼:將各個參數中起主要作用的碼位集中在一起,這樣它們就不易於被遺傳運算元破壞掉。
評估編碼的三個規范:完備性、健全性、非冗餘性。
二、選擇
遺傳演算法中的選擇操作就是用來確定如何從父代群體中按某種方法選取那些個體遺傳到下一代群體中的一種遺傳運算,用來確定重組或交叉個體,以及被選個體將產生多少個子代個體。
常用的選擇運算元:
1、 輪盤賭選擇(Roulette Wheel Selection):是一種回放式隨機采樣方法。每個個體進入下一代的概率等於它的適應度值與整個種群中個體適應度值和的比例。選擇誤差較大。
2、 隨機競爭選擇(Stochastic Tournament):每次按輪盤賭選擇一對個體,然後讓這兩個個體進行競爭,適應度高的被選中,如此反復,直到選滿為止。
3、 最佳保留選擇:首先按輪盤賭選擇方法執行遺傳演算法的選擇操作,然後將當前群體中適應度最高的個體結構完整地復制到下一代群體中。
4、 無回放隨機選擇(也叫期望值選擇Excepted Value Selection):根據每個個體在下一代群體中的生存期望來進行隨機選擇運算。方法如下
(1) 計算群體中每個個體在下一代群體中的生存期望數目N。
(2) 若某一個體被選中參與交叉運算,則它在下一代中的生存期望數目減去0.5,若某一個體未被選中參與交叉運算,則它在下一代中的生存期望數目減去1.0。
(3) 隨著選擇過程的進行,若某一個體的生存期望數目小於0時,則該個體就不再有機會被選中。
5、 確定式選擇:按照一種確定的方式來進行選擇操作。具體操作過程如下:
(1) 計算群體中各個個體在下一代群體中的期望生存數目N。
(2) 用N的整數部分確定各個對應個體在下一代群體中的生存數目。
(3) 用N的小數部分對個體進行降序排列,順序取前M個個體加入到下一代群體中。至此可完全確定出下一代群體中M個個體。
6、無回放余數隨機選擇:可確保適應度比平均適應度大的一些個體能夠被遺傳到下一代群體中,因而選擇誤差比較小。
7、均勻排序:對群體中的所有個體按期適應度大小進行排序,基於這個排序來分配各個個體被選中的概率。
8、最佳保存策略:當前群體中適應度最高的個體不參與交叉運算和變異運算,而是用它來代替掉本代群體中經過交叉、變異等操作後所產生的適應度最低的個體。
9、隨機聯賽選擇:每次選取幾個個體中適應度最高的一個個體遺傳到下一代群體中。
10、排擠選擇:新生成的子代將代替或排擠相似的舊父代個體,提高群體的多樣性。
三、交叉
遺傳演算法的交叉操作,是指對兩個相互配對的染色體按某種方式相互交換其部分基因,從而形成兩個新的個體。
適用於二進制編碼個體或浮點數編碼個體的交叉運算元:
1、單點交叉(One-pointCrossover):指在個體編碼串中只隨機設置一個交叉點,然後再該點相互交換兩個配對個體的部分染色體。
2、兩點交叉與多點交叉:
(1) 兩點交叉(Two-pointCrossover):在個體編碼串中隨機設置了兩個交叉點,然後再進行部分基因交換。
(2) 多點交叉(Multi-pointCrossover)
3、均勻交叉(也稱一致交叉,UniformCrossover):兩個配對個體的每個基因座上的基因都以相同的交叉概率進行交換,從而形成兩個新個體。
4、算術交叉(ArithmeticCrossover):由兩個個體的線性組合而產生出兩個新的個體。該操作對象一般是由浮點數編碼表示的個體。
四、變異
遺傳演算法中的變異運算,是指將個體染色體編碼串中的某些基因座上的基因值用該基因座上的其它等位基因來替換,從而形成以給新的個體。
以下變異運算元適用於二進制編碼和浮點數編碼的個體:
1、基本位變異(SimpleMutation):對個體編碼串中以變異概率、隨機指定的某一位或某幾位僅因座上的值做變異運算。
2、均勻變異(UniformMutation):分別用符合某一范圍內均勻分布的隨機數,以某一較小的概率來替換個體編碼串中各個基因座上的原有基因值。(特別適用於在演算法的初級運行階段)
3、邊界變異(BoundaryMutation):隨機的取基因座上的兩個對應邊界基因值之一去替代原有基因值。特別適用於最優點位於或接近於可行解的邊界時的一類問題。
4、非均勻變異:對原有的基因值做一隨機擾動,以擾動後的結果作為變異後的新基因值。對每個基因座都以相同的概率進行變異運算之後,相當於整個解向量在解空間中作了一次輕微的變動。
5、高斯近似變異:進行變異操作時用符號均值為P的平均值,方差為P2的正態分布的一個隨機數來替換原有的基因值。
G. 八皇後問題的遺傳演算法解法,c語言編寫
||#include <stdlib.h>
#include<math.h>
#include<conio.h>
#include<stdio.h>
int N=0;
int a[10][10];
int yp=1;
FILE * fp;
void main()
{
int *pa;
int m,n,f,aa;
int check(),reback();
int prt();
clrscr();
fp=fopen("data.dat","w");
printf("please input the number of queens(4--10):");
scanf("%d",&N);
for(m=0;m<N;m++)
for(n=0;n<N;n++)
a[m][n]=0;
m=0;n=0;aa=0;
do{for(n=0;n<N;n++)
{
f=check(m,n);
if(m==N-1 && f==1){a[m][n]=1; prt();f=0;a[m][n]=0;}
if(f==1){ a[m][n]=1; break;}
if(n==N-1&&f==0)
{
do{
m--;
n=reback(m);
if(m==0 && n==N-1 && aa==1) break;
}while(n>=N-1);
}
}
aa=1;
m++;
if(m>=N)m=0;
}while(m<N &&n<N);
printf("\n\n********IT'S OVER!!********");
fprintf(fp,"\n\n**********IT'S OVER!!*******");
close(fp);
getch();
}
int check(int x1,int y1)
{int a1,b1;
for(a1=0;a1<x1;a1++){
for(b1=0;b1<N;b1++){
if(a[a1][b1]==1){
if(a1==x1||b1==y1) return(0);
if((a1-b1)==(x1-y1)) return(0);
if((a1+b1)==(x1+y1))return(0);
}
}
}
return(1);
}
int reback(int w)
{
int x;
for(x=0;x<N;x++)
if(a[w][x]==1)
{
a[w][x]=0;
return(x);
}
}
int prt()
{int t,y;
clrscr();
printf("\n************ %d **************\n\n",yp);
fprintf(fp,"\n************ %d **************\n\n",yp);
yp++;
for(t=0;t<N;t++){
for(y=0;y<N;y++){
printf("%3d",a[t][y]);
fprintf(fp,"%3d",a[t][y]);
}
printf("\n");
fprintf(fp,"\n");
}
getch();
return(0);
}