遗传算法的自定义输出函数
此示例展示了遗传算法求解器 ga
中自定义输出函数的使用。自定义输出函数执行以下任务:
将种群前两个分量的范围绘制为一个矩形。矩形的左边和下边分别位于
x(1)
和x(2)
的极小值,右边和上边分别位于各自的极大值。当最佳函数值降至
0.1
以下(目标函数的最小值为0
)时停止迭代。每 10 代将整个种群记录在 MATLAB® 工作区中名为
gapopulationhistory
的变量中。将初始交叉分数修改为自定义值
0.2
,然后在 25 代之后将其更新回默认的0.8
。0.2
的初始设置导致前几次迭代主要通过变异进行随机搜索。0.8
的后续设置导致接下来的迭代主要通过现有种群成员的组合进行搜索。
目标函数
目标函数针对四维 x
,其前两个分量为整数值。
function f = gaintobj(x)
f = rastriginsfcn([x(1)-6 x(2)-13]);
f = f + rastriginsfcn([x(3)-3*pi x(4)-5*pi]);
输出函数
自定义输出函数在初始化期间设置图,并在迭代期间维护图。输出函数还会暂停 0.1s
的迭代,以便您可以看到情节的发展。
function [state,options,optchanged] = gaoutfun(options,state,flag) persistent h1 history r optchanged = false; switch flag case 'init' h1 = figure; ax = gca; ax.XLim = [0 21]; ax.YLim = [0 21]; l1 = min(state.Population(:,1)); m1 = max(state.Population(:,1)); l2 = min(state.Population(:,2)); m2 = max(state.Population(:,2)); r = rectangle(ax,'Position',[l1 l2 m1-l1 m2-l2]); history(:,:,1) = state.Population; assignin('base','gapopulationhistory',history); case 'iter' % Update the history every 10 generations. if rem(state.Generation,10) == 0 ss = size(history,3); history(:,:,ss+1) = state.Population; assignin('base','gapopulationhistory',history); end % Find the best objective function, and stop if it is low. ibest = state.Best(end); ibest = find(state.Score == ibest,1,'last'); bestx = state.Population(ibest,:); bestf = gaintobj(bestx); if bestf <= 0.1 state.StopFlag = 'y'; disp('Got below 0.1') end % Update the plot. figure(h1) l1 = min(state.Population(:,1)); m1 = max(state.Population(:,1)); l2 = min(state.Population(:,2)); m2 = max(state.Population(:,2)); r.Position = [l1 l2 m1-l1 m2-l2]; pause(0.1) % Update the fraction of mutation and crossover after 25 generations. if state.Generation == 25 options.CrossoverFraction = 0.8; optchanged = true; end case 'done' % Include the final population in the history. ss = size(history,3); history(:,:,ss+1) = state.Population; assignin('base','gapopulationhistory',history); end
问题设置和解
设定下界和上界。
lb = [1 1 -30 -30]; ub = [20 20 70 70];
设置整数变量和变量的数量。
intcon = [1 2]; nvar = 4;
设置选项来调用自定义输出函数,并且最初几乎没有交叉。
options = optimoptions('ga','OutputFcn',@gaoutfun,'CrossoverFraction',0.2);
为了实现可再现性,请设置随机数生成器。
rng default
设置目标函数并调用求解器。
fun = @gaintobj; [x,fval] = ga(fun,nvar,[],[],[],[],lb,ub,[],intcon,options)
ga stopped because the average change in the penalty function value is less than options.FunctionTolerance and the constraint violation is less than options.ConstraintTolerance. x = 6.0000 13.0000 9.4248 14.7130 fval = 0.9950
输出函数暂停了求解器。
查看历史记录的大小。
disp(size(gapopulationhistory))
40 4 13
40×4 的种群矩阵有 6 条记录(40 个个体,每个个体是一个 4 元素行向量)。