Benutzerdefinierte Ausgabefunktion für genetischen Algorithmus
Dieses Beispiel zeigt die Verwendung einer benutzerdefinierten Ausgabefunktion im genetischen Algorithmus-Solver ga. Die benutzerdefinierte Ausgabefunktion führt die folgenden Aufgaben aus:
Zeichnen Sie den Bereich der ersten beiden Komponenten der Population als Rechteck auf. Die linke und untere Seite des Rechtecks befinden sich jeweils an den Minima von
x(1)undx(2), und die rechte und obere Seite befinden sich an den jeweiligen Maxima.Halten Sie die Iterationen an, wenn der beste Funktionswert unter
0.1fällt (der Mindestwert der Zielfunktion ist0).Zeichnen Sie alle 10 Generationen die gesamte Population in einer Variablen namens
gapopulationhistoryin Ihrem MATLAB ®-Arbeitsbereich auf.Ändern Sie den anfänglichen Crossover-Anteil in den benutzerdefinierten Wert
0.2und aktualisieren Sie ihn nach 25 Generationen wieder auf den Standardwert0.8. Die anfängliche Einstellung von0.2bewirkt, dass bei den ersten Iterationen hauptsächlich zufällige Suchen durch Mutation durchgeführt werden. Die spätere Einstellung von0.8bewirkt, dass bei den folgenden Iterationen primär über Kombinationen vorhandener Populationsmitglieder gesucht wird.
Zielfunktion
Die Zielfunktion ist für vierdimensionales x, dessen erste beiden Komponenten ganzzahlig sind.
function f = gaintobj(x)
f = rastriginsfcn([x(1)-6 x(2)-13]);
f = f + rastriginsfcn([x(3)-3*pi x(4)-5*pi]);
Ausgabefunktion
Die benutzerdefinierte Ausgabefunktion richtet das Diagramm während der Initialisierung ein und verwaltet das Diagramm während der Iterationen. Die Ausgabefunktion pausiert auch die Iterationen für 0.1s, sodass Sie die Entwicklung des Diagramms verfolgen können.
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
Problemaufbau und -lösung
Legen Sie die Unter- und Obergrenzen fest.
lb = [1 1 -30 -30]; ub = [20 20 70 70];
Legen Sie die Ganzzahlvariablen und die Anzahl der Variablen fest.
intcon = [1 2]; nvar = 4;
Legen Sie Optionen fest, um die benutzerdefinierte Ausgabefunktion aufzurufen und zunächst nur wenig Überschneidungen zu haben.
options = optimoptions('ga','OutputFcn',@gaoutfun,'CrossoverFraction',0.2);
Stellen Sie zur Reproduzierbarkeit den Zufallszahlengenerator ein.
rng default
Legen Sie die Zielfunktion fest und rufen Sie den Solver auf.
fun = @gaintobj; [x,fval] = ga(fun,nvar,[],[],[],[],lb,ub,[],intcon,options)
Got below 0.1
ga stopped by the output or plot function. The reason for stopping:
y
x =
6.0000 13.0000 9.4201 15.7052
fval =
0.0059

Die Ausgabefunktion hat den Solver angehalten.
Zeigen Sie die Größe des aufgezeichneten Verlaufs an.
disp(size(gapopulationhistory))
40 4 6
Es gibt sechs Datensätze der 40 x 4-Populationsmatrix (40 Individuen, jeweils ein 4-Element-Zeilenvektor).