一、案例引入
求
二、使用MATLAB事先探測出該函數的最大值的大概位置
PS:使用MATLAB繪圖窗口中的“工具->數據遊標”即可手動探測出函數最大值所在的大致座標.
繪圖代碼:
%detect.m
x = -2:0.001:2;
y = 200*exp(-0.05*x).*sin(x);
plot(x,y)
grid on;
三、源代碼
目標函數
(注:對於優化問題中的最大值或極大值問題,可以直接將目標函數當作適應度函數)
%targetFun.m
function y = targetFun(x);
y = 200*exp(-0.05*x).*sin(x);
將一個二進制串轉換爲十進制數
%transform2To10.m
function y = transform2To10(x);
bitLength = size(x, 2);
y = x(bitLength);
for i = 1:bitLength-1
y = y + x(bitLength-i)*power(2, i);
end
計算種羣中每個個體的染色體的適應度,結果存放在fitValue中;
計算種羣中每個個體的染色體被複制的累積概率,結果存放在cumsumP中
%fitnessFun.m
function [fitValue, cumsumP] = fitnessFun(population);
global bitLength;
global boundsBegin;
global boundsEnd;
popSize = size(population, 1); %種羣中個體的個數
for i = 1:popSize
x = transform2To10(population(i,:));
xx = boundsBegin + x * (boundsEnd - boundsBegin)/(power(2,bitLength)-1);
fitValue(i) = targetFun(xx);
end
fitValue = fitValue' + 230;
fSum = sum(fitValue);
pPerPop = fitValue/fSum;
cumsumP(1) = pPerPop(1);
for i = 2:popSize
cumsumP(i) = cumsumP(i-1) + pPerPop(i);
end
進行選擇操作(從原種羣中選擇出兩個個體的染色體),以便得到新種羣
%selectTwo.m
function selTwo = selectTwo(population, cumsumP);
for i=1:2
r = rand;
prand = cumsumP - r;
j = 1;
while prand(j)<0
j = j + 1;
end
selTwo(i) = j;
end
決定在遺傳運算中是否需要進行交叉或變異過程
%ifCroIfMut.m
function p = ifCroIfMut(croOrMut);
test(1:100) = 0;
l = round(100*croOrMut);
test(1:l) = 1;
n = round(rand*99)+1;
p = test(n);
根據選擇出的兩個個體(這兩個個體在新種羣中)的染色體以及交叉概率進行交叉過程的到兩個子代染色體
%crossoverTwo.m
function cTwo = crossoverTwo(population, selTwo, pC);
bitLength = size(population, 2);
p = ifCroIfMut(pC);
if p == 1
choice = round(rand*(bitLength-2))+1;
cTwo(1,:) = [population(selTwo(1),1:choice) population(selTwo(2), choice+1:bitLength)];
cTwo(2,:) = [population(selTwo(2),1:choice) population(selTwo(1), choice+1:bitLength)];
else
cTwo(1,:) = population(selTwo(1),:);
cTwo(2,:) = population(selTwo(2),:);
end
根據選擇出的一個個體(這個個體在新種羣中)的染色體以及變異概率進行變異過程
%mutateOne.m
function new = mutateOne(old, pM);
bitLength = size(old,2);
new = old;
p = ifCroIfMut(pM);
if p == 1
choice = round(rand*(bitLength-1)) + 1;
new(choice) = abs(old(choice)-1);
end
主體求解代碼:
%GA.m
global bitLength;
global boundsBegin;
global boundsEnd;
bounds = [-2 2];
precision = 0.0001;
boundsBegin = bounds(:,1);
boundsEnd = bounds(:, 2);
bitLength = ceil(log2((boundsEnd - boundsBegin)'/precision));
popSize = 50;
generationN = 12;
pCrossover = 0.90;
pMutation = 0.09;
population = round(rand(popSize, bitLength));
[fitValue, cumsumP] = fitnessFun(population);
generation = 1;
while generation < generationN + 1
for j = 1:2:popSize
%選擇兩個個體
selTwo = selectTwo(population, cumsumP);
%交叉兩個個體
cTwo = crossoverTwo(population, selTwo, pCrossover);
cNew(j,:) = cTwo(1,:);
cNew(j+1,:) = cTwo(2,:);
%變異兩個個體
mNew(j,:) = mutateOne(cNew(j,:), pMutation);
mNew(j+1,:) = mutateOne(cNew(j+1,:), pMutation);
end
population = mNew;
[fitValue, cumsumP] = fitnessFun(population);
[fMax, nMax] = max(fitValue); %nMax爲fitValue中所有元素的最大值fMax在向量fitValue中的索引
fMean = mean(fitValue); %求得fitValue中所有元素的平均值
yMax(generation) = fMax;
yMean(generation) = fMean;
x = transform2To10(population(nMax,:));
xx = boundsBegin + x * (boundsEnd - boundsBegin)/(power(2,bitLength)-1);
xMax(generation) = xx;
generation = generation + 1;
end
generation = generation - 1;
bestPopulation = xx;
bestTargetFunValue = targetFun(xx);
figure(1);
hand1 = plot(1:generation, yMax);
set(hand1,'linestyle', '-','linewidth', 1.8,'marker', '*', 'markersize', 6);
hold on;
hand2 = plot(1:generation, yMean);
set(hand2,'color', 'r','linestyle', '-','linewidth', 1.8,'marker', 'h', 'markersize', 6);
xlabel('進化代數'); ylabel('最大/平均適應度'); xlim([1 generationN]);
legend('最大適應度', '平均適應度');
box off; hold off;
四、求解結果