Этот пример показывает использование пользовательской выходной функции в решателе генетического алгоритма ga
. Пользовательская выходная функция выполняет следующие задачи:
Постройте область значений первых двух компонентов генеральной совокупности как прямоугольник. Левые и более низкие стороны прямоугольника в минимумах x(1)
и x(2)
соответственно, и правильные и верхние стороны в соответствующих максимумах.
Остановите итерации, когда лучшее значение функции опускается ниже 0.1
(минимальным значением целевой функции является 0
).
Запишите целую генеральную совокупность в переменной под названием gapopulationhistory
в вашей рабочей области MATLAB® каждые 10 поколений.
Измените начальную перекрестную часть к пользовательскому значению 0.2
, и затем обновите его назад к 0.8
по умолчанию после 25 поколений. Начальная установка 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(10)
Установите целевую функцию и вызовите решатель.
fun = @gaintobj; [x,fval] = ga(fun,nvar,[],[],[],[],lb,ub,[],IntCon,options)
Got below 0.1 Optimization terminated: y; x = 6.0000 13.0000 9.4217 15.7016 fval = 0.0098
Выходная функция остановила решатель.
Просмотрите размер записанной истории.
disp(size(gapopulationhistory))
40 4 7
Существует семь записей 40 4 матрица генеральной совокупности (40 человек, каждый вектор - строка с 4 элементами).