• No se han encontrado resultados

3. Programas de Optimización de Ciclos Combinados mediante Algoritmos Genéticos

3.1.5. Creación de los descendientes de una población

Una vez que se tiene la primera generación creada, evaluada y con sus valores pertinentes almacenados en los registros, se inicia un bucle en el que se generará un total de ‘1−mingeneraciones’ sin considerar que se pueda haber alcanzado el criterio de convergencia, el cual se explicará más adelante. En cada iteración de este bucle se llevará a cabo por tanto la creación de la nueva generación (incluyendo este paso los procesos de selección, recombinación y mutación de la generación precedente) , su evaluación y el reemplazamiento de la población anterior. A continuación puede verse la parte del programa principal que realiza este proceso.

%% PRIMERAS ITERACIONES INT_MUT=int_mut;

for i=2:1:min_generaciones

%% % 4 - Creacion de los descendientes

[pob_int, inputs_fitness_int]=Pobl_Intermedia_1P_sinDesg_sub(pob, fitness_pob, ... prob_mut, INT_MUT, pres_seleccion, p_cond, AP, DT, DI, s_anterior, h_anterior, ... rend, perd_carga, h1_g, t1_g, t4_g, x, MW_gases_comb, ratio);

%% % 5 - Evaluacion de dicha poblacion intermedia

[fitness_int]=Fitness_1P_sinDesg(inputs_fitness_int, rend_TG);

%% % 6 - Rellenado de los registros totales, que contaran con las poblaciones ... intermedias tambien

POB_tot=[pob; pob_int];

FIT_tot=[fitness_pob; fitness_int]; %% % 7 - Reemplazamiento de la poblacion

[pob, fitness_pob, test_generacion, ...

mejor_indiv]=Reemplazamiento_1P_sinDesg(POB_tot, FIT_tot, pres_seleccion, N); %% % 8 - Rellenado de los registros finales & registros de indicadores de evolucion

POB_historial(:,:,i)=pob; FIT_historial(:,i)=fitness_pob; MEJOR_individuo(i,:)=mejor_indiv; TEST_historial(i,:)=test_generacion; valor_criterio(i)=(TEST_historial(i,2)-TEST_historial(1,2)); %% % 9 - Recalculado de parametros coef_mut=(100-test_generacion(end))/(100-FIT_max_rel); INT_MUT=int_mut*coef_mut; end

A continuación se van a explicar los pasos del 4 al 6 que realiza el algoritmo genético, mostrando las funciones auxiliares llamadas, que comprenden la creación de la descendencia de una población.

Paso 4: Creación de los descendientes En este paso se lleva a cabo la mayor parte del proceso

de generación de una población nueva; la selección, recombinación, y mutación de la generación anterior. Esta población intermedia creada no tendrá solo N individuos, sino que contendrá los N individuos de la población inicial, losN descendientes, y los individuos resultantes de la mutación. Esto se realiza mediante la función auxiliarPobl_Intermedia_1P_sinDesg_sub, que devuelve un vector con la población descendiente y la mutada, y los valores respectivos con los que se evaluará su fitness.

function [pob_int, inputs_fitness_int]=Pobl_Intermedia_1P_sinDesg_sub(pob, fitness, ...

prob_mut, INT_MUT, pres_seleccion, p_cond, AP, DT_terminal, DT_inicial, s_anterior, ... h_anterior, rend, perd_carga, h1_g, t1_g, t4_g, x, MW_gases_comb, ratio)

%% Desarrollador: Joaquin Corredoyra Alcaraz % Tutor: Ruben Abbas Camara

% U.D. Motores Termicos % ETS Ingenieros Industriales % Universidad Politecnica de Madrid % 2016

%%

PROGRAMAS DE OPTIMIZACIÓN DE CICLOS COMBINADOS MEDIANTE ALGORITMOS GENÉTICOS [N,n_var]=size(pob); num_progen=round(0.5*N); num_mating_pool=round(0.75*N); %% % CROSSOVER % % % % SELECCION [fit_max, ¬]=max(fitness);

[probabilidades]=Prob_Seleccion( fitness, fit_max, pres_seleccion);

[seleccionados_reprod, ¬]=Selec_Probab_Lineal(pob, probabilidades, num_mating_pool); % RECOMBINACION

descendientes=zeros([2*num_progen, n_var]);

inputs_fitness_descendientes=zeros([2*num_progen, 5]); for i=1:2:(2*num_progen)

a=round(num_mating_pool*rand+0.5); %Para que siempre coja un numero >0 b=round(num_mating_pool*rand+0.5);

progenitor1=seleccionados_reprod(a,:); progenitor2=seleccionados_reprod(b,:);

[descendiente1, descendiente2]=Reproduccion_Uniforme(progenitor1, progenitor2); descendientes(i,:)=descendiente1;

descendientes(i+1,:)=descendiente2; end

% COMPROBACION DE LOS DESCENDIENTES for i=1:1:2*num_progen

[descendientes(i, 1), descendientes(i, 2), h5, h6, h1, h7, M, h1_g, ...

h4_g]=Comprobar_Inputs_1P_sinDesg_sub(descendientes(i, 1), p_cond, AP, ... descendientes(i, 2), DT_terminal, DT_inicial, s_anterior, h_anterior, rend, ... perd_carga, h1_g, t1_g, t4_g, x, MW_gases_comb, ratio);

inputs_fitness_descendientes(i,:)=[h5, h6, h1, h7, M, h1_g, h4_g]; end

%% % MUTACION % % %

num_mut=round(0.5*N); % SELECCION

[seleccionados_mut, ¬]=Selec_Probab_Lineal(pob, probabilidades, num_mut); % MUTACION

descendencia_mutada=Mutacion_1P_sinDesg(seleccionados_mut, INT_MUT, prob_mut); inputs_fitness_mut=zeros([num_mut, 5]);

% COMPROBACION DE LOS DESCENDIENTES for i=1:1:num_mut

[descendencia_mutada(i, 1), descendencia_mutada(i, 2), h5, h6, h1, h7, M, h1_g, ... h4_g]=Comprobar_Inputs_1P_sinDesg_sub(descendencia_mutada(i, 1), p_cond, AP, ... descendencia_mutada(i, 2), DT_terminal, DT_inicial, s_anterior, h_anterior, rend, ... perd_carga, h1_g, t1_g, t4_g, x, MW_gases_comb, ratio);

inputs_fitness_mut(i,:)=[h5, h6,h1, h7, M, h1_g, h4_g]; end %% % POBLACION INTERMEDIA % % % [pob_int]=[descendientes; descendencia_mutada]; [inputs_fitness_int]=[inputs_fitness_descendientes; inputs_fitness_mut]; end Crossover:

En esta primera parte de la generación de la población intermedia se lleva a cabo la creación de la mating pool1mediante un proceso de selección y la obtención de la descendencia por recombinación.

Proceso de Selección: Primero se genera el vector selecionados_reprodcon aquellos individuos

que conforman la mating pool. Para escogerlos, en primer lugar se le asigna una probabilidad de ser elegido a cada individuo de la generación inicial mediante Prob_Seleccion. Esta función toma como datos de entrada el vector con los rendimientos de todos lso individuos, el rendimiento del individuo más fuerte, y la presión de selección. Se ha elegido asignar probabilidades de acuerdo con un proceso de seleción similar al de tipo Boltzman explicado en la Sección (1.3.3.4) aunque con la modificación de la inclusión en la ecuación (1.10) de la presión de selección (pressel) en lugar de la temperatura. Este valor es introducido por el usuario y no varía a lo largo del progograma, y se recuerda que cuanto mayor sea, mayor será la diferencia entre la probabilidad de ser seleccionado de los individuos fuertes con respecto a

1Se recuerda que la mating pool es un conjunto de posibles progenitores entre los cuales aleatoriamente se irán seleccio-

Ciclo 1P sin desgasificador: Optimización de la presión de línea y del PP

los débiles. Con esta modificación, la ecuación mediante la cual se asignan probabilidades a os individuos de una población es la siguiente:

Pi=exp[−(ηmáxηipressel] (3.1) Al utilizar esta expresión también se introduce el elitismo, dado que el individuo de mayor fitness de la población recibirá una probabilidad de ser elegido igual a 1, dado quePi= 1 siηi=ηmáx. Por tanto, de esta forma el programa garantiza la inclusión del individuo más fuerte en la mating pool. El programa auxiliarProb_Selecciones el siguiente:

function [probabilidad]=Prob_Seleccion( fitness, fitness_max, pres_seleccion)

%% Desarrollador: Joaquin Corredoyra Alcaraz % Tutor: Ruben Abbas Camara

% U.D. Motores Termicos % ETS Ingenieros Industriales % Universidad Politecnica de Madrid % 2016 %% [N,¬]=size(fitness); probabilidad=zeros([N,1]); for i=1:1:N probabilidad(i)=exp(-(abs(fitness_max-fitness(i)))*pres_seleccion); end

El proceso de selección se completa mediante una selección por muestreo universal, como la explicada en la Sección (1.3.3.4). Esto se realiza mediante la función auxiliarSelec_Probab_Linealque, como se puede ver a continuación, sigue la misma metodología que la explicada en dicha Sección.

function[ seleccionados, posicion_selec]=Selec_Probab_Lineal(pob, probabilidades, num_selecc)

%% Desarrollador: Joaquin Corredoyra Alcaraz % Tutor: Ruben Abbas Camara

% U.D. Motores Termicos % ETS Ingenieros Industriales % Universidad Politecnica de Madrid % 2016 %% [¬,n_var]=size(pob); seleccionados=zeros([num_selecc, n_var]); posicion_selec=zeros([num_selecc, 1]); suma_prob=sum(probabilidades); intervalo=suma_prob/num_selecc; %% % COLOCACION DE PUNTEROS % % % punteros=zeros([num_selecc, 1]); punteros(1)=intervalo*rand; for i=2:1:num_selecc punteros(i)=punteros(i-1)+intervalo; end %% % ORDENACION PROBABILIDADES % % %

[prob_ord, posic_inicial]=sort(probabilidades, 'descend'); contador=zeros([ length(prob_ord)+1, 1]); for i=1:1:length(prob_ord) contador(i+1)=contador(i)+prob_ord(i); end %% % SELECCION PROGENITORES % % % for i=1:1:num_selecc j=1;

while j≤length(prob_ord) && posicion_selec(i)==0

if contador(j)≤punteros(i) && punteros(i)≤contador(j+1) seleccionados(i,:)=pob(posic_inicial(j),:); posicion_selec(i)=posic_inicial(j); end j=j+1; end end end

PROGRAMAS DE OPTIMIZACIÓN DE CICLOS COMBINADOS MEDIANTE ALGORITMOS GENÉTICOS

Esta función devuelve la matriz seleccionados con los individuos que formarán la mating pool, y el vectorposicion_selec, con su posción dentro de la población inicial.

Proceso de Recombinación: Una vez completado el proceso de selección, comienza el de recom-

binación. Mediante un bucleforse van seleccionando parejas de progenitores de entre los seleccionados previamente, y se introducen estos individuos en la función auxiliar encargada de realizar dicha recom- binación; Reproduccion_Uniforme. Dicha recombinación se realiza por medio de crossover uniforme, aunque como en el programa analizado los individuos solo cuentan con dos componentes, la recombina- ción pasa a ser un intercambio del primer gen de un progenitor con el del otro. No obstante, la función

Reproduccion_Uniformeha sido desarrollada de forma que realice un crossover uniforme para cualquier

tamaño de individuo, de forma que no tendrá que ser modificada en posteriores algoritmos. Esta función es la siguiente:

function [descendiente1, descendiente2]=Reproduccion_Uniforme(progenitor1, progenitor2)

%% Desarrollador: Joaquin Corredoyra Alcaraz % Tutor: Ruben Abbas Camara

% U.D. Motores Termicos % ETS Ingenieros Industriales % Universidad Politecnica de Madrid % 2016 %% [¬,n_var]=size(progenitor1); descendiente1=zeros([1, n_var]); descendiente2=zeros([1, n_var]); %% % VECTOR MASCARA % % % indiv_aux=round(rand(1,n_var)); numero_ptos_crossover=0; for i=1:1:n_var numero_ptos_crossover=numero_ptos_crossover+indiv_aux(i); end u=round(n_var*rand+0.5); if numero_ptos_crossover==0 indiv_aux(u)=1; elseif numero_ptos_crossover==n_var indiv_aux(u)=0; end %% % RECOMBINACION % % % for i=1:1:n_var if indiv_aux(i)==0 descendiente1(i)=progenitor1(i); descendiente2(i)=progenitor2(i); elseif indiv_aux(i)==1 descendiente1(i)=progenitor2(i); descendiente2(i)=progenitor1(i); end end end

Se hace uso de un vector máscara indiv_aux formado por unos y ceros, de la misma longitud que un individuo de la población. Este vector se usa en la recombinación de las variables de forma que si en una posición determinada el vector toma valor 0, el primer descendiente (descendiente1) tomará en dicha posición el valor que proporciona el primer progenitor (progenitor1) para dicha variable, mientras que el segundo descendiente toma el valor que proporciona el segundo progenitor. Lo contrario sucede si el valor del vector máscara en dicha posición es 1. Se puede ver que si el vector máscara estuviera compuesto enteramente por ceros o por unos, no tendría lugr ninguna recombinación dado que los descendientes recibirían todas las variables del mismo progenitor. Para evitar esto se introducen las variablesnum_puntos_crossoveryu. La primera contabiliza la cantidad de unos que contiene el vector máscara, y de ser esta cantidad cero o n_var, lo que equivale a que el vector máscara esté compuesto enteramente de unos, este vector se modifica en la posición aleatoriaupara tomar un valor 1 o un valor 0, respectivamente. De esta forma se consigue que se intercambie al menos una de ls variables.

Al finalizar, se devuelven los dos vectores correspondientes a los dos descendientes obtenidos. Como se ha dicho, este proceso se enmarca dentro de un bucle for, que se realiza hasta obtener N nuevos descendientes.

Ciclo 1P sin desgasificador: Optimización de la presión de línea y del PP

Al finalizar este proceso, se comprueba que los descendientes obtenidos son válidos y se modifican de no serlo.

Mutación:

Se ha escogido que mute la mitad de la población precedente. La mitad que será mutada se selec- ciona primero mediante Selec_Probab_Lineal, y tras realizar esto se introduce en la función auxiliar

Mutacion_1P_sinDesg. Esta función se utilizará con muy pocas modificaciones en el resto de AGs, y

devuelve un vector con los descendientes resultado de la mutación. Para realizar la mutación se hace uso de una matriz compuesta por tantos vectores máscara como individuos se desee mutar. La probabilidad de que un elemento de esta matriz sea 0 es mayor que la de que valga o 1 a no ser que prob_muttome un valor mayor de 0.5, que hace que sea más probable que el valor sea 1. Esto es porque ‘rand-0.5*1’ devuelve números comprendidos en el intervalo (−0,5,0,5), y es la adición de1*prob_mutlo que permite que se pueda tomar el valor 1. Para cada vector incluido en la matriz se realiza un proceso de comproba- ción de que no está formado enteramente por ceros, dado que entonces no habría mutación. Después de esto, y tras haber inicializdo una matriz que contendrá mutaciones aleatorias para componente de cada individuo, se realiza la mutación de los individuos seleccionados para tal proceso. Es en la generación de la matriz con las mutaciones en donde se diferenciará esta función auxiliar de la utilizada en otros AG. A continuación se muestra el código de dicha función:

function [descend_mut]=Mutacion_1P_sinDesg(seleccionados_mut, int_mut, prob_mut)

%% Desarrollador: Joaquin Corredoyra Alcaraz % Tutor: Ruben Abbas Camara

% U.D. Motores Termicos % ETS Ingenieros Industriales % Universidad Politecnica de Madrid % 2016

%%

%% % MUTACIONES % % %

% Se generan las mutaciones aleatoriamente favoreciendo un incremento en p (variara ... entre -1 y 2 por int_mut) y

% una disminucion en PP (que variara entre -1 y 0 K por int_mut) [N, n_var]=size(seleccionados_mut);

mutaciones=zeros([N, n_var]);

mutaciones(:,1)=int_mut*(3*rand(N,1)-ones(N,1)); mutaciones(:,2)=int_mut*(rand(N,1)-ones(N,1)); %% % MATRIZ DE VECTORES MASCARA % % %

matriz_aux=round(rand(N,n_var)-0.5*ones(N,n_var)+prob_mut*ones(N,n_var)); numero_ptos_crossover=zeros(N,1); for i=1:1:N for j=1:1:n_var numero_ptos_crossover(i)=numero_ptos_crossover(i)+matriz_aux(i,j); end end

u=round(n_var*rand(N,1)+0.5); %Variable aleatoria para vigilar que no mute niguna de ... las variables for i=1:1:N if numero_ptos_crossover(i)==0 matriz_aux(i,u(i))=1; end end %% % MUTACION PROGENITORES % % % descend_mut=seleccionados_mut+mutaciones.*matriz_aux; end

Para realizar la matrizmutacionesse ha tenido en cuenta que los mayores rendimientos se obtienen para valores altos de presi’on y bajos de PP, por lo que se favorece que la mutación tenga este efecto. Esto no se puede realizar en algoritmos en los que no se tenga tan claro cuál es el efecto de todas y cada una de las variables; en estos casos, las mutaciones serán puramente aleatorias, pudiendo elevar o disminuir el valor de cada variable con la misma probabilidad. Se puede ver cómoint_mutmodifica la intensidad de la mutación; cuanto mayor sea, de mayor magnitud serán las variaciones producidas durante la mutación. El proceso de mutación termina con una comprobación de los descendientes obtenidos, dando lugar a soluciones válidas.

PROGRAMAS DE OPTIMIZACIÓN DE CICLOS COMBINADOS MEDIANTE ALGORITMOS GENÉTICOS

Tras finalizar la mutación se da por finalizada la función Pobl_Intermedia_1P_sinDesg_sub, y de- vuelve una matriz con la descendencia por recombinación y por mutación, y otra matriz con los valores necesarios para calcular sus fitness en elPaso 5.

Documento similar