/************************************************************ This is the header file for df1.c This file contains the global variables and definitions for functions df1, df1_chg_H, df1_chg_R, df1_chg_C, and def1_init. This file allows you to set the initialization values that define the dynamic behavior of test function generated by the df1 Test Function Generator. Details regarding this test function generator can be found in "A Test Problem Generator for Non-Stationary Environments" by Ronald Morrison and Kenneth De Jong in the Proceeding of the Congress on Evolutionary Computation (CEC-99). The functions themselves are located in df1.c Permission is hereby granted to copy all or any part of this program for free distribution. File: df1.h version 1.4 June 25, 2000 Modified to change "bounce" characteristics at the end of the range of the changes. Direct comments and suggestions to: Ronald Morrison at ronald.morrison@mitretek.org *************************************************************/ #include #define max(a, b) (a > b) ? a : b /* Set up for a maximum of 100 peaks and 10 dimensions */ #define MAX_PEAKS 100 #define MAX_DIM 10 /* Declare the actual number of peaks and dimensions for this problem. Put YOUR VALUES here! */ #define NUMBER_PEAKS 5 #define NUMBER_DIM 2 /* Declare some variables. These variables are all randomized in function df1_init. If you prefer specific values for some or all of these peaks (for example, if you want one high peak of a specific value) you may set any values you like at the end of the randomization process in appropriate section of df_init.*/ double H[NUMBER_PEAKS]; /* H refers to the height of the peaks */ double R[NUMBER_PEAKS]; /* R controls the slope of the peaks It is the radius value of the right circular cones.*/ double x[NUMBER_PEAKS][NUMBER_DIM]; /* These are the spatial coordinates */ int IUPH[NUMBER_PEAKS]; int IUPR[NUMBER_PEAKS]; int IUPC[NUMBER_PEAKS][NUMBER_DIM]; /* The following variables establish the static landscape for the test problem and establish the dynamic behavior of the environment. Default values are provided, but the values in this file may be changed to generate a wide variety of dynamic behaviors, from very simple, to very complex. */ /* First we establish the static environment that we will apply dynamics to. The static environment consists of the maximum of a field of right circular k-dimensional cones, where the fitness is defined, for example in 2 dimensions as: f(X,Y) = max(over i=1 to N) (Hi - Ri*(sqrt((X-Xi)^2 + (Y-Yi^2)))) The height of the cones range from Hbase to (Hbase + Hrange). The radii of the cones range from Rbase to (Rbse + Rrange). */ int NoPeaks = NUMBER_PEAKS; /* Actual number of peaks */ int NoDim = NUMBER_DIM; /* Actual number of dimensions */ double Hbase = 3; /* min height */ double Hrange = 3; double Hmax; /* This always equals Hbase + Hrange, and is set in df1_init */ double Hminpct; /* This always equals Hbase/Hmax, and is set in df1_init */ double Rbase = 2; /* min r value */ double Rrange = 5; double Rmax; /* This always equals Rbase + Rrange, and is set in df1_init */ double Rminpct; /* This ways equals Rbase/Rmax, and is set in df1_init */ /* The next section sets the variables that control the dynamics of the problem. The dynamics are controlled by the Logistics function given by: Y(t) = A*Y(t-1)*(1-Y(t-1)) where Y(t) is Y at time t, and Y(t-1) is Y at time t-1. The logistics function allows a wide range of dynamic performance by a simple change of the value of A, from simple. constant step sizes, to step sizes that alternate between two values, to step sizes that rotate through several values, to completely chaotic step size selection. It is recommended that you plot the logistics function Y values vs. A values (1 #include int df1_flip (void); /* prototype for df1_flip */ double df1 (double coord[NUMBER_DIM]); /* prototype for df1 */ void df1_init (); /* prototype for df1_init */ void df1_chg_R (int NoToChg, int Peaks[NUMBER_PEAKS]); /* prototype for df1_chg_R */ void df1_chg_H (int NoToChg, int Peaks[NUMBER_PEAKS]); /* prototype for df1_chg_H */ void df1_chg_c (int CoordNo, int NoToChg, int Peaks[NUMBER_PEAKS]); /* prototype for df1_chg_c */ /********************************************************** * df1 (coord) evlauates fitness function at the location specified by the n-dimensional vector coord ************************************************************/ double df1 (double coord[NUMBER_DIM]) { double z, zi, sum; int i, j; sum = 0.0; for (i = 0; i < NoDim; i++) { sum += (x[0][i] - coord[i]) * (x[0][i] - coord[i]); } z = H[0] - R[0] * sqrt (sum); if (NoPeaks > 1) { for (j = 1; j < NoPeaks; j++) { sum = 0.0; for (i = 0; i < NoDim; i++) { sum += (x[j][i] - coord[i]) * (x[j][i] - coord[i]); } zi = H[j] - R[j] * sqrt (sum); z = max (z, zi); } } return z; } /* end of function df1(coord[NUMBER_DIM]) */ /**************************************************/ /* Start of function df1_init This initializes the variables for df1 *****************************************************/ void df1_init () /* This uses the values set in df1.h for NoPeaks, NoDim, Ah, Ar, and Ac[NUMBER_DIM] */ { int i, j; srand (time (0)); /* initalize random number generator */ /* Work past the inital transients in the step values */ /* This changes the Hstep value from the initialized value to the value(s) driven by the Ah value. */ for (j = 0; j < 100; j++) Hstep = Ah * Hstep * (1.0 - Hstep); /* This changes the Rstep value from the initialized value to the value(s) driven by the Ar value. */ for (j = 0; j < 100; j++) Rstep = Ar * Rstep * (1.0 - Rstep); /* This changes the cstep[] value from the initialized value to the value(s) driven by the Ac[] values. */ for (i = 0; i < NoDim; i++) { for (j = 0; j < 100; j++) cstep[i] = Ac[i] * cstep[i] * (1.0 - cstep[i]); } /* This section randomizes the cone values. To set specific cone intialtion values, do so after these loops */ for (i = 0; i < NoPeaks; i++) { R[i] = Rbase + Rrange * (float) rand () / (float) RAND_MAX; H[i] = Hbase + Hrange * (float) rand () / (float) RAND_MAX; for (j = 0; j < NoDim; j++) x[i][j] = 2 * (float) rand () / (float) RAND_MAX - 1.0; } /* Include following lines setting R[0] = H[0] = 0.0 */ /* if a non-negative landscape is wanted. */ /* R[0] = 0.0; H[0] = 0.0; */ /*If you have any specific cones that you want in the landscape, put specific values of R[i], H[i] and x[i][j] here to create the desired landscape. */ /* compute other initalization values */ Rmax = Rbase + Rrange; Rminpct = Rbase / Rmax; Hmax = Hbase + Hrange; Hminpct = Hbase / Hmax; /* This section randomly sets whether the dyanmic varaible start to move by increasing or decreasing. This is done through a set of up/down flags. These are randomly set. The user can reset any of them to any desired specific values after the loop. */ for (i = 0; i < NoPeaks; i++) { IUPH[i] = df1_flip (); IUPR[i] = df1_flip (); for (j = 0; j < NoDim; j++) { IUPC[i][j] = df1_flip (); } } /* put specific values of IUPH[i], IUPR[i], and IUPC[i][j] here to */ /* to set specific inital values for the up/down flags */ } /* end of function df1_init **************************************************************/ /* This is the start of the routines to modify the landscape. df1_chg_R modifies R values df1_chg_H modifies H values df1_chg_c modifies coordinate values All functions take an array wich specifies which peaks to modify. Peaks are numbered from 0 to NoPeaks -1. No tests are done to see if the values in array Peaks are valid. *************************************************************/ void df1_chg_R (int NoToChg, int Peaks[NUMBER_PEAKS]) /* NoToChg is the number of peaks to change the R value of. Peaks is an array of peak numbers to change. */ { int j; double Rpct, Rtemp; if (NoToChg > 0) { for (j = 0; j < NoToChg ; j++) { Rpct = R[Peaks[j]] / Rmax; Rstep = Ar * Rstep * ((double) (1.0) - Rstep); Rtemp = Rstep * Rstepscale; if (IUPR[Peaks[j]] == 1) { Rpct = Rpct + Rtemp; if (Rpct > 1.0) { IUPR[Peaks[j]] = 0; Rpct = 1.0 - (Rpct - 1.0); } } else { Rpct = Rpct - Rtemp; if (Rpct < Rminpct) { IUPR[Peaks[j]] = 1; if (Rpct >= 0) { Rpct = Rminpct + (Rminpct - Rpct); } else{ Rpct = Rminpct - Rpct; } } } R[Peaks[j]] = Rpct * Rmax; } } } /* end of function df1_chg_R */ /************************************************** This section changes the peak heights **************************************************/ void df1_chg_H (int NoToChg, int Peaks[NUMBER_PEAKS]) /* changes peaks H value (height) */ /* same arguments as df1_chg-R */ { int j; double Hpct, Htemp; if (NoToChg > 0) { for (j = 0; j < NoToChg; j++) { Hpct = H[Peaks[j]] / Hmax; Hstep = Ah * Hstep * ((double) 1.0 - Hstep); Htemp = Hstep * Hstepscale; if (IUPH[Peaks[j]] == 1) { Hpct = Hpct + Htemp; if (Hpct > 1.0) { IUPH[Peaks[j]] = 0; Hpct = 1.0 - (Hpct - 1.0); } } else { Hpct = Hpct - Htemp; if (Hpct < Hminpct) { IUPH[Peaks[j]] = 1; if (Hpct >= 0) { Hpct = Hminpct + (Hminpct - Hpct); } else { Hpct = Hminpct - Hpct; } } } H[Peaks[j]] = Hpct * Hmax; } } /* end of function df1_chg_H ************************************************************8*/ void df1_chg_c (int CoordNo, int NoToChg, int Peaks[NUMBER_PEAKS]) /* This change the peak location. CoordNo is the number of which dimension to change CoordNo ranges from 0 to DimNo-1 */ { int j; double xpct, xtemp; if (NoToChg > 0) { for (j = 0; j< NoToChg; j++) { xpct = (x[Peaks[j]][CoordNo] + offset[CoordNo]) / scale[CoordNo]; cstep[CoordNo] = Ac[CoordNo] * cstep[CoordNo] * ((double) 1.0 - cstep[CoordNo]); xtemp = cstep[CoordNo] * cstepscale[CoordNo]; if (IUPC[Peaks[j]][CoordNo] == 1) { xpct = xpct + xtemp; if (xpct > 1.0) { IUPC[Peaks[j]][CoordNo] = 0; xpct = 1.0 - (xpct - 1.0); } } else { xpct = xpct - xtemp; if (xpct < 0.0) { IUPC[Peaks[j]][CoordNo] = 1; xpct = -xpct; } } x[Peaks[j]][CoordNo] = (xpct * scale[CoordNo]) - offset[CoordNo]; } } } /* end of function df1_chg_c **********************************************************/ /* function df1_flip() */ /* function returns a 1 or 0 depending upon random() */ int df1_flip () { int i; i = 0; if (rand () > RAND_MAX / 2) i = 1; return i; } /* end of funtion df1_flip() */ ========================CUT HERE ========================== /* This little demo program steps through the static fitness landscape generated by df1, through the interval 0.01 to 0.99 in 0.01 increments, generatess the fitness values found, and sends them to a logfile It then changes each parameter one time and send the results to the log file again*/ #include double df1(double A[]); /* prototype of evaluator */ void df1_init(); /* prototype of initializer*/ void df1_chg_R (int NoToChg, int Peaks[5]); /* prototype for df1_chg_R */ void df1_chg_H (int NoToChg, int Peaks[5]); /* prototype for df1_chg_H */ void df1_chg_c (int CoordNo, int NoToChg, int Peaks[5]); /* prototype for df1_chg_c */ double mycoord[2]; double f; double ix = .01; double iy = .01; int ChangedPeaks[5] = {0,1,2,3,4}; int NumOfChangedPeaks = 5; int Dimension1 = 0; int Dimension2 = 1; FILE *logfp; void main () { df1_init(); logfp = fopen("logfile", "a"); /* send the values to the logfile */ for (ix = .01; ix <= 1.0; ix=ix+.01) { for (iy = .01; iy <= 1.0; iy=iy+.01) { mycoord[0] = ix; mycoord[1] = iy; f = df1(mycoord); fprintf(logfp, "X,Y,Fitness %f %f %f \n", mycoord[0],mycoord[1],f); } } /* Change the height */ df1_chg_H(NumOfChangedPeaks, ChangedPeaks); /* Change the slope */ df1_chg_R(NumOfChangedPeaks, ChangedPeaks); /* Change the x location */ df1_chg_c(Dimension1,NumOfChangedPeaks, ChangedPeaks); /* Change the y location */ df1_chg_c(Dimension2,NumOfChangedPeaks, ChangedPeaks); /* send the new values to the logfile */ for (ix = .01; ix <= 1.0; ix=ix+.01) { for (iy = .01; iy <= 1.0; iy=iy+.01) { mycoord[0] = ix; mycoord[1] = iy; f = df1(mycoord); fprintf(logfp, "X,Y,Fitness %f %f %f \n", mycoord[0],mycoord[1],f); } } if (logfp) fclose(logfp); }