《遗传算法(GA)的MATLAB实现》

一、案例引入

f(x)=200e0.05xsinx,x[2,2] 的最大值




二、使用MATLAB事先探测出该函数的最大值的大概位置

PS:使用MATLAB绘图窗口中的“工具->数据游标”即可手动探测出函数最大值所在的大致坐标.

绘图代码:

%detect.m

x = -2:0.001:2;
y = 200*exp(-0.05*x).*sin(x);
plot(x,y)
grid on;



preGA




三、源代码

目标函数

(注:对于优化问题中的最大值或极大值问题,可以直接将目标函数当作适应度函数)

%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;



四、求解结果



GA

猜你喜欢

转载自blog.csdn.net/wuchangi/article/details/79170239