/********************************************************************\ *** NON-DOMINATED SORTING *** *** using *** *** GENETIC ALGORITHM *** *** for *** *** MULTI OBJECTIVE OPTIMIZATION *** *** *** *** Developed by : Kalyanmoy Deb and Mayank Goyal *** *** The Department of Mechanical Engineering *** *** Indian Institute of Technology, Kanpur *** *** Kanpur, PIN 208 016, INDIA *** ***................................................................*** *** This is a GA implementation for multi-objective optimization. *** *** For multi-objective optimization, non-domonated sorting has *** *** been used. The design variables can be Binary, Integer, Real *** *** or Enumerated data type. Moreover a design vector can have *** *** design variables where each variable can be any of the above *** *** mentioned types. The order in which the design variables *** *** are needed is also maintained in the code. For multi-objective*** *** optimization, sharing is done using either of two ways : *** *** Sharing on Fitness Space or Sharing on Parameter Space. After *** *** completion, results are stored in a 'result.out' and for *** *** detailed inspection in a file 'report'. For a detail discussion*** *** please refer to Journal paper: *** *** Srinivas, N. and Deb, K. (1994). Multiobjective optimization *** *** using nondominated sorting genetic algorithms. Evolutionary *** *** Computation. Vol. 2, No. 3. Pages 221--248. *** *** *** *** Please send your comments or bug information at *** *** deb@ls11.informatik.uni-dortmund.de or deb@iitk.ernet.in *** *** *** *** All rights reserved. Not to be used for commercial purposes. *** *** In case of a publication resulted by use of this code, *** *** an acknowledgement will be appreciated. *** *** *** *** Last update 15 June 1998 Kalyanmoy Deb *** \********************************************************************/ #include #include #define BITS_PER_BYTE 8 #define UINTSIZE (BITS_PER_BYTE*sizeof(unsigned)) #define INFINITY 1e7 #define EPSILON 1e-6 #define PI 3.1415927 #define MAXVECSIZE 30 #define MAXPOPSIZE 500 #define MAXENUMDATA 100 #define MAXOBJ 5 #define MINSCHEME 1 /* do not change */ #define TRUE 1 /* ,, */ #define FALSE 0 /* ,, */ #define ONESITE 1 /* ,, */ #define UNIF 2 /* ,, */ #define BIN 1 /* ,, */ #define INT 2 /* ,, */ #define ENUM 3 /* ,, */ #define CONT 4 /* ,, */ #define square(x) ((x)*(x)) #define cube(x) ((x)*(x)*(x)) #define PENALTY_COEFF 1.0e3 /*============================= Choose your problem here (put your problem at the end of code) ===========================*/ #define f3 /*================= TYPE DEFINTIONS : =================*/ struct indiv { unsigned *chrom; /* chrosome string */ float fitness[MAXOBJ]; /* fitness functions */ float x[MAXVECSIZE]; /* variables */ float dumfitness; /* modified objective */ int flag; /* flag as follows 0 => untouched 1 => dominated 2 => non-dominated 3 => exhausted */ int front; /* Front of the indiv. */ int parent1; /* two parents */ int parent2; }; typedef struct indiv INDIVIDUAL ; typedef INDIVIDUAL *POPULATION ; /* array of individuals */ /*==================== FUNCTION PROTOTYPES : ====================*/ float randomperc(); float get_beta(); float get_delta(); float get_beta_rigid(); double noise(); float rndreal(); int small(); /*================== GLOBAL VARIABLES : ==================*/ int pop_size, /* Population Size */ gen_no, /* Current generation number */ max_gen, /* Maximum no. of generations */ no_xover, /* No. of cross overs done */ no_mutation, /* No. of mutations done */ num_var, /* Number of total design variables */ num_bin_var, /* Number of binary variables */ num_int_var, /* Number of integer variables */ num_enum_var, /* Number of enumerated variables */ num_cont_var, /* Number of continuous variables */ num_obj, /* Number of objectives */ lchrom[MAXVECSIZE], /* Length of chromosome */ chromsize, /* Number of bytes needed to store lchrom strings */ x_strategy, /* Crossover strategy UNIF,ONESITE etc. */ REPORT, /* Flag for Full reports (True/False) */ var_RIGID[MAXVECSIZE], /* Flag for rigid boundaries (T/F) */ BINGA, /* Flag for binary GA (T/F) */ REALGA, /* Flag for real-GA (T/F) */ FITNESS, /* Flag for sharing strategy (T/F) */ PARAM, minmax[MAXOBJ], /* min or max flag */ tourneylist[MAXPOPSIZE],/* List of indices of individuals for tournament selection routine */ tourneypos, /* Current position of tournament */ tourneysize, /* Tournament size ( = 2 for binary )*/ var_type[MAXVECSIZE], /* Temp. variable type */ TotalChromLength, /* Total Chromosome Length */ num_enum_data[MAXVECSIZE];/* Number of Enumerated Data for each enumerated variable */ float seed, /* Random seed number */ n_distribution_c, n_distribution_m, /* Distribution index for SBX */ p_xover, /* Cross over probability */ p_mutation, /* Mutation probability */ closeness, /* Closeness epsilon */ minx[MAXVECSIZE], /* Minimum value of design variables */ maxx[MAXVECSIZE], /* Maximum value of design variables */ x_lower[MAXVECSIZE], /* Lower and Upper bounds on each */ x_upper[MAXVECSIZE], /* design variable */ afmin[MAXOBJ], /* approx min value of obj funs. */ afmax[MAXOBJ], /* approx max value of obj funs */ dshare, /* Sharing distance */ max_spread, /* Maximum spread */ maxf[MAXOBJ], /* Maximum fitness values */ minf[MAXOBJ], /* Minimum fitness values */ avgfitness[MAXOBJ], /* Average fitness values */ dum_avg, min_dum, /* Avg. and min. dummy fitness */ init_dum,delta_dum, /* Initial and delta dummy fitness */ c1=0.0,c2=0.0, /* Children */ weightage[MAXOBJ], /* Weightage assigned to fitness */ EnumData[MAXVECSIZE][MAXENUMDATA]; /* Enumerated Data */ POPULATION oldpop, newpop; /* Old and New populations */ int *choices, nremain; float *fraction; /*==================================================================== SUBROUTINE FOR INPUTTING GLOBAL PARAMETERS : ====================================================================*/ input_parameters() { int k,temp2,count; char ans; float temp1, sumweight; printf("\nNumber of objective functions (2) --> "); scanf("%d",&num_obj); printf("\nSpecify minimization (1) or maximization (-1) for each function "); for (count=0; count ",count+1); scanf("%d",&minmax[count]); } printf("\nNumber of variables (Maximum %2d) --- : ",MAXVECSIZE); scanf("%d",&num_var); BINGA = FALSE; REALGA = FALSE; TotalChromLength=0; num_bin_var=0; num_int_var=0; num_enum_var=0; num_cont_var=0; for (k=0; k<= num_var-1; k++) { printf("\nVariable Type for variable #%2d : \n",k+1); printf("\t\t 1 for Binary\n"); printf("\t\t 2 for Integer\n"); printf("\t\t 3 for Enumerated\n"); printf("\t\t 4 for Continuous/Real"); printf("\n Give your choice (1/2/3/4) ------- : "); scanf("%d",&var_type[k]); if (var_type[k]!=ENUM) /* If not ENUM, ask for bounds */ { printf("\nLower and Upper bounds of x[%d] ----- : ",k+1); scanf("%f %f",&x_lower[k],&x_upper[k]); } if (var_type[k]!=CONT) var_RIGID[k] = TRUE; if (var_type[k]==BIN) /* If BIN Type ask for chromosome length */ { num_bin_var++; BINGA = TRUE; printf("\nChromosome Length ------------------ : "); scanf("%d",&lchrom[k]); TotalChromLength += lchrom[k]; } else lchrom[k] = 0; /* End of BIN */ if (var_type[k]==ENUM) /* If ENUM Type read the enumerated data */ { num_enum_var++; REALGA=TRUE; printf("\nEnter the data for variable [%d] in ASCENDING order.\n",k+1); printf("End of data recognized by 999999: "); temp2=0; scanf("%f",&temp1); EnumData[k][0] = temp1; temp2++; while (!small(temp1-999999.0)) { scanf("%f",&temp1); EnumData[k][temp2] = temp1; temp2++; } num_enum_data[k]=temp2-1; x_lower[k]=EnumData[k][0]; x_upper[k]=EnumData[k][num_enum_data[k]-1]; } else num_enum_data[k]=0; /* End of ENUM */ if (var_type[k]==INT) /* If INT Type form the enumerated data */ { num_int_var++; REALGA=TRUE; num_enum_data[k] = x_upper[k]-x_lower[k]+1; for (count=0;count ",count+1); scanf("%f", &weightage[count]); sumweight += weightage[count]; printf("\n Lower and Upper values of function #%2d (approx.) -> ",count+1); scanf("%f %f", &afmin[count], &afmax[count]); } for (count=0; count MAXPOPSIZE) { printf("\n Increase the value of MAXPOPSIZE in program"); printf(" and re-run the program"); exit(-1); } printf("\nCross Over Probability ? ( 0.7 to 1 ) : "); scanf("%f",&p_xover); printf("\nMutation Probability ? ( 0 to 0.2 ) -- : "); scanf("%f",&p_mutation); printf("\n Give the strategy for X-over"); printf("\n 1 : Single-point crossover"); printf("\n 2 : Uniform crossover"); printf("\n Give your choice -------------(1/2) : "); scanf("%d",&x_strategy); if (REALGA) { printf("\nDistribution Index for crossover and mutation (30 50) : "); scanf("%f %f",&n_distribution_c, &n_distribution_m); } printf("\nHow many generations (100) ? --------- : "); scanf("%d",&max_gen); printf("\nGive random seed (0 to 1.0) : "); scanf("%f",&seed); input_app_parameters(); } /*==================================================================== Initialses zero'th generation and global parameters ====================================================================*/ initialize() { float u; int tmp,k,k1,i,j,j1,stop; double temp[MAXVECSIZE],coef; unsigned mask=1,nbytes; randomize(); app_initialize(); oldpop = (INDIVIDUAL *)malloc(pop_size*sizeof(INDIVIDUAL)); newpop = (INDIVIDUAL *)malloc(pop_size*sizeof(INDIVIDUAL)); if (oldpop == NULL) nomemory("oldpop in initialize()"); if (newpop == NULL) nomemory("newpop in initialize()"); if (BINGA) /* If Binary Variables, allocate memory for chromosomes */ { chromsize = (TotalChromLength/UINTSIZE); if (TotalChromLength%UINTSIZE) chromsize++; nbytes = chromsize*sizeof(unsigned); for(j = 0; j < pop_size; j++) { if((oldpop[j].chrom = (unsigned *) malloc(nbytes)) == NULL) nomemory("oldpop chromosomes"); if((newpop[j].chrom = (unsigned *) malloc(nbytes)) == NULL) nomemory("newpop chromosomes"); } } /* End of If (BINGA) */ /* Initializing continuous, integer and enumerated variables */ for (k=0; k<= pop_size-1; k++) { oldpop[k].flag = 0; oldpop[k].parent1 = oldpop[k].parent2 = 0; oldpop[k].dumfitness = 0.0; for (j=0; j<=num_var-1; j++) { if (var_type[j]!=BIN) { u = randomperc(); oldpop[k].x[j] = x_lower[j] * (1-u) + x_upper[j] * u; if ((var_type[j]==INT)||(var_type[j]==ENUM)) { for(k1=0;k1EnumData[j][num_enum_data[j]-1]) { oldpop[k].x[j]=EnumData[j][num_enum_data[j]-1]; continue; } else if ((EnumData[j][k1]oldpop[k].x[j])) oldpop[k].x[j]=( (EnumData[j][k1+1]-oldpop[k].x[j])> (oldpop[k].x[j]-EnumData[j][k1]) ) ? EnumData[j][k1] : EnumData[j][k1+1]; } /* End of for k1 */ } /* End of if (INT or ENUM) */ } /* End of if (not BIN) */ } /* Initializing chromosomes for binary variables */ for(k1 = 0; k1 < chromsize; k1++) { oldpop[k].chrom[k1] = 0; if(k1 == (chromsize-1)) stop = TotalChromLength - (k1*UINTSIZE); else stop = UINTSIZE; /* A fair coin toss */ for(j1 = 1; j1 <= stop; j1++) { if (flip(0.5)) oldpop[k].chrom[k1] = oldpop[k].chrom[k1]|mask; if (j1 != stop) oldpop[k].chrom[k1] = oldpop[k].chrom[k1]<<1; } /* End of for (j1) */ } /* End of for (k1) */ } /* End of for (k) */ no_xover = no_mutation = 0; init_dum = pop_size; /* For Sharing */ min_dum = 0.0; delta_dum = 0.1*init_dum; /* Decoding binary strings and initializing fitness values for each individual */ for (k=0; k<= pop_size-1; k++) { decode_string(&(oldpop[k])); objective(&(oldpop[k])); } } /*==================================================================== Decodes the string of the individual (if any) and puts the values in the array of floats. ====================================================================*/ decode_string(ptr_indiv) INDIVIDUAL *ptr_indiv; { double *temp,coef[MAXVECSIZE]; int j; if (ptr_indiv == NULL) error_ptr_null("ptr_indiv in decode_string"); if (BINGA) { temp = (double *) malloc(num_var * sizeof(double)); for(j=0; jchrom,temp); for(j=0; jx[j] = temp[j]*x_upper[j] + (1.0 - temp[j])*x_lower[j]; } free(temp); } } /*==================================================================== Prints an error message and terminates the program ====================================================================*/ nomemory(string) char *string; { printf("\nmalloc: out of memory making %s!!\n",string); printf("\n Program is halting ....."); exit(-1); } /*============================================================== Gives error message of null pointer and terminates the program. ==============================================================*/ error_ptr_null(string) char *string; { printf("\n Error !! Pointer %s found Null !",string); printf("\n Program is halting ....."); exit(-1); } /*==================================================================== Calculates statistics of current generation : ====================================================================*/ statistics(pop,gen) POPULATION pop; int gen; { int j,iobj; float dumsumfit = 0.0; float sumfitness[MAXOBJ]; for (iobj=0; iobj maxf[iobj]) maxf[iobj] = pop[j].fitness[iobj]; if (pop[j].fitness[iobj] < minf[iobj]) minf[iobj] = pop[j].fitness[iobj]; } } dum_avg = dumsumfit/(double)pop_size; for (iobj=0; iobj=sumlengthstring) flag1=TRUE; else flag1=FALSE; sumlengthstring+=lchrom[count]; if ((bitpos>1; } /* End of for (j) */ } /* End of for (k) */ } /*==================================================================== GENERATION OF NEW POPULATION through SELECTION, XOVER & MUTATION : ====================================================================*/ generate_new_pop() { int j,k,k1,mate1,mate2; app_computation(); preselect(); for (k=0; k<= pop_size-1; k += 2) { mate1 = select(); /* Stoc. Rem. Roulette Wheel Selection */ mate2 = select(); switch( x_strategy ) /* Crossover */ { case ONESITE : cross_over_1_site(mate1,mate2,k,k+1); break; case UNIF : cross_over_unif(mate1,mate2,k,k+1) ; break; } mutation(&newpop[k]); /* Mutation */ decode_string(&(newpop[k])); update_x_BIN_ENUM(&(newpop[k])); objective(&(newpop[k])); newpop[k].parent1 = mate1+1; newpop[k].parent2 = mate2+1; mutation(&newpop[k+1]); decode_string(&(newpop[k+1])); update_x_BIN_ENUM(&(newpop[k+1])); objective(&(newpop[k+1])); newpop[k+1].parent1 = mate1+1; newpop[k+1].parent2 = mate2+1; } /* For whole population */ } /*************************************************************** For integer and enumerated data, a permissible solution is calculated here **************************************************************/ update_x_BIN_ENUM(indv) INDIVIDUAL *indv; { int j, k1; for(j=0;jx[j]x[j]=EnumData[j][0]; continue; } else if (indv->x[j]>EnumData[j][num_enum_data[j]-1]) { indv->x[j]=EnumData[j][num_enum_data[j]-1]; continue; } else if ((EnumData[j][k1]< indv->x[j])&& (EnumData[j][k1+1]> indv->x[j])) indv->x[j]=( (EnumData[j][k1+1] - indv->x[j]) > (indv->x[j]-EnumData[j][k1]) ) ? EnumData[j][k1] : EnumData[j][k1+1]; } /* End of for (k1) */ } } /*==================================================================== Binary cross over routine. ====================================================================*/ binary_xover (parent1, parent2, child1, child2) unsigned *parent1, *parent2, *child1, *child2; /* Cross 2 parent strings, place in 2 child strings */ { int j, jcross, k; unsigned mask, temp; if (BINGA == FALSE) return; if (parent1 == NULL) error_ptr_null("parent1 in binary_xover"); if (parent2 == NULL) error_ptr_null("parent2 in binary_xover"); if (child1== NULL) error_ptr_null("child1 in binary_xover"); if (child2== NULL) error_ptr_null("child2 in binary_xover"); jcross = rnd(1 ,(TotalChromLength - 1));/* Cross between 1 and l-1 */ for(k = 1; k <= chromsize; k++) { if(jcross >= (k*UINTSIZE)) { child1[k-1] = parent1[k-1]; child2[k-1] = parent2[k-1]; } else if((jcross < (k*UINTSIZE)) && (jcross > ((k-1)*UINTSIZE))) { mask = 1; for(j = 1; j <= (jcross-1-((k-1)*UINTSIZE)); j++) { temp = 1; mask = mask<<1; mask = mask|temp; } child1[k-1] = (parent1[k-1]&mask)|(parent2[k-1]&(~mask)); child2[k-1] = (parent1[k-1]&(~mask))|(parent2[k-1]&mask); } else { child1[k-1] = parent2[k-1]; child2[k-1] = parent1[k-1]; } } } /*==================================================================== Creates two children from parents p1 and p2, stores them in addresses pointed by c1 and c2. low and high are the limits for x values and rand_var is the random variable used to create children points. ====================================================================*/ create_children(p1,p2,c1,c2,low,high,RIGID) float p1,p2,*c1,*c2,low,high; int RIGID; { float difference, x_mean, beta, temp; float u, u_l, u_u, beta_l=0.0, beta_u=0.0, beta1=0.0, beta2=0.0; int flag; if (c1 == NULL) error_ptr_null("c1 in create_children"); if (c2 == NULL) error_ptr_null("c2 in create_children"); flag = 0; if ( p1 > p2) { temp = p1; p1 = p2; p2 = temp; flag = 1; } x_mean = ( p1 + p2) * 0.5; difference = p2 - p1; if(difference <= 1.0e-9) { *c1 = p1; *c2 = p2; } else { if (RIGID) { beta_l = 1.0 + 2.0*(p1-low)/(p2-p1); beta_u = 1.0 + 2.0*(high-p2)/(p2-p1); if (MINSCHEME) { if(beta_l <= beta_u) beta_u = beta_l; else beta_l = beta_u; u = rndreal(0.0,1.0); beta1 = beta2 = get_beta_rigid(u,beta_l); } else { u_l = rndreal(0.0,1.0); beta1 = get_beta_rigid(u_l,beta_l); u_u = rndreal(0.0,1.0); beta2 = get_beta_rigid(u_u,beta_u); } } else { u = rndreal(0.0,1.0); beta1 = beta2 = get_beta(u); } *c1 = x_mean - beta1 * 0.5 * difference; *c2 = x_mean + beta2 * 0.5 * difference; } if (flag == 1) { temp = *c1; *c1 = *c2; *c2 = temp; } if (*c1 < low) *c1 = low; if (*c2 > high) *c2 = high; if (*c1 < low || *c2 > high) { printf("Error!! p1 = %f, p2 = %f, c1 = %f, c2 = %f\n",p1,p2,*c1,*c2); exit(-1); } } /*==================================================================== cross over using strategy of 1 cross site with swapping . A random variable is chosen and crossed over. The variables on left side are passed as it is and those on right are swapped between the two parents. ====================================================================*/ cross_over_1_site(first,second,childno1,childno2) int first,second,childno1,childno2; { int j,k,site; if (flip(p_xover)) /* Cross over has to be done */ { no_xover++; if (BINGA) binary_xover(oldpop[first].chrom ,oldpop[second].chrom, newpop[childno1].chrom,newpop[childno2].chrom); site = rnd(0,num_var-1); for (k=0; k<=site-1; k++) /* Passing the values straight before the cross-site */ if (var_type[site]!=BIN) /* Only if variable type is not BINARY */ { newpop[childno1].x[k] = oldpop[first].x[k]; newpop[childno2].x[k] = oldpop[second].x[k]; } for (k=site+1; k<=num_var-1; k++) /* Swapping the values after the cross-site */ if (var_type[site]!=BIN) { newpop[childno2].x[k] = oldpop[first].x[k]; newpop[childno1].x[k] = oldpop[second].x[k]; } /* If variable != BINARY create children at the cross site variable */ if (var_type[site]!=BIN) create_children(oldpop[first].x[site], oldpop[second].x[site], &(newpop[childno1].x[site]), &(newpop[childno2].x[site]), x_lower[site],x_upper[site],var_RIGID[site]); } /* Cross over done */ else /* Passing x-values straight */ { if (BINGA) for (k=0; k<=chromsize; k++) { newpop[childno1].chrom[k] = oldpop[first].chrom[k]; newpop[childno2].chrom[k] = oldpop[second].chrom[k]; } for (k=0; k<=num_var-1; k++) { newpop[childno1].x[k] = oldpop[first].x[k]; newpop[childno2].x[k] = oldpop[second].x[k]; } } } /*==================================================================== CROSS - OVER USING strategy of uniform 50% variables For one variable problem, it is crossed over as usual. For multivariables, each variable is crossed over with a probability of 50 % , each time generating a new random beta. ====================================================================*/ cross_over_unif(first,second,childno1,childno2) int first,second,childno1,childno2; { float difference,x_mean,beta; int site,k; if (flip(p_xover)) /* Cross over has to be done */ { no_xover++; if (BINGA) binary_xover(oldpop[first].chrom,oldpop[second].chrom, newpop[childno1].chrom,newpop[childno2].chrom); for (site = 0; site<=num_var-1; site++) { if (var_type[site]!=BIN) if (flip(0.5) || (num_var==1)) { create_children(oldpop[first].x[site],oldpop[second].x[site], &(newpop[childno1].x[site]),&(newpop[childno2].x[site]), x_lower[site],x_upper[site],var_RIGID[site]); } else { newpop[childno1].x[site] = oldpop[first].x[site]; newpop[childno2].x[site] = oldpop[second].x[site]; } } /* for loop */ } /* Cross over done */ else /* Passing x-values straight */ { if (BINGA) for (k=0; k<=chromsize; k++) { newpop[childno1].chrom[k] = oldpop[first].chrom[k]; newpop[childno2].chrom[k] = oldpop[second].chrom[k]; } for (site=0; site<=num_var-1; site++) { newpop[childno1].x[site] = oldpop[first].x[site]; newpop[childno2].x[site] = oldpop[second].x[site]; } } } /*=================================================================== Calculates beta value for given random number u (from 0 to 1) If input random numbers (u) are uniformly distributed for a set of inputs, Binary Probability distribution simulation ====================================================================*/ float get_beta(u) float u; { float beta; if (1.0-u < EPSILON ) u = 1.0 - EPSILON; if ( u < 0.0) u = 0.0; if (u < 0.5) beta = pow(2.0*u,(1.0/(n_distribution_c+1.0))); else beta = pow( (0.5/(1.0-u)),(1.0/(n_distribution_c+1.0))); return (beta); } /***************************************************************** Calculates beta for rigid boundaries ****************************************************************/ float get_beta_rigid(u,betaa) float u, betaa; { float bet, beta; if (u <= 0.0+1.0e-9) beta = 0.0; else if (u >= 1.0-1.0e-9) beta = betaa; else { bet = 1.0/betaa; bet = 2.0 - pow(bet, (n_distribution_c + 1.0)); if (u <= 1.0/bet) beta = pow(bet * u, (1.0 / (n_distribution_c + 1.0))); else beta = pow(1.0/(2.0-u*bet), (1.0 / (n_distribution_c + 1.0))); } return beta; } /*================================================================== For given u value such that -1 <= u <= 1, this routine returns a value of delta from -1 to 1. Exact value of delta depends on specified n_distribution. This is called by mutation(). ====================================================================*/ float get_delta(u, delta_l, delta_u) float u, delta_l, delta_u; { float delta, aa; if (u >= 1.0-1.0e-9) delta = delta_u; else if (u <= 0.0+1.0e-9) delta = delta_l; else { if (u <= 0.5) { aa = 2.0*u + (1.0-2.0*u)*pow((1+delta_l), (n_distribution_m + 1.0)); delta = pow(aa, (1.0 / (n_distribution_m + 1.0))) - 1.0; } else { aa = 2.0*(1-u) + 2.0*(u-0.5)*pow((1-delta_u), (n_distribution_m + 1.0)); delta = 1.0 - pow(aa, (1.0 / (n_distribution_m + 1.0))); } } if (delta < -1.0 || delta > 1.0) { printf("Error in mutation!! delta = %f\n",delta); exit(-1); } return (delta); } /*================================================================== Binary mutation routine ( borrowed from sga.c ) ====================================================================*/ binmutation(child) unsigned *child; /* Mutate an allele w/ pmutation, count # of mutations */ { int j, k, stop; unsigned mask, temp = 1; if (BINGA == FALSE) return; if (child== NULL) error_ptr_null(" child in binmutation"); for(k = 0; k < chromsize; k++) { mask = 0; if(k == (chromsize-1)) stop = TotalChromLength - ((k-1)*UINTSIZE); else stop = UINTSIZE; for(j = 0; j < stop; j++) { if(flip(p_mutation)) { mask = mask|(temp<x[site]; distance = x_lower[site] - x; delta_l = distance / (x_upper[site] - x_lower[site]); if (delta_l < -1.0) delta_l = -1.0; distance = x_upper[site] - x; delta_u = distance / (x_upper[site] - x_lower[site]); if (delta_u > 1.0) delta_u = 1.0; if (MINSCHEME) { if (-1.0*delta_l < delta_u) delta_u = -1.0 * delta_l; else delta_l = -1.0 * delta_u; } } else /* flexible */ { delta_l = -1.0; delta_u = 1.0; } u = rndreal(0.0, 1.0); delta = get_delta(u, delta_l, delta_u) * (x_upper[site] - x_lower[site]); indiv->x[site] += delta; } } /* if flip() */ if (BINGA) binmutation(indiv->chrom); } /*==================================================================== Reporting the user-specified parameters : fp is the file pointer to output file. ====================================================================*/ initreport(fp) FILE *fp; { int k, iobj; if (fp == NULL) error_ptr_null(" File fp in initreport"); fprintf(fp,"\n============================================="); fprintf(fp,"\n INITIAL REPORT "); fprintf(fp,"\n============================================="); fprintf(fp,"\n"); fprintf(fp,"\n Number of objective functions : %2d",num_obj); for (iobj=0; iobj>1; } count++; } count=0; for(j=0;j=count;k--) { fprintf(fp,"%d",temp[k]); } count+=lchrom[j]; if (j!=num_var-1) fprintf(fp,"_"); } } /*==================================================================== Reporting the statistics of current population ( gen. no. 'num'): fp is file pointer to output file. ====================================================================*/ report(fp,num) FILE *fp; int num; { int k,j,iobj; char string[30]; if (fp == NULL) error_ptr_null(" file fp in report()"); /* ----------------------------------------- */ /* WRITING IN THE OUTPUT FILE FOR INSPECTION */ /* ----------------------------------------- */ fprintf(fp,"\n======================== Generation # : %3d =================================",num); if (BINGA) fprintf(fp,"\n No. Rank x Obj. Fun. Values (f1,f2, etc.) Parents String"); else fprintf(fp,"\n No. Rank x Obj. Fun. Values (f1,f2, etc. Parents "); fprintf(fp,"\n-----------------------------------------------------------------------------"); for (k=0; k<= pop_size-1; k++) { fprintf(fp,"\n %3d. %3d [%7.3f ] ",k+1,oldpop[k].front,oldpop[k].x[0]); for (j= 1; j<=num_var-1; j++) fprintf(fp,"\n [%7.3f ] ",oldpop[k].x[j]); for (j=0;j delta_dum) oldpop[i].dumfitness = min_dum-delta_dum; /* smaller than the smallest dummy fitness in previous front */ else adjust(front_index); } phenoshare(); minimum_dum(); front_index++ ; } /* --if else-- */ for(i=0; ifitness[iobj] - critter2->fitness[iobj])/square(afmax[iobj]-afmin[iobj]); } else if (PARAM) /* Sharing on parameter space */ { for (i=0;ix[i]-critter2->x[i]); /* /square(x_upper[i]-x_lower[i]); */ } dst = sqrt(dst); return(dst); } minimum_dum() { /* finding the minimum dummy fitness in the current front */ int i; min_dum = 1000000000.0 ; for(i=0; i= 55) { jrand = 1; advance_random(); } return((float) oldrand[jrand]); } int rnd(low, high) /* Pick a random integer between low and high */ int low,high; { int i; float randomperc(); if(low >= high) i = low; else { i = (randomperc() * (high - low + 1)) + low; if(i > high) i = high; } return(i); } float rndreal(lo ,hi) /* real random number between specified limits */ float lo, hi; { return((randomperc() * (hi - lo)) + lo); } warmup_random(random_seed) /* Get random off and running */ float random_seed; { int j1, ii; double new_random, prev_random; oldrand[54] = random_seed; new_random = 0.000000001; prev_random = random_seed; for(j1 = 1 ; j1 <= 54; j1++) { ii = (21*j1)%54; oldrand[ii] = new_random; new_random = prev_random-new_random; if(new_random<0.0) new_random = new_random + 1.0; prev_random = oldrand[ii]; } advance_random(); advance_random(); advance_random(); jrand = 0; } /*----------------------------------------------------------*/ /* Files for tournament selection : */ /* Source : sga.c (c) E.Goldberg */ /*----------------------------------------------------------*/ select_memory() { /* allocates auxiliary memory for stochastic remainder selection*/ unsigned nbytes; int j; choices = NULL; fraction = NULL; nbytes = pop_size*sizeof(int); if((choices = (int *) malloc(nbytes)) == NULL) nomemory(stderr,"choices"); nbytes = pop_size*sizeof(float); if((fraction = (float *) malloc(nbytes)) == NULL) nomemory(stderr,"fraction"); } select_free() { /* frees auxiliary memory for stochastic remainder selection */ choices = NULL; fraction = NULL; free(choices); free(fraction); } preselect() /* preselection for stochastic remainder method */ { int j, jassign, k; float expected; int flip(); if(dum_avg == 0) { for(j = 0; j < pop_size; j++) choices[j] = j; } else { j = 0; k = 0; /* Assign whole numbers */ do { expected = (float)((oldpop[j].dumfitness)/dum_avg); jassign = (int)expected; /* note that expected is automatically truncated */ fraction[j] = expected - (float)jassign; while(jassign > 0) { jassign--; choices[k] = j; k++; } j++; } while(j < pop_size); j = 0; /* Assign fractional parts */ while(k < pop_size) { if(j >= pop_size) j = 0; if(fraction[j] > 0.0) { /* A winner if true */ if(flip(fraction[j])) { choices[k] = j; fraction[j] = fraction[j] - 1.0; k++; } } j++; } } nremain = pop_size - 1; } int select() /* selection using remainder method */ { int jpick, slect; int rnd(); jpick = rnd(0, nremain); slect = choices[jpick]; choices[jpick] = choices[nremain]; nremain--; return(slect); } reset1() /* Name changed from reset because of clash with lib. function - RBA */ /* Shuffles the tourneylist at random */ { int i, rand1, rand2, temp_site; for(i=0; ix[0]; person->fitness[0] = square(a); person->fitness[1] = square((2.0-a)); nc = 0; #endif /* Second problem */ #ifdef f2 a=person->x[0]; person->fitness[0]=(a<=1.0) ? -a : ((a<=3) ? -2+a : ((a<=4) ? 4-a : -4+a)); person->fitness[1]=(a-5)*(a-5); nc = 0; #endif /* Third problem */ #ifdef f3 a1 = person->x[0]; a2 = person->x[1]; person->fitness[0]=(a1-2)*(a1-2)+(a2-1)*(a2-1)+2; person->fitness[1]=9*a1-(a2-1)*(a2-1); nc = 2; g[0] = -1.0*(a1*a1 + a2*a2 - 225.0); g[1] = -1.0*(a1 - 3.0*a2 + 10.0); #endif penalty = 0.0; for (i=0; ifitness[i] = person->fitness[i] + minmax[i] * penalty; } /********************** END OF FILE **************************/