Пользовательская выходная функция для генетического алгоритма

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

Setup задач и решение

Установите нижние и верхние границы.

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)
Got below 0.1
Optimization terminated: y

x =

    6.0000   13.0000    9.4201   15.7052


fval =

    0.0059

Выходная функция остановила решатель.

Просмотрите размер записанной истории.

disp(size(gapopulationhistory))
    40     4     6

Существует шесть записей 40 4 матрица населения (40 индивидуумов, каждый вектор-строка с 4 элементами).

Похожие темы