Efectos de las opciones de algoritmos genéticos
Este ejemplo muestra los efectos de algunas opciones para la función del algoritmo genético ga
. Puede crear y cambiar opciones utilizando la función optimoptions
.
Establezca un problema para ga
ga
busca el mínimo de una función utilizando el algoritmo genético. Para este ejemplo, utilice ga
para minimizar la función de aptitud shufcn
, una función de valor real de dos variables.
Grafique shufcn
sobre el rango = [-2 2;-2 2]
llamando a plotobjective
, que se incluye cuando ejecuta este ejemplo.
plotobjective(@shufcn,[-2 2; -2 2]);
Para utilizar el solucionador ga
, proporcione al menos dos argumentos de entrada: una función de aptitud y el número de variables en el problema. Los dos primeros argumentos de salida devueltos por ga
son x
, el mejor punto encontrado, y Fval
, el valor de la función en el mejor punto. Un tercer argumento de salida, exitFlag
, indica por qué ga
se detuvo. ga
también puede devolver un cuarto argumento, Output
, que contiene información sobre el rendimiento del solucionador.
FitnessFunction = @shufcn; numberOfVariables = 2;
Ejecute el solucionador ga
.
rng default % For reproducibility [x,Fval,exitFlag,Output] = ga(FitnessFunction,numberOfVariables);
ga stopped because the average change in the fitness value is less than options.FunctionTolerance.
fprintf('The number of generations is: %d\n', Output.generations);
The number of generations is: 124
fprintf('The number of function evaluations is: %d\n', Output.funccount);
The number of function evaluations is: 5881
fprintf('The best function value found is: %g\n', Fval);
The best function value found is: -186.199
Si ejecuta este ejemplo sin el comando rng default
, los resultados pueden diferir, porque ga
es un algoritmo estocástico.
Cómo funciona el algoritmo genético
El algoritmo genético funciona sobre una población utilizando un conjunto de operadores que se aplican a la población. Una población es un conjunto de puntos en el espacio de diseño. La población inicial se genera aleatoriamente de forma predeterminada. El algoritmo calcula la próxima generación de la población utilizando la aptitud de los individuos de la generación actual. Para obtener más detalles, consulte Cómo funciona el algoritmo genético.
Agregar visualización
Para visualizar el rendimiento del solucionador mientras se ejecuta, configure una opción 'PlotFcn'
usando optimoptions
. En este caso, seleccione dos funciones de gráfico en un arreglo de celdas. Conjunto gaplotbestf
, que representa gráficamente la puntuación media y la mejor puntuación de la población en cada generación. Configure también gaplotstopping
, que representa el porcentaje de criterios de detención satisfechos.
opts = optimoptions(@ga,'PlotFcn',{@gaplotbestf,@gaplotstopping});
Ejecute el solucionador ga
, incluido el argumento opts
.
[x,Fval,exitFlag,Output] = ...
ga(FitnessFunction,numberOfVariables,[],[],[],[],[],[],[],opts);
ga stopped because the average change in the fitness value is less than options.FunctionTolerance.
Especificar opciones de población
Las opciones de población pueden tener un gran efecto en el rendimiento del solucionador. La velocidad de cada iteración depende del tamaño de la población: una población más grande conduce a iteraciones más lentas. Por el contrario, una población más grande lleva a ga
a explorar más a fondo, por lo que puede conducir a una mejor solución. De manera similar, un rango inicial más amplio puede llevar a una exploración más exhaustiva, pero puede requerir una población más grande para explorar el rango más amplio con una minuciosidad similar.
Especificar el tamaño de la población
ga
crea una población inicial predeterminada utilizando un generador de números aleatorios uniforme. El tamaño de población predeterminado utilizado por ga
es 50 cuando el número de variables de decisión es menor que 5, y 200 en caso contrario. El tamaño predeterminado podría no funcionar bien para algunos problemas; por ejemplo, un tamaño de población más pequeño puede ser suficiente para problemas más pequeños. Dado que el problema actual solo tiene dos variables, especifique un tamaño de población de 10. Establezca el valor de la opción PopulationSize
en 10 en las opciones existentes, opts
.
opts.PopulationSize = 10;
Especificar rango de población inicial
El método predeterminado para generar una población inicial utiliza un generador de números aleatorios uniforme. Para problemas sin restricciones de números enteros, ga
crea una población inicial donde todos los puntos están en el rango de –10 a 10. Por ejemplo, puede generar una población de tamaño tres en el rango predeterminado utilizando este comando:
Population = [-10,-10] + 20*rand(3,2);
Puede establecer el rango inicial cambiando la opción InitialPopulationRange
. El rango debe ser una matriz con dos filas. Si el rango tiene solo una columna, es decir, es de 2 por 1, entonces el rango de cada variable es el rango dado. Por ejemplo, si establece el rango en [-1; 1]
, entonces el rango inicial para ambas variables es –1 a 1. Para especificar un rango inicial diferente para cada variable, debe especificar el rango como una matriz con dos filas y columnas numberOfVariables
. Por ejemplo, si establece el rango en [-1 0; 1 2]
, entonces la primera variable tiene el rango de –1 a 1, y la segunda variable tiene el rango de 0 a 2 (cada columna corresponde a una variable).
Modificar el valor de la opción InitialPopulationRange
en las opciones existentes, opts
.
opts.InitialPopulationRange = [-1 0; 1 2];
Ejecute el solucionador ga
.
[x,Fval,exitFlag,Output] = ga(FitnessFunction,numberOfVariables,[],[],[], ...
[],[],[],[],opts);
ga stopped because the average change in the fitness value is less than options.FunctionTolerance.
fprintf('The number of generations is: %d\n', Output.generations);
The number of generations is: 67
fprintf('The number of function evaluations is: %d\n', Output.funccount);
The number of function evaluations is: 614
fprintf('The best function value found is: %g\n', Fval);
The best function value found is: -179.987
Reproducir resultados
De forma predeterminada, ga
comienza con una población inicial aleatoria creada utilizando generadores de números aleatorios MATLAB®. El solucionador produce la siguiente generación utilizando operadores ga
que también utilizan estos mismos generadores de números aleatorios. Cada vez que se genera un número aleatorio, el estado de los generadores de números aleatorios cambia. Por lo tanto, incluso si no cambia ninguna opción, puede obtener resultados diferentes cuando vuelva a ejecutar el solucionador.
Ejecute el solucionador dos veces para mostrar este fenómeno.
Ejecute el solucionador ga
.
[x,Fval,exitFlag,Output] = ga(FitnessFunction,numberOfVariables);
ga stopped because the average change in the fitness value is less than options.FunctionTolerance.
fprintf('The best function value found is: %g\n', Fval);
The best function value found is: -186.484
Ejecute ga
nuevamente.
[x,Fval,exitFlag,Output] = ga(FitnessFunction,numberOfVariables);
ga stopped because the average change in the fitness value is less than options.FunctionTolerance.
fprintf('The best function value found is: %g\n', Fval);
The best function value found is: -185.867
ga
da resultados diferentes en las dos ejecuciones porque el estado del generador de números aleatorios cambia de una ejecución a otra.
Si desea reproducir sus resultados antes de ejecutar ga
, puede guardar el estado del flujo de números aleatorios.
thestate = rng;
Ejecutar ga
.
[x,Fval,exitFlag,Output] = ga(FitnessFunction,numberOfVariables);
ga stopped because the average change in the fitness value is less than options.FunctionTolerance.
fprintf('The best function value found is: %g\n', Fval);
The best function value found is: -186.467
Restablezca la transmisión y vuelva a ejecutar ga
. Los resultados son idénticos a la ejecución anterior.
rng(thestate); [x,Fval,exitFlag,Output] = ga(FitnessFunction,numberOfVariables);
ga stopped because the average change in the fitness value is less than options.FunctionTolerance.
fprintf('The best function value found is: %g\n', Fval);
The best function value found is: -186.467
Si ejecuta ga
antes de especificar que desea reproducir los resultados, puede restablecer el generador de números aleatorios siempre que tenga la estructura output
.
strm = RandStream.getGlobalStream; strm.State = Output.rngstate.State;
Ejecutar nuevamente ga
. Una vez más, los resultados son idénticos.
[x,Fval,exitFlag,Output] = ga(FitnessFunction,numberOfVariables);
ga stopped because the average change in the fitness value is less than options.FunctionTolerance.
fprintf('The best function value found is: %g\n', Fval);
The best function value found is: -186.467
Modificar criterios de detención
ga
utiliza cuatro criterios diferentes para determinar cuándo detener el solucionador. ga
se detiene cuando alcanza el número máximo de generaciones; de manera predeterminada, este número es 100 veces el número de variables. ga
también detecta si el mejor valor de aptitud no cambia durante un tiempo dado en segundos (límite de tiempo de bloqueo) o durante un cierto número de generaciones (generaciones máximas de bloqueo). Otro criterio es el límite de tiempo máximo en segundos. Modificar los criterios de detención para aumentar el número máximo de generaciones a 300 y el número máximo de generaciones de detención a 100.
opts = optimoptions(opts,'MaxGenerations',300,'MaxStallGenerations', 100);
Vuelva a ejecutar el solucionador ga
.
[x,Fval,exitFlag,Output] = ga(FitnessFunction,numberOfVariables,[],[],[], ...
[],[],[],[],opts);
ga stopped because the average change in the fitness value is less than options.FunctionTolerance.
fprintf('The number of generations is: %d\n', Output.generations);
The number of generations is: 299
fprintf('The number of function evaluations is: %d\n', Output.funccount);
The number of function evaluations is: 2702
fprintf('The best function value found is: %g\n', Fval);
The best function value found is: -186.729
Especifique operadores ga
ga
comienza con un conjunto aleatorio de puntos en la población y utiliza operadores para producir la próxima generación de la población. Los diferentes operadores son escala, selección, cruce y mutación. La toolbox proporciona varias funciones para especificar para cada operador. Especifique fitscalingprop
para FitnessScalingFcn
y selectiontournament
para SelectionFcn
.
opts = optimoptions(@ga,'SelectionFcn',@selectiontournament, ... 'FitnessScalingFcn',@fitscalingprop);
Ejecutar nuevamente ga
.
[x,Fval,exitFlag,Output] = ga(FitnessFunction,numberOfVariables,[],[],[], ...
[],[],[],[],opts);
ga stopped because the average change in the fitness value is less than options.FunctionTolerance.
fprintf('The number of generations is: %d\n', Output.generations);
The number of generations is: 52
fprintf('The number of function evaluations is: %d\n', Output.funccount);
The number of function evaluations is: 2497
fprintf('The best function value found is: %g\n', Fval);
The best function value found is: -186.417
El mejor valor de la función puede mejorar o empeorar según los operadores especificados. Experimentar con diferentes operadores suele ser la mejor manera de determinar qué conjunto de operadores funciona mejor para su problema.