遺傳算法(Genetic Algorithm)是常用的智能算法的一種,遺傳算法GA(Genetic Algorithm)入門知識梳理 對GA進行了詳盡的基本介紹,其結尾附的七個鏈接也讓人很有啓發。本文附上自己對遺傳算法的學習理解與代碼實現。
//挖坑
根據遺傳算法基礎知識,寫出僞代碼如下:
Initialization();
while less than maximum iterations
Crossover(parent, pCross) -> childrenCross
Mutation(parent, pMutation) -> childrenMutate
[childrenCross; cihldrenMutate] -> children
Calculate the fitness of children
select(children) -> parent
if Satisfy terminal condition
break
end
end
整體思路可以說是比較簡單,生成種羣->交叉、變異->遺傳(自然選擇)->下一代。生成種羣需要一定的編碼技巧(挖坑,以後填)。
下面給出具體MATLAB代碼實現:
%%
%編碼方式: 基本二進制編碼
%Input: FitFunc: Any function
% pCrossover: probability of crossover, default 0.5
% pMutation: probability of mutation, default 0.04
% GroupNum: number of individuals of the virtual group, default 30
% MaxIter: maximum iterations
% MaxRepeat: (optional)determine the convergence standard 判斷收斂
%parent.fitness
%parent.chrom
function Result = MyGA(FitFunc, pCrossover, pMutation, GroupNum, MaxIter, MaxRepeat)
%Default parameters
if nargin < 6
MaxRepeat = 10;
if nargin < 5
MaxIter = 1000;
if nargin < 4
GroupNum = 50;
if nargin < 3
pMutation = 0.04;
if nargin < 2
pCrossover = 0.5;
end
end
end
end
end
Result = [];
epsilon = 1e-5;
iter = 0;
iRepeat = 1;
bit = 22;
thisMax = 0;
parent = InitGroup(GroupNum, FitFunc, bit); %Generate initial population
while iter < MaxIter
children1 = Crossover(parent, pCrossover/iter^0.1); %Return crossovered chromes
children.chrom = [];
children.fitness = [];
children.chrom = Mutation([parent.chrom; children1], pMutation/iter^0.1);
children.fitness = CalcFit(children.chrom, FitFunc, bit);
children = select(children, GroupNum);
parent = children;
iter = iter + 1;
%parent.chrom;
%[m, I] = max(parent.fitness)
if (thisMax-max(parent.fitness))/max(parent.fitness) < epsilon
iRepeat = iRepeat + 1;
else
iRepeat = 1;
end
thisMax = max(parent.fitness);
disp(thisMax)
Result = [Result; thisMax];
end
end
%Encoding method: 普通二進制編碼
function parent = InitGroup(GroupNum, FitFunc, bit)
parent.fitness = [];
parent.chrom = [];
for i = 1:GroupNum
item = dec2bin(fix(rand*2^bit));
while size(item, 2) < bit
item = ['0', item];
end
parent.chrom = [parent.chrom; item];
end
parent.fitness = CalcFit(parent.chrom, FitFunc, bit);
end
%User Define 自定義解碼方式
function Decode = Decoding(Population, bit)
Decode = bin2dec(Population) * 2 / (2^bit)+1;
end
%Calculate Fitness
function Fitness = CalcFit(Population, Fun, bit)
DecodedPop = Decoding(Population, bit);
Fitness = Fun(DecodedPop);
end
%roulette selcting method
function newPop = select(parent, PopNum)
%Add: The best survive?
cumFit = cumsum(parent.fitness)/sum(parent.fitness);
%[M, I] = max(parent.fitness);
%newPop.chrom(1,:) = parent.chrom(I, :);
%newPop.fitness = parent.fitness(I);
for i = 1 : PopNum
index = find (cumFit - rand > 0);
newPop.chrom(i,:) = parent.chrom(index(1),:);
newPop.fitness(i) = parent.fitness(index(1));
end
end
function childrenChrom = Crossover(parent, pCrossover)
[PopNum, bit] = size(parent.chrom);
childrenChrom = [];
%[M, I] = max(parent.fitness);
%childrenChrom = parent.chrom(I, :); %Parent with highest fitness
for i = 1 : PopNum/2
RandCross = rand(1);
if RandCross < pCrossover
i = fix(rand(1)*PopNum + 1);
j = fix(rand(1)*PopNum + 1);
while i == j
i = fix(rand(1)*PopNum + 1);
j = fix(rand(1)*PopNum + 1);
end
BreakPoint = fix(rand(1)*bit + 1);
temp = parent.chrom(i, 1:BreakPoint);
parent.chrom(i, 1:BreakPoint) = parent.chrom(j, 1:BreakPoint);
parent.chrom(j, 1:BreakPoint) = temp;
childrenChrom = [childrenChrom; parent.chrom(i, :); parent.chrom(j, :)];
end
end
end
function childrenChrom = Mutation(chrom, pMutation)
[PopNum, bit] = size(chrom);
childrenChrom = chrom;
for i = 1:PopNum
for j = 1:bit
if rand < pMutation
childrenChrom(i, j) = '1'-childrenChrom(i, j)+'0';
end
end
end
end
解幾個簡單的例子
簡單一元函數
在
此函數在指定區間上只有一個最大值,用遺傳算法可以很容易地得到結果。
MyGA(@myFun)
其中myFun爲上文所述的函數,即爲遺傳算法中的適應度函數。
MyGA(@myFun);
1.8185
1.8123
1.8184
1.8193
1.8193
1.8193
1.8193
1.8195
1.8196
1.8196
1.8196
1.8196
1.8196
1.8196
1.8194
1.8196
1.8196
1.8196
1.8197
1.8196
1.8196
1.8196
1.8197
1.8197
iter =
25
隨機選擇一組輸出如上所示。其中定義算法收斂的相對誤差限epsilon爲