/* Function opti (vec, gen, pop, n_vars, merit, v0, v_del) Subroutines to minimize a merit function. Code adapted from Dr. Dobbs Journal, April 1997 with modifications Article: Differential Evolution by Kenneth Price and Rainer Storn Source Code: page 78 Added end_flag so merit function can terminate search. -- DCS Note: To call opti from C use: opti_(vec, gen, pop, n_vars, merit, v0, v_del) Input: gen -- Integer: Number of "generations" to let solutions evolve. pop -- Integer: Number of "strands" (solutions) to use. n_vars -- Integer: Number of "genes" (variables). v0(n_vars) -- Real(8): Initial strand guess. v_del(n_vars) -- Real(8): Typical variation of the genes. Output: vec(n_vars) -- Real(8): Optimum solution. opti -- Real(8): Figure of merit of the optimum solution. The Merit function prototype is: function merit (vec, end_flag) result (this_merit) real(8) vec(*) ! Input: trial strand integer end_flag ! Output: Set = 1 to terminate optimization. real(8) this_merit ! Output: Merit value corresponting to vec. ... end function */ //###################################################################### //######## START OPTI.H #################################### //###################################################################### // Use genetic algorithm to optimize functions #ifndef _OPTI_H_ #define _OPTI_H_ #include #include #include // #elif defined(CESR_WINCVF) // #include // #include // #include // #endif using namespace std; typedef double (*EvalFunc) (double *, int&); inline int RandInt(int limit) {return rand()%limit;} inline double UniRand() {return double(rand())/RAND_MAX;} class Strand; class GenePool; class Opti; class Mini; class Maxi; class Strand{ public: double *gene; protected: int length; double cost; public: Strand() : gene(0), length(0) {} Strand(int len) : length(len) {gene = new double[length];} Strand(Strand &s0) : length(s0.length){ gene = new double[length]; this->operator=(s0); } Strand(double *v, int len) : length(len) { gene = new double[length]; for(int i=0; i0) delete [] gene; length = len; gene = new double[length]; } double& Cost() {return cost;} void Init(double delta){ for(int i=0; i0) for(int i=0; i0) for(int i=0; i0) for(int i=0; i0) for(int i=0; i0){ for(int i=1; i strand[index].cost; } virtual int Better(int ind1, int ind2){ return strand[ind1].cost > strand[ind2].cost; } }; double MiniVec(double solution[], const int& gen, const int& pop, const int& len, EvalFunc func, double v0[], const double& delta); double MiniOff(double solution[], const int& gen, const int& pop, const int& len, EvalFunc func, const double& offset, const double& delta); extern "C" double minidel(double solution[], const int& gen, const int& pop, const int& len, EvalFunc func, double v0[], double vdel[]); double MaxiVec(double solution[], const int& gen, const int& pop, const int& len, EvalFunc func, double v0[], const double& delta); double MaxiDel(double solution[], const int& gen, const int& pop, const int& len, EvalFunc func, double v0[], double vdel[]); #endif //###################################################################### //######## END OPTI.H #################################### //###################################################################### #if defined(CESR_WINCVF) extern "C" void ERR_EXIT(); #else extern "C" void err_exit_(); #endif Strand& Opti::Optimize(){ int a, b, c, j, end_flag; const double CR = 0.8, frac = 1.4; double rfrac, flex_cr; flex_cr = CR * 10.0/length; if ( 0.1 > flex_cr ) flex_cr = 0.1; if ( CR < flex_cr ) flex_cr = CR; for(int i=0; i