Этот пример показывает использование пользовательской выходной функции в решателе генетического алгоритма 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-элементный вектор-строка).