Don't like ads? PRO users don't see any ads ;-)
Guest

Untitled

By: a guest on Jun 9th, 2012  |  syntax: None  |  size: 4.07 KB  |  hits: 22  |  expires: Never
download  |  raw  |  embed  |  report abuse  |  print
Text below is selected. Please press Ctrl+C to copy to your clipboard. (⌘+C on Mac)
  1. #include <cfloat>
  2. #include <cmath>
  3. #include <cstdlib>
  4. #include <ctime>
  5. #include <iostream>
  6. #include <vector>
  7.  
  8. #include "rmath.h"
  9.  
  10. using namespace std;
  11.  
  12. #define POPULATION 50
  13. #define CHROMOSOMES     2
  14. #define MUTATE_AMOUNT 0.9
  15. #define MUTATE_PROBABILITY 0.9
  16. #define RANGE_LOWER 10
  17. #define RANGE_UPPER 100
  18. #define THRESHOLD 0.01
  19.  
  20. #define VARIABLE_MUTATION
  21. #define MUTATION_EPOCH 4000
  22.  
  23. double fitness(vector<double> *data) {
  24.         return (1 + pow((
  25.                 pow(
  26.                         (data->at(0) - 0.2)
  27.                 ,2)
  28.                 +
  29.                 pow(
  30.                         (data->at(1) - 0.1)
  31.                 ,2)
  32.                 ),0.25) - cos(5 * 3.1415926535897932384626433832795 * sqrt(
  33.                 pow(
  34.                         (data->at(0) - 0.2)
  35.                 ,2)
  36.                 +
  37.                 pow(
  38.                         (data->at(1) - 0.1)
  39.                 ,2)
  40.                 )
  41.         ));
  42. }
  43.  
  44. class set {
  45.         public:
  46.                 vector<double> data;
  47.                 double eval;
  48.  
  49.                 //CONSTRUCTOR
  50.                 set(int n_data) {
  51.                         data.reserve(n_data);
  52.                         for (int i=0;i<n_data;i++) {
  53.                                 data.push_back(RANGE_LOWER + (random(RANGE_UPPER - RANGE_LOWER)));
  54.                         }
  55.                         eval = 0;
  56.                 }
  57.                 //DESTRUCTOR
  58.                 ~set() {}
  59.                 //FUNCTIONS
  60. };
  61. class population {
  62.         public:
  63.                 vector<set> sets;
  64.                 vector<set> sets2;
  65.                
  66.                 double mutation;
  67.                 double mutation_probability;
  68.  
  69.                 //CONSTRUCTOR
  70.                 population(int n_sets,int n_data, double mutation = 0.2, double mutation_probability = 0.05) {
  71.                         sets.reserve(n_sets);
  72.                         sets2.reserve(n_sets);
  73.                         this->mutation = mutation;
  74.                         this->mutation_probability = mutation_probability;
  75.                         for (int i=0;i<n_sets;i++) {
  76.                                 sets.push_back(set(n_data));
  77.                                 sets2.push_back(set(n_data));
  78.                         }
  79.                 }
  80.                 //DESTRUCTOR
  81.                 ~population() {}
  82.                 //FUNCTIONS
  83.                 void crossover(int a, int b, int c) {
  84.                         int count = sets2[c].data.size();
  85.                         int divider = count / 2;
  86.                         for (int i=0;i<divider;i++) {
  87.                                 sets2[c].data[i] = sets[a].data[i];
  88.                                 sets2[c].data[i+divider] = sets[b].data[i+divider];
  89.                         }
  90.                         if (count % 2 != 0) {
  91.                                 sets2[c].data.back() = sets[b].data.back();
  92.                         }
  93.                         return;
  94.                 }
  95.                 void mutate(int a) {
  96.                         for (unsigned int i=0;i<sets[a].data.size();i++) {
  97.                                 sets[a].data[i] += random(mutation);
  98.                         }
  99.                         return;
  100.                 }
  101.                 double evaluate() {
  102.                         double sum = 0;
  103.                         for (unsigned int i=0;i<sets.size();i++) {
  104.                                 sets[i].eval = fitness(&sets[i].data) + DBL_MIN;
  105.                                 sum += 1 / sets[i].eval;
  106.                         }
  107.                         return sum;
  108.                 }
  109.                 void evolve() {
  110.                         double sum = evaluate();
  111.                         for (unsigned int i=0;i<sets.size();i++) {
  112.                                 crossover(findparent(sum),findparent(sum),i);
  113.                                 if (urandom() < mutation_probability) {
  114.                                         mutate(i);
  115.                                 }
  116.                         }
  117.                         sets.swap(sets2);
  118.                         evaluate();
  119.                         return;
  120.                 }
  121.                 int findparent(double sum) {
  122.                         double rand = urandom(sum);
  123.                         sum = 0;
  124.                         for (unsigned int i=0;i<sets.size();i++) {
  125.                                 sum += 1 / sets[i].eval;
  126.                                 if (rand < sum) {
  127.                                         return i;
  128.                                 }
  129.                         }
  130.                         return (int)(urandom(sets.size()-1));
  131.                 }
  132.                 int findbest() {
  133.                         int index = 0;
  134.                         double min = sets[0].eval;
  135.                         for (unsigned int i=1;i<sets.size();i++) {
  136.                                 if (sets[i].eval < min) {
  137.                                         min = sets[i].eval;
  138.                                         index = i;
  139.                                 }
  140.                         }
  141.                         return index;
  142.                 }
  143.                 double average() {
  144.                         double sum = 0;
  145.                         for (unsigned int i=0;i<sets.size();i++) {
  146.                                 sum += sets[i].eval;
  147.                         }
  148.                         return (sum/sets.size());
  149.                 }
  150. };
  151.  
  152. void print(population *evo, int iterations) {
  153.         cout << "\nFitness (Average): " << evo->average();
  154.         cout << "\nFitness (Elite): " << evo->sets[evo->findbest()].eval;
  155.         cout << "\nChromosomes (Elite) : [";
  156.         for (int i=0;i<CHROMOSOMES;i++) {
  157.                  cout << " " << evo->sets[evo->findbest()].data[i] << ",";
  158.         }
  159.         cout << "]";
  160.         cout << "\nIterations : " << iterations;
  161.         return;
  162. };
  163.  
  164. int main() {
  165.         srand ((unsigned)time(NULL));
  166.  
  167.         /* INIT SETTINGS */
  168.         population evo(POPULATION,CHROMOSOMES,MUTATE_AMOUNT,MUTATE_PROBABILITY);
  169.  
  170.         /* TRAIN UNTIL THRESHOLD */
  171.         evo.evaluate();
  172.  
  173.         int i=0;
  174.         while (evo.sets[evo.findbest()].eval > THRESHOLD) {
  175.                 evo.evolve();
  176.                 i++;
  177.                 #ifdef VARIABLE_MUTATION
  178.                         if (i % MUTATION_EPOCH == 0) {
  179.                                 print(&evo,i);
  180.                                 evo.mutation = urandom(evo.average());
  181.                                 evo.mutation_probability = urandom(evo.average());
  182.                         }
  183.                 #endif
  184.         }
  185.  
  186.         /* POST RESULTS */
  187.         cout << "\n ---- RESULTS ----";
  188.         print(&evo,i);
  189.         cout << "\n";
  190.         system("pause");
  191.         return 0;
  192. }