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

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

Похожие темы