// Michael S. Branicky, 04 February 2005 // compiles with g++ -lc -lm // // This code offered with no guarantees whatsoever. // #include #include #include #include #include #define TEST 1 #define ELITISM 0 int N=1000; // number of generations int k=1001; // number of individuals int EVALS; // number of fitness evaluations double pmut=0.1; // mutation probability // returns a uniformly distributed random double between 0.0 and 1.0 double myrand() { return drand48(); } // Use: Metropolis Algorithm for Maximization // // Source: Based on the code and explanation // of a routine for minimization found in // Press et al., _Numerical_Recipes_in_C_, // Cambridge Univ. Press, 1988. Page 351. // // Returns a boolean value on whether or not to // accept a reconfiguration which leads to a // change dE in the objective function E. // If dE>0, returns 1 (TRUE); if dE<=0, returns // 1 with probablity exp(dE/T), where T is a // temperature determined by the annealing schedule. // int metrop(double dE, double T) { double r=myrand(); #if TEST cout << exp(dE/T) << endl;; #endif return ((dE>0)||(r8) newrow-=8; for (int j=0; j<8; j++) { if (j==quotient) succ[j]=newrow; else succ[j]=init[j]; } } // copy each digit of an encoding with a prob. of error p (in place) void mutate(int enc[], double p) { for(int i=1; i<=8; i++) { double r=myrand(); if (r0.000001; T/=10.) { int i=metrop(-1.,T); // int j=metrop(1.,T); // cout << i << ", " << j << endl; cout << i << endl; } s[8]=0; s2[8]=0; // configs from R&N, p 112 int enc1[8]={5, 6, 7, 4, 5, 6, 7, 6}; int enc2[8]={8, 3, 7, 4, 2, 5, 1, 6}; // configs from R&N, p 117 int enc3[8]={2, 3, 7, 4, 8, 5, 5, 2}; int enc4[8]={3, 2, 7, 5, 2, 4, 1, 1}; int enc5[8]={2, 4, 4, 1, 5, 1, 2, 4}; int enc6[8]={3, 2, 5, 4, 3, 2, 1, 3}; // test fitness printenc(s,enc1); cout << "Fitness ( " << s << " ) = " << fitness(enc1) << "\n"; printenc(s,enc2); cout << "Fitness ( " << s << " ) = " << fitness(enc2) << "\n\n"; printenc(s,enc3); cout << "Fitness ( " << s << " ) = " << fitness(enc3) << "\n"; printenc(s,enc4); cout << "Fitness ( " << s << " ) = " << fitness(enc4) << "\n"; printenc(s,enc5); cout << "Fitness ( " << s << " ) = " << fitness(enc5) << "\n"; printenc(s,enc6); cout << "Fitness ( " << s << " ) = " << fitness(enc6) << "\n\n"; // test mutate mutate2(enc1,enc2,1.0); printenc(s,enc2); cout << "Random Encoding: " << s << "\n"; mutate2(enc1,enc2,0.5); printenc(s,enc2); cout << "Random Encoding: " << s << "\n"; mutate2(enc1,enc2,0.0); printenc(s,enc2); cout << "Random Encoding: " << s << "\n\n"; mutate(enc1,1.0); printenc(s,enc1); cout << "Random Encoding: " << s << "\n"; mutate(enc1,0.5); printenc(s,enc1); cout << "Random Encoding: " << s << "\n"; mutate(enc1,0.0); printenc(s,enc1); cout << "Random Encoding: " << s << "\n\n"; // test xover xover(enc3,enc4); printenc(s,enc3); printenc(s2,enc4); cout << "Offspring = " << s << ", " << s2 << endl; xover(enc5,enc6); printenc(s,enc5); printenc(s2,enc6); cout << "Offspring = " << s << ", " << s2 << endl; // test successor function int enc7[8]={1, 2, 3, 4, 5, 6, 7, 8}; int enc8[8]; int bestE=0; int bestSuccIndex; for (int i=1; i<=56; i++) { getsuccessor(enc7, i, enc8); int f=fitness(enc8); if ((f>bestE)||((f==bestE)&&(myrand()<0.1))) { bestE=f; bestSuccIndex=i; } printenc(s,enc8); cout << "Successor ( " << i << " ) = " << s << ", " << f << endl; } getsuccessor(enc7, bestSuccIndex, enc8); printenc(s,enc8); cout << "Best Successor ( " << bestSuccIndex << " ) = " << s << endl; // generate a random successor int RandomSuccIndex=(int) ceil(myrand()*56); // random int in {1, 2, ..., 56} getsuccessor(enc7, RandomSuccIndex, enc8); printenc(s,enc8); cout << "Successor ( " << RandomSuccIndex << " ) = " << s << endl; } int main() { int pop[k][8], newpop[k][8], popE[k]; int bestE, sumE, bestind; char s[9]; double cumprobs[k]; srand48((long) getpid()); s[8]=0; #if TEST test(); return(1); #endif EVALS=0; // start with a completely random population // for (int i=0; ibestE) { bestE=E; bestind=i; printenc(s,pop[bestind]); cout << "New Best ( " << s << " ): " << EVALS << ", " << bestE << "\n"; if (bestE==28) { cout << "Solution Found" << endl; return(1); } } } // compute selection probabilities cumprobs[0]=(double) popE[0]/sumE; // cout << cumprobs[0] << endl; for (int i=1; i=r) { index=j; break; } for (int j=0; j<8; j++) newpop[i][j]=pop[index][j]; } // crossover for (int i=ELITISM; i