#include "genocop.h" /********************************************************************************/ /* */ /* FUNCTION NAME : oper1() */ /* */ /* SYNOPSIS : VECTOR oper1(parent,fin_mat,rc) */ /* */ /* DESCRIPTION : This function returns a new vector generated */ /* from the parent vector, after applying */ /* the operator, uniform mutation. */ /* */ /* FUNCTIONS CALLED : find_range(), */ /* frange_ran(), */ /* irange_ran(), */ /* vector(). */ /* */ /* CALLING FUNCITONS : optimization() */ /* */ /* AUTHOR : Swarnalatha Swaminathan */ /* */ /* DATE : 1/17/92 */ /* */ /* */ /* REV DATE BY DESCRIPTION */ /* --- ---- -- ----------- */ /* */ /* */ /********************************************************************************/ void oper1(parent,fin_mat,rc) VECTOR parent; /*The parent vector*/ MATRIX fin_mat; /*The final matrix*/ INDEX rc; /*Row and column of the final matrix*/ { int comp,i; float llim,ulim;/*Lower and Upper limits of the value to be mutated*/ comp = irange_ran(1,rc.c-2); /*Finding the lower and upper limits between which the values are to be mutated*/ find_range(&llim,&ulim,comp,fin_mat,rc,parent); /*Find a random value between the lower and the upper limits, to substitute*/ /*for the old value*/ parent[comp] = frange_ran(llim,ulim); } /********************************************************************************/ /* */ /* FUNCTION NAME : oper2() */ /* */ /* SYNOPSIS : VECTOR oper2(parent,fin_mat,rc) */ /* */ /* DESCRIPTION : This function returns a new vector generated */ /* from the parent vector, after applying */ /* the operator, boundary mutation. */ /* */ /* FUNCTIONS CALLED : find_range(), */ /* flip(), */ /* irange_ran(), */ /* vector(). */ /* */ /* CALLING FUNCITONS : optimization() */ /* */ /* AUTHOR : Swarnalatha Swaminathan */ /* */ /* DATE : 1/17/92 */ /* */ /* */ /* REV DATE BY DESCRIPTION */ /* --- ---- -- ----------- */ /* */ /* */ /********************************************************************************/ void oper2(parent,fin_mat,rc) VECTOR parent; /*The parent vector*/ MATRIX fin_mat; /*The final matrix*/ INDEX rc; /*Row and column of the final matrix*/ { int comp,i; float llim,ulim;/*Lower and Upper limits of the value to be mutated*/ comp = irange_ran(1,rc.c-2); /*Finding the lower and upper limits between which the values are to be mutated*/ find_range(&llim,&ulim,comp,fin_mat,rc,parent); /*Replace either the lower limit or the upper limit at random,*/ /*for the old value*/ parent[comp] = (flip() == TAIL) ? llim : ulim; } /********************************************************************************/ /* */ /* FUNCTION NAME : oper3() */ /* */ /* SYNOPSIS : VECTOR oper3(parent,fin_mat,r,c,T,t,B) */ /* */ /* DESCRIPTION : This function returns a new vector generated */ /* from the parent vector, after applying */ /* the operator, non-uniform mutation. */ /* */ /* FUNCTIONS CALLED : find_range(), */ /* flip(), */ /* get_F(), */ /* irange_ran(), */ /* vector(). */ /* */ /* CALLING FUNCITONS : optimization() */ /* */ /* AUTHOR : Swarnalatha Swaminathan */ /* */ /* DATE : 1/17/92 */ /* */ /* */ /* REV DATE BY DESCRIPTION */ /* --- ---- -- ----------- */ /* */ /* */ /********************************************************************************/ void oper3(parent,fin_mat,rc,T,t,B) VECTOR parent; MATRIX fin_mat; INDEX rc; unsigned long T; /*Total number of generations*/ unsigned long t; /*Current generation number*/ int B; { int comp,i; float llim,ulim; comp = irange_ran(1,rc.c-2); find_range(&llim,&ulim,comp,fin_mat,rc,parent); /*From the current value of the component to be mutated, chooose at random*/ /*whether to mutate with a lesser value or a greater value*/ /*Then find a value lesser or greater than the original value from the*/ /*function get_f()*/ parent[comp] = (flip() == TAIL) ? parent[comp]-get_F(T,t,parent[comp]-llim,B) : parent[comp]+get_F(T,t,ulim-parent[comp],B); } /********************************************************************************/ /* */ /* FUNCTION NAME : oper4() */ /* */ /* SYNOPSIS : MATRIX oper4(p1,p2,x2_vari) */ /* */ /* DESCRIPTION : This function returns two new vectors */ /* generated after whole arithmetical */ /* crossover, from the two parent vectors. */ /* */ /* FUNCTIONS CALLED : matrix() */ /* */ /* CALLING FUNCITONS : optimization() */ /* */ /* AUTHOR : Swarnalatha Swaminathan */ /* */ /* DATE : 1/17/92 */ /* */ /* */ /* REV DATE BY DESCRIPTION */ /* --- ---- -- ----------- */ /* A 10/1/92 Tom Logan Parameter A is now */ /* random(0-1) */ /* */ /********************************************************************************/ void oper4(p1,p2,x2_vari) VECTOR p1,p2; /*The two parents chosen for crossover*/ int x2_vari; /*Length of the vector*/ { MATRIX child; int i; float A; child = matrix(1,2,1,x2_vari); do A = frange_ran(0.0,1.0); while (A==0); /* insure A is above 0 */ for(i=1; i<=x2_vari; i++) { child[1][i] = p1[i] * A + p2[i] * (1.0-A); child[2][i] = p2[i] * A + p1[i] * (1.0-A); } for(i=1; i<=x2_vari; i++) { p1[i] = child[1][i]; p2[i] = child[2][i]; } free_matrix(child,1,2,1); } /********************************************************************************/ /* */ /* FUNCTION NAME : oper5() */ /* */ /* SYNOPSIS : MATRIX oper5(p1,p2,STEP,rc,fin_mat,X,x2) */ /* */ /* DESCRIPTION : This function returns two new vectors */ /* generated after simple arithmetical */ /* crossover, from the two parent vectors. */ /* */ /* FUNCTIONS CALLED : irange_ran() */ /* matrix(), */ /* satis_con() */ /* */ /* CALLING FUNCITONS : optimization() */ /* */ /* AUTHOR : Swarnalatha Swaminathan */ /* */ /* DATE : 1/17/92 */ /* */ /* */ /* REV DATE BY DESCRIPTION */ /* --- ---- -- ----------- */ /* */ /* */ /********************************************************************************/ void oper5(p1,p2,STEP,rc,fin_mat) VECTOR p1,p2; /*The two parents for crossing over*/ INDEX rc; /*Row and column of the final matrix*/ MATRIX fin_mat; /*The final matrix*/ int STEP; /*Parameter for the crossover*/ { MATRIX child; FLAG _CHECK1 = FALSE,/*Check to see if the newly created vectors satisfies the*/ _CHECK2 = FALSE;/*set of constraints*/ int i,n=1,cut; child = matrix(1,2,1,rc.c-2); /*Get a random spot on the vector for crossover*/ cut = irange_ran(1,rc.c-2); /*Copy the parent vectors on to the child vectors*/ for(i=1; i<=cut; i++) { child[1][i] = p1[i]; child[2][i] = p2[i]; } do { /*Cross the two vectors*/ for(i=cut + 1; i<=rc.c-2; i++) { child[1][i] = p1[i] * (float)n/(float)STEP + p2[i] * (1.0-(float)n/(float)STEP); child[2][i] = p2[i] * (float)n/(float)STEP + p1[i] * (1.0-(float)n/(float)STEP); } /*Check to see if they satisfy the constraints*/ _CHECK1 = satis_con(child[1],fin_mat,rc); _CHECK2 = satis_con(child[2],fin_mat,rc); n++; /*If the constraints not satisfied, then generate another*/ /*set of crossed over values*/ }while((n<=STEP) && ((_CHECK1 == FALSE) || (_CHECK2 == FALSE))); for(i=1; i<=rc.c-2; i++) { p1[i] = child[1][i]; p2[i] = child[2][i]; } free_matrix(child,1,2,1); } /********************************************************************************/ /* */ /* FUNCTION NAME : oper6() */ /* */ /* SYNOPSIS : VECTOR oper6(parent,fin_mat,r,c,T,t,B) */ /* */ /* DESCRIPTION : This function returns a new vector generated */ /* from the parent vector, after applying */ /* the operator, whole non-uniform mutation. */ /* */ /* FUNCTIONS CALLED : find_range(), */ /* flip(), */ /* get_F(), */ /* irange_ran(), */ /* vector(). */ /* */ /* CALLING FUNCITONS : optimization() */ /* */ /* AUTHOR : Swarnalatha Swaminathan */ /* */ /* DATE : 1/17/92 */ /* */ /* */ /* REV DATE BY DESCRIPTION */ /* --- ---- -- ----------- */ /* A 9/1/92 Tom Logan */ /* */ /********************************************************************************/ void oper6(parent,fin_mat,rc,T,t,B) VECTOR parent; MATRIX fin_mat; INDEX rc; unsigned long T; /*Total number of generations*/ unsigned long t; /*Current generation number*/ int B; { int comp, i, num, *next; float llim,ulim; next = ivector(1, rc.c-2); for(i=1; i<=rc.c-2; i++) next[i] = 0; for (i=1; i<=rc.c-2; i++) { do comp = irange_ran(1, rc.c-2); while (next[comp] == 1); next[comp] = 1; find_range(&llim,&ulim,comp,fin_mat,rc,parent); /*From the current value of the component to be mutated, chooose at random*/ /*whether to mutate with a lesser value or a greater value*/ /*Then find a value lesser or greater than the original value from the*/ /*function get_f()*/ parent[comp] = (flip() == TAIL) ? parent[comp]-get_F(T,t,parent[comp]-llim,B) : parent[comp]+get_F(T,t,ulim-parent[comp],B); } free_ivector(next,1); } /********************************************************************************/ /* */ /* FUNCTION NAME : oper7() */ /* */ /* SYNOPSIS : void oper7(p1,p2,rc,fin_mat,X,x2) */ /* */ /* DESCRIPTION : This function returns one new vector */ /* */ /* FUNCTIONS CALLED : frange_ran() */ /* vector(), */ /* satis_con() */ /* */ /* CALLING FUNCITONS : optimization() */ /* */ /* AUTHOR : Tom Logan */ /* */ /* DATE : 10/1/92 */ /* */ /* */ /* REV DATE BY DESCRIPTION */ /* --- ---- -- ----------- */ /* */ /* */ /********************************************************************************/ void oper7(p1,p2,rc,fin_mat) VECTOR p1,p2; /*The two parents for crossing over*/ INDEX rc; /*Row and column of the final matrix*/ MATRIX fin_mat; /*The final matrix*/ { VECTOR child; FLAG _CHECK = FALSE;/*Check to see if the newly created vector satisfies the*/ /*set of constraints*/ int i,n=2,tries=10; float A; child = vector(1,rc.c-2); do { A = frange_ran(0.0,1.0); for(i=1; i<=rc.c-2; i++) child[i] = A * (p2[i] - p1[i]) + p2[i]; /*Check to see if it satisfies the constraints*/ _CHECK = satis_con(child,fin_mat,rc); n++; /*If the constraints not satisfied, then try again */ } while((n<=tries) && (_CHECK == FALSE)); if (_CHECK) for(i=1; i<=rc.c-2; i++) p1[i] = child[i]; free_vector(child,1); } /********************************************************************************/ /* */ /* FUNCTION NAME : satis_con() */ /* */ /* SYNOPSIS : FLAG satis_con(child,fin_mat,rc) */ /* */ /* DESCRIPTION : This function returns TRUE or FALSE depending*/ /* on whether the vector passed satisfies all */ /* the constraints or not. */ /* */ /* FUNCTIONS CALLED : none() */ /* */ /* CALLING FUNCITONS : oper5() */ /* */ /* AUTHOR : Swarnalatha Swaminathan */ /* */ /* DATE : 1/17/92 */ /* */ /* */ /* REV DATE BY DESCRIPTION */ /* --- ---- -- ----------- */ /* */ /* */ /********************************************************************************/ FLAG satis_con(child,fin_mat,rc) VECTOR child; /*The vector to be checked for violation of constriants*/ MATRIX fin_mat; /*The final matrix*/ INDEX rc; /*Row and column of the final matrix*/ { int i,j; float tot; for(j=1; j<=rc.c-2; j++) if((child[j] > fin_mat[j][rc.c]) || (child[j] < fin_mat[j][1])) return(FALSE); /*Substitute the values for all the variables, with the new values of*/ /*the vector passed and check if the limits are crossed*/ for(j=1; j<=rc.r; j++) { tot = 0.0; for(i=2; i<=rc.c-1; i++) tot = tot + fin_mat[j][i] * child[i-1]; /*If the limits are crossed, return FALSE*/ if((tot < fin_mat[j][1]) || (tot > fin_mat[j][rc.c])) return(FALSE); } /*If the limits are not crossed, return TRUE*/ return(TRUE); } /********************************************************************************/ /* */ /* FUNCTION NAME : find_range() */ /* */ /* SYNOPSIS : void find_range(llim,ulim,comp,fin_mat,rc */ /* X,x2)*/ /* */ /* DESCRIPTION : This function finds the upper and lower */ /* limits, within which the mutation should */ /* occur. */ /* */ /* FUNCTIONS CALLED : none() */ /* */ /* CALLING FUNCITONS : oper1() */ /* oper2() */ /* oper3() */ /* */ /* AUTHOR : Swarnalatha Swaminathan */ /* */ /* DATE : 1/17/92 */ /* */ /* */ /* REV DATE BY DESCRIPTION */ /* --- ---- -- ----------- */ /* */ /* */ /********************************************************************************/ void find_range(llim,ulim,comp,fin_mat,rc,parent) float *llim,*ulim;/*Upper and lower limits*/ int comp; /*Component of the vector to be mutated*/ INDEX rc; /*Row and column of the final matrix*/ MATRIX fin_mat; /*The final matrix*/ VECTOR parent; /*The vector with the values of the variables*/ { int i,j; float tot,templ,tempu,temp; FLAG _CHANGE=FALSE; /*Replace the values of the variables, and for the values of the vectors*/ /*except the one which is to be mutated*/ /*Find the lower and upper limits within which the mutation component's*/ /*value should be found*/ for(j=1; j<=rc.r; j++) if(fin_mat[j][comp+1] != 0.0) { tot = 0.0; for(i=2; i<=rc.c-1; i++) if(i!=comp+1) tot = tot + fin_mat[j][i] * parent[i-1]; templ = (fin_mat[j][1] - tot) / fin_mat[j][comp+1]; tempu = (fin_mat[j][rc.c] - tot) / fin_mat[j][comp+1]; if(fin_mat[j][comp+1]<0) swap(&templ,&tempu); /* if(templ > tempu) swap(&templ,&tempu); */ if(!_CHANGE) { *llim = templ; *ulim = tempu; _CHANGE = TRUE; } else { if(*llim < templ) *llim = templ; if(*ulim > tempu) *ulim = tempu; } } } /********************************************************************************/ /* */ /* FUNCTION NAME : irange_ran() */ /* */ /* SYNOPSIS : int irange_ran(llim,ulim) */ /* */ /* DESCRIPTION : This function returns a random integer */ /* between the llim and ulim. */ /* */ /* FUNCTIONS CALLED : None */ /* */ /* CALLING FUNCITONS : find_parent(), */ /* oper1(). */ /* oper2(). */ /* oper3(). */ /* oper5(). */ /* */ /* AUTHOR : Swarnalatha Swaminathan */ /* */ /* DATE : 1/17/92 */ /* */ /* */ /* REV DATE BY DESCRIPTION */ /* --- ---- -- ----------- */ /* */ /* */ /********************************************************************************/ int irange_ran(llim,ulim) int ulim,llim; { int num; do num = llim + ((int) ((newrand()*(long)(ulim-llim+1))/(long) 65535)); while ((num < llim) || (num > ulim)); return(num); } /********************************************************************************/ /* */ /* FUNCTION NAME : get_F() */ /* */ /* SYNOPSIS : float get_F(T,t,y,B) */ /* */ /* DESCRIPTION : This function returns the float value which */ /* is the evaluated value of the function, */ /* needed for the operators 3 and 6 */ /* */ /* FUNCTIONS CALLED : none() */ /* */ /* CALLING FUNCITONS : oper3() */ /* CALLING FUNCITONS : oper6() */ /* */ /* AUTHOR : Tom Logan */ /* */ /* DATE : 2/23/93 */ /* */ /* */ /* */ /********************************************************************************/ float get_F(T,t,y,B) unsigned long t,T; int B; float y; { float factor; factor = (float) pow(1.0 - (float)t/(float)T,(float)B); factor = factor * frange_ran(0.0,1.0); if (factor < 0.00001) factor = 0.00001; return(y * factor); }