COPASI API  4.16.103
CGA.cpp
Go to the documentation of this file.
1 // Begin CVS Header
2 // $Source: /Volumes/Home/Users/shoops/cvs/copasi_dev/copasi/optimization/CGA.cpp,v $
3 // $Revision: 1.28 $
4 // $Name: $
5 // $Author: shoops $
6 // $Date: 2012/04/23 21:11:20 $
7 // End CVS Header
8 
9 // Copyright (C) 2012 by Pedro Mendes, Virginia Tech Intellectual
10 // Properties, Inc., University of Heidelberg, and The University
11 // of Manchester.
12 // All rights reserved.
13 
14 // Copyright (C) 2008 by Pedro Mendes, Virginia Tech Intellectual
15 // Properties, Inc., EML Research, gGmbH, University of Heidelberg,
16 // and The University of Manchester.
17 // All rights reserved.
18 
19 // Copyright (C) 2001 - 2007 by Pedro Mendes, Virginia Tech Intellectual
20 // Properties, Inc. and EML Research, gGmbH.
21 // All rights reserved.
22 
23 /**
24  * File name: CGA.cpp
25  *
26  * Programmer: Yongqun He
27  * Contact email: yohe@vt.edu
28  * Purpose: This is the implementation (.cpp file) of the CGA class.
29  * It is to implement the genetic algorithm for COPASI optimization
30  * Note: Modified from Gepasi and Dingjun Chen's implementation
31  */
32 
33 #include <iostream>
34 #include <fstream>
35 #include <sys/timeb.h>
36 #include <time.h>
37 
38 #include "copasi.h"
39 #include "CGA.h"
40 
41 //default constructor
43 {
44  // this->super();
45 
46  mPopSize = 0;
47  mGener = 0;
48  mParamNum = 0;
49 
50  mCrp = NULL;
51  mMidX = NULL;
52  mIndV = NULL;
53  mCandX = NULL;
54  mWins = NULL;
55 
56  setMethodParameterNumber(3);
57  std::vector <COptAlgorithmParameter> & AlgorithmParameters = getMethodParameters();
58 
59  AlgorithmParameters.resize(3);
60  //#1:
61  AlgorithmParameters[0].setName("Population Size");
62  AlgorithmParameters[0].setValue(100); // Set a default value
63  //#2:
64  AlgorithmParameters[1].setName("Generation Number");
65  AlgorithmParameters[1].setValue(100.0); // Set a default value
66  //#3:
67  AlgorithmParameters[2].setName("Mutation Variance");
68  AlgorithmParameters[2].setValue(0.1); // Set a default value
69 
70  //initialize();
71 }
72 
73 // initialize function
75 {
76  unsigned int i;
77 
78  mMin = *(mRealProblem.getParameterMin());
79  mMax = *(mRealProblem.getParameterMax());
80  mParamNum = mRealProblem.getParameterNum();
81 
82  std::vector <COptAlgorithmParameter> &AlgmParams = getMethodParameters();
83 
84  for (i = 0; i < getMethodParameterNumber(); i++)
85  {
86  if (AlgmParams[i].getName() == "Population Size")
87  mPopSize = unsigned(AlgmParams[i].getValue());
88  else if (AlgmParams[i].getName() == "Generation Number")
89  mGener = unsigned(AlgmParams[i].getValue());
90  else if (AlgmParams[i].getName() == "Mutation Variance")
91  mMutVar = AlgmParams[i].getValue();
92  }
93 
94  mCandX = new double[2 * mPopSize];
95  // create array for tournament
96  mWins = new unsigned int[2 * mPopSize];
97  // create array for crossover points
98  mCrp = new unsigned int[mParamNum];
99  // create array for shuffling the population
100  mMidX = new unsigned int[mPopSize];
101  // create the population array
102  mIndV = new double * [2 * mPopSize];
103  // create the individuals
104 
105  for (i = 0; i < 2*mPopSize; i++)
106  {
107  mIndV[i] = new double[mParamNum];
108  }
109 
111 
112  return 0;
113 }
114 
115 // initialize the first generation
117 {
118  int i;
119 
120  for (i = 0; i < mParamNum; i++)
121  mIndV[0][i] = 1.1 + dr250();
122 
123  try
124  {
125  // calculate the fitness
126  mCandX[0] = evaluate(0);
127  }
128  catch (unsigned int e)
129  {
131  }
132 
133  // the others are randomly generated
134  creation(1, mPopSize);
135 
136  mBest = fittest();
137 }
138 
139 // Copy constructor
140 CGA::CGA(const CGA& source) : COptAlgorithm(source)
141 {
142  mGener = source.mGener;
143  mPopSize = source.mPopSize;
144  mCrossNum = source.mCrossNum;
145  mMin = source.mMin;
146  mMax = source.mMax;
147  mMutVar = source.mMutVar;
148  mMutProb = source.mMutProb;
149  mBest = source.mBest;
150  mParamNum = source.mParamNum;
151  mIndV = source.mIndV;
152  mCandX = source.mCandX;
153  mCrp = source.mCrp;
154  mMidX = source.mMidX;
155  mWins = source.mWins;
156 }
157 
158 // Object assignment overloading
159 CGA& CGA::operator=(const CGA & source)
160 {
161  cleanup();
162 
163  if (this != &source)
164  {
165  mGener = source.mGener;
166  mPopSize = source.mPopSize;
167  mCrossNum = source.mCrossNum;
168  mMin = source.mMin;
169  mMax = source.mMax;
170  mMutVar = source.mMutVar;
171  mMutProb = source.mMutProb;
172  mBest = source.mBest;
173  mParamNum = source.mParamNum;
174  mIndV = source.mIndV;
175  mCandX = source.mCandX;
176  mCrp = source.mCrp;
177  mMidX = source.mMidX;
178  mWins = source.mWins;
179  }
180 
181  return *this;
182 }
183 
184 // clean up
186 {return 0;}
187 
188 //destructor
190 {
191  delete mIndV;
192  delete mMidX;
193  delete mCrp;
194  delete mWins;
195  delete mCandX;
196 }
197 
198 //implementation of mutation functions
199 
200 // set real problem
202 {
203  mRealProblem = aProb;
204 }
205 
206 //set parameter
207 void CGA::setParamNum(int num)
208 {
209  mParamNum = num;
210 }
211 
212 //set population size
213 void CGA::setPopSize(int num)
214 {
215  mPopSize = num;
216 }
217 
218 //set generation
219 void CGA::setGeneration(int num)
220 {
221  mGener = num;
222 }
223 
224 //set the mutation variance
225 void CGA::setMutVar(double num)
226 {
227  mMutVar = num;
228 }
229 
230 //set the minimum
231 void CGA::setMin(double num)
232 {
233  mMin = num;
234 }
235 
236 //set maximum
237 void CGA::setMax(double num)
238 {
239  mMax = num;
240 }
241 
242 //set array of individuals w/ candidate values for the parameters
243 void CGA::setIndv(int i, int j, double num)
244 {
245  mIndV[i][j] = num;
246 }
247 
248 //set array of values of objective function for individuals
249 void CGA::setCandx(int i, double num)
250 {
251  mCandX[i] = num;
252 }
253 
254 //set the best result
255 void CGA::setBest(unsigned int num)
256 {
257  mBest = num;
258 }
259 
260 //implementation of access functions
261 
262 //get parameter number
264 {
265  return mParamNum;
266 }
267 
268 //get the best candidate
270 {
271  return mCandX[mBest];
272 }
273 
274 // get generation
275 unsigned int CGA::getGeneration()
276 {
277  return mGener;
278 }
279 
280 // get population size
282 {
283  return mPopSize;
284 }
285 
286 // init optimization random numbers
288 {
289  struct timeb init_time;
290  ftime(&init_time);
291  r250_init(init_time.millitm);
292  return 0;
293 }
294 
295 // evaluate the fitness of one individual
296 double CGA::evaluate(unsigned int i)
297 {
298  int j;
299  double tmp;
300 
301  for (j = 0; j < mParamNum; j++)
302  {
303  tmp = mIndV[i][j];
304  mRealProblem.setParameter(j, tmp);
305  }
306 
307  //for debugging purpose
308  //std::cout << "Debug: mRealProblem.getParameterNum() is:" << mRealProblem.getParameterNum() << std::endl;
309 
311 
312  return mRealProblem.getBestValue();
313 }
314 
315 #ifdef XXXX
316 
317 // evaluate the fitness of one individual
318 double CGA::evaluate(unsigned int i)
319 {
320  int j;
321  //bool outside_range = FALSE;
322  double fitness;
323  double fitness0;
324  //double tmp;
325 
326  //YOHE: this is the mathematics function used only for testing purpose
327  // evaluate the fitness
328 
329  try
330  {
331  fitness0 = 0;
332 
333  for (j = 0; j < mParamNum; j++)
334  {
335  fitness = fitness0 + pow(mIndV[i][j], 4.0) - 16.0 * pow(mIndV[i][j], 2.0) + 5.0 * mIndV[i][j];
336  fitness0 = fitness;
337  }
338 
339  fitness = fitness0 / 2.0;
340  }
341  catch (unsigned int e)
342  {
344  }
345 
346  return fitness;
347 }
348 
349 #endif // XXXX
350 
351 // copy individual o to position d
352 void CGA::copy(unsigned int o, unsigned int d)
353 {
354  int i;
355 
356  for (i = 0; i < mParamNum; i++)
357  mIndV[d][i] = mIndV[o][i];
358 
359  mCandX[d] = mCandX[o];
360 }
361 
362 // swap individuals o and d
363 void CGA::swap(unsigned int o, unsigned int d)
364 {
365  int i;
366  double tmp;
367 
368  for (i = 0; i < mParamNum; i++)
369  {
370  tmp = mIndV[d][i];
371  mIndV[d][i] = mIndV[o][i];
372  mIndV[o][i] = tmp;
373  }
374 
375  tmp = mCandX[d];
376  mCandX[d] = mCandX[o];
377  mCandX[o] = tmp;
378  i = mWins[d];
379  mWins[d] = mWins[o];
380  mWins[o] = i;
381 }
382 
383 //mutate one individual
384 void CGA::mutate(unsigned int i)
385 {
386  int j;
387  //double mMin, mMax, mut;
388  double mut;
389  // mutate the parameters
390 
391  for (j = 0; j < mParamNum; j++)
392  {
393  //YOHE: test
394  // double indtmp = mIndV[i][j];
395  // double rnorm = rnormal01();
396  // mut = indtmp * (1 + mMutVar * rnorm);
397 
398  // calculate the mutatated parameter
399  mut = mIndV[i][j] * (1 + mMutVar * rnormal01());
400 
401  // force it to be within the bounds
402 
403  if (mut <= mMin)
404  mut = mMin + std::numeric_limits< C_FLOAT64 >::epsilon();
405  else
406 
407  {
408  if (mut < mMin)
409  mut = mMin;
410  }
411 
412  if (mut >= mMax)
413  mut = mMax - std::numeric_limits< C_FLOAT64 >::epsilon();
414  else
415 
416  {
417  if (mut > mMax)
418  mut = mMax;
419  }
420 
421  // store it
422  mIndV[i][j] = mut;
423  }
424 
425  // evaluate the fitness
426  mCandX[i] = evaluate(i);
427 }
428 
429 // process crossover
430 void CGA::crossover(unsigned int p1, unsigned int p2, unsigned int c1, unsigned int c2)
431 {
432  int i, j, s, e;
433  unsigned int pp1, pp2, tmp, l;
434 
435  try
436  {
437  if (mParamNum > 1)
438  {
439  // get a random number of crossover points, always less than half the number of genes
440  mCrossNum = r250n((unsigned int) mParamNum / 2);
441  }
442  else
443  mCrossNum = 0;
444 
445  // if less than 0 just copy parent to child
446  if (mCrossNum == 0)
447  {
448  for (j = 0; j < mParamNum; j++)
449  {
450  mIndV[c1][j] = mIndV[p1][j];
451  mIndV[c2][j] = mIndV[p2][j];
452  }
453 
454  return;
455  }
456 
457  // chose first point
458  mCrp[0] = 1 + r250n(mParamNum - mCrossNum);
459 
460  // chose the others
461  for (i = 1; i < mCrossNum; i++)
462  {
463  l = mParamNum - mCrossNum + i - 1 - mCrp[i - 1];
464  mCrp[i] = 1 + mCrp[i - 1] + (l == 0 ? 0 : r250n(l));
465  }
466 
467  // copy segments
468  pp1 = p2;
469 
470  pp2 = p1;
471 
472  for (i = 0; i <= mCrossNum; i++)
473  {
474  // swap the indexes
475  tmp = pp1;
476  pp1 = pp2;
477  pp2 = tmp;
478 
479  if (i == 0)
480  s = 0;
481  else
482  s = mCrp[i - 1];
483 
484  if (i == mCrossNum)
485  e = mParamNum;
486  else
487  e = mCrp[i];
488 
489  for (j = s; j < e; j++)
490  {
491  mIndV[c1][j] = mIndV[pp1][j];
492  mIndV[c2][j] = mIndV[pp2][j];
493  }
494  }
495  }
496  catch (unsigned int e)
497  {}}
498 
499 // shuffle data
500 void CGA::shuffle(void)
501 {
502  unsigned int i, a, b, tmp;
503 
504  for (i = 0; i < mPopSize; i++)
505  mMidX[i] = i;
506 
507  for (i = 0; i < mPopSize / 2; i++)
508  {
509  a = r250n(mPopSize);
510  b = r250n(mPopSize);
511  tmp = mMidX[a];
512  mMidX[a] = mMidX[b];
513  mMidX[b] = tmp;
514  }
515 }
516 
517 // replicate the individuals w/ crossover
518 void CGA::replicate(void)
519 {
520  unsigned int i;
521 
522  // generate a random order for the parents
523  shuffle();
524  // reproduce in consecutive pairs
525 
526  for (i = 0; i < mPopSize / 2; i++)
527  crossover(mMidX[i*2], mMidX[i*2 + 1], mPopSize + i*2, mPopSize + i*2 + 1);
528 
529  // check if there is one left over and just copy it
530  if (mPopSize % 2 > 0)
531  copy(mPopSize - 1, 2*mPopSize - 1);
532 
533  // mutate the offspring
534  for (i = 0; i < mPopSize; i++)
535  mutate(mPopSize + i);
536 }
537 
538 // select mPopSize individuals
539 void CGA::select(int method)
540 {
541  unsigned int i, j, nopp, opp;
542 
543  switch (method)
544  {
545  case 1: // parent-offspring competition
546 
547  for (i = mPopSize; i < 2*mPopSize; i++)
548  {
549  // if offspring is fitter keep it
550 
551  if (mCandX[i] < mCandX[i - mPopSize])
552  copy(i, i - mPopSize);
553  }
554 
555  break;
556 
557  case 2: // tournament competition
558  // compete with 20% of the population
559  nopp = mPopSize / 5;
560  // but at least one
561 
562  if (nopp < 1)
563  nopp = 1;
564 
565  // parents and offspring are all in competition
566  for (i = 0; i < 2*mPopSize; i++)
567  {
568  mWins[i] = 0;
569 
570  for (j = 0; j < nopp; j++)
571  {
572  // get random opponent
573  opp = r250n(mPopSize * 2);
574 
575  if (mCandX[i] <= mCandX[opp])
576  mWins[i]++;
577  }
578  }
579 
580  // selection of top mPopSize winners
581  for (i = 0; i < mPopSize; i++)
582  for (j = i + 1; j < 2*mPopSize; j++)
583  if (mWins[i] < mWins[j])
584  swap(i, j);
585 
586  break;
587  }
588 }
589 
590 // check the best individual at this generation
591 unsigned int CGA::fittest(void)
592 {
593  unsigned int i, b;
594  double f;
595  f = mCandX[0];
596  b = 0;
597 
598  for (i = 1; i < mPopSize; i++)
599  if (mCandX[i] < f)
600  {
601  b = i;
602  f = mCandX[i];
603  }
604 
605  return b;
606 }
607 
608 // initialise the population
609 void CGA::creation(unsigned int l, unsigned int u)
610 {
611  unsigned int i;
612  int j;
613 
614  // double mMin, mMax, la;
615  double la;
616 
617  // BOOL linear;
618  bool linear;
619 
620  for (i = l; i < u; i++)
621  {
622  for (j = 0; j < mParamNum; j++)
623  {
624  try
625  {
626  // determine if linear or log scale
627  linear = FALSE;
628  la = 1.0;
629 
630  if (mMin == 0.0)
631  mMin = std::numeric_limits< C_FLOAT64 >::epsilon();
632 
633  if ((mMax <= 0.0) || (mMin <= 0.0))
634  linear = TRUE;
635  else
636  {
637  la = log10(mMax) - log10(mMin);
638 
639  if (la < 1.8)
640  linear = TRUE;
641  }
642 
643  // set it to a random value within the interval
644  if (linear)
645  mIndV[i][j] = mMin + dr250() * (mMax - mMin);
646  else
647  mIndV[i][j] = mMin * pow(10.0, la * dr250());
648  }
649  catch (unsigned int e)
650  {
651  mIndV[i][j] = (mMax - mMin) * 0.5 + mMin;
652  }
653  }
654 
655  try
656  {
657  // calculate its fitness
658  mCandX[i] = evaluate(i);
659  }
660  catch (unsigned int e)
661  {
663  }
664  }
665 
666  // get the index of the fittest
667  mBest = fittest();
668 }
669 
670 // dump data
671 void CGA::dumpData(unsigned int i)
672 {
673  //YOHE: use cout instead
674  //ofstream finalout("debugopt.dat",ios::app);
675 
676  //if (!finalout)
677  // {
678  // cout << "debugopt.dat cannot be opened!" << endl;
679  // exit(1);
680  //}
681  //finalout << "#" << i << "\t" << mCandX[mBest] << endl;
682  std::cout << "#" << i << "\t" << mCandX[mBest] << std::endl;
683 
684  for (int j = 0; j < mParamNum; j++)
685  {
686  //finalout << mIndV[mBest][j] << "\t";
687  std::cout << mIndV[mBest][j] << "\t";
688  }
689 
690  //finalout << std::endl;
691  // finalout << std::endl;
692  //finalout.close();
693 }
694 
695 // optimise function, the real function for optimization
697 {
698  unsigned int i, last_update, u100, u300, u500;
699  double bx;
700 
701  struct timeb before, after;
702  double dTime = 0;
703 
704  ftime(&before);
705  dTime = time(NULL);
706 
707  //mMin = *(mRealProblem.getParameterMin());
708  //mMax = *(mRealProblem.getParameterMax());
709  //mParamNum = mRealProblem.getParameterNum();
710 
711  std::cout << "mMin = " << mMin << ", mMax= " << mMax << ", mParamNum = " << mParamNum << std::endl;
712  std::cout << "mRealProblem.getParameterNum() = " << mRealProblem.getParameterNum() << std::endl;
713 
714  initOptRandom();
715 
716  /*
717  //YOHE: new
718 
719  std::vector <COptAlgorithmParameter> *AlgmParams = getMethodParameters();
720 
721  for (int i=0; i < (getMethodParameterNumber()); i++)
722  {
723  if ((*AlgmParams)[i].getName() == "Population Size")
724  mPopSize = (*AlgmParams)[i].getValue();
725  else if ((*AlgmParams)[i].getName() == "Generation Number")
726  mGener = (*AlgmParams)[i].getValue();
727  else if ((*AlgmParams)[i].getName() == "Mutation Variance")
728  mMutVar = (*AlgmParams)[i].getValue();
729  }
730  */
731 
732  // initialise the variance for mutations
733  //setMutVar(0.1);
734 
735  // initialise the update registers
736  last_update = 0;
737  u100 = u300 = u500 = 0;
738 
739  //Display layout of all MPI processes
740  std::cout << std::endl;
741  std::cout << "Initial populaiton has successfully created!!!!!" << std::endl;
742 
743  // and store that value
744  bx = getBestCandidate();
745 
746  std::cout << "-----------------------------best result at each generation---------------------" << std::endl;
747  std::cout << "Generation\t" << "Best candidate value for object function\t" << "Display " << mParamNum << " parameters" << std::endl;
748  std::cout << std::endl;
749 
750  int psize = getPopSize();
751 
752  // ITERATE FOR gener GENERATIONS
753 
754  for (i = 0; i < getGeneration(); i++)
755  {
756  std::cout << std::endl;
757  std::cout << "GA is processing at generation " << i << std::endl;
758 
759  dumpData(i);
760  // replicate the individuals
761  replicate();
762  // select the most fit
763  select(2);
764  // get the index of the fittest
765  // mBest = fittest();
766  setBest(fittest());
767 
768  if (getBestCandidate() != bx)
769  {
770  last_update = i;
771  bx = getBestCandidate();
772  }
773 
774  if (u100)
775  u100--;
776 
777  if (u300)
778  u300--;
779 
780  if (u500)
781  u500--;
782 
783  // perturb the population if we have stalled for a while
784  if ((u500 == 0) && (i - last_update > 500))
785  {
786  creation(psize / 2, psize);
787  u500 = 500;
788  u300 = 300;
789  u100 = 100;
790  }
791 
792  else if ((u300 == 0) && (i - last_update > 300))
793  {
794  creation(unsigned(psize*0.7), psize);
795 
796  u300 = 300;
797  u100 = 100;
798  }
799 
800  else if ((u100 == 0) && (i - last_update > 100))
801  {
802  creation(unsigned(psize*0.9), psize);
803  u100 = 100;
804  }
805  }
806 
807  ftime(&after);
808  std::ofstream tout("time.dat");
809 
810  if (!tout)
811  {
812  std::cout << " tout cannot output!" << std::endl;
813  exit(0);
814  }
815 
816  tout << "CPU's Calculation Time [ms]:" << 1000*(after.time - before.time) + (after.millitm - before.millitm) << std::endl;
817  tout << " It has taken about " << time(NULL) - dTime << " seconds!" << std::endl;
818  tout.close();
819 
820  std::cout << std::endl;
821  std::cout << "GA has successfully done!" << std::endl;
822  std::cout << " It has taken about " << time(NULL) - dTime << " seconds!" << std::endl;
823  std::cout << "and it is ready to exit now!" << std::endl;
824 
825  return 0;
826 }
void setPopSize(int num)
Definition: CGA.cpp:213
Definition: CGA.h:35
void dumpData(unsigned int i)
Definition: CGA.cpp:671
void setGeneration(int num)
Definition: CGA.cpp:219
double getBestCandidate()
Definition: CGA.cpp:269
#define TRUE
Definition: CGA.h:25
bool initialize()
Definition: CGA.cpp:74
double mMutProb
Definition: CGA.h:45
CGA()
Definition: CGA.cpp:42
void select(int method)
Definition: CGA.cpp:539
unsigned int mPopSize
Definition: CGA.h:41
void mutate(unsigned int i)
Definition: CGA.cpp:384
qreal linear(qreal a, qreal b, qreal t)
void setMax(double num)
Definition: CGA.cpp:237
void replicate(void)
Definition: CGA.cpp:518
void setCandx(int i, double num)
Definition: CGA.cpp:249
double ** mIndV
Definition: CGA.h:48
int mParamNum
Definition: CGA.h:47
double mMax
Definition: CGA.h:43
unsigned int * mCrp
Definition: CGA.h:50
int getPopSize()
Definition: CGA.cpp:281
void setBest(unsigned int num)
Definition: CGA.cpp:255
double mMutVar
Definition: CGA.h:44
CGA & operator=(const CGA &source)
Definition: CGA.cpp:159
virtual bool calculate()
#define FALSE
Definition: CGA.h:26
unsigned int mBest
Definition: CGA.h:46
double evaluate(unsigned int i)
Definition: CGA.cpp:296
void swap(unsigned int o, unsigned int d)
Definition: CGA.cpp:363
CRealProblem mRealProblem
Definition: CGA.h:55
void setIndv(int i, int j, double num)
Definition: CGA.cpp:243
int initOptRandom()
Definition: CGA.cpp:287
int getParamNum()
Definition: CGA.cpp:263
unsigned int mGener
Definition: CGA.h:40
void creation(unsigned int l, unsigned int u)
Definition: CGA.cpp:609
unsigned int * mMidX
Definition: CGA.h:51
int cleanup()
Definition: CGA.cpp:185
void initFirstGeneration()
Definition: CGA.cpp:116
unsigned int fittest(void)
Definition: CGA.cpp:591
void crossover(unsigned int p1, unsigned int p2, unsigned int c1, unsigned int c2)
Definition: CGA.cpp:430
void setParamNum(int num)
Definition: CGA.cpp:207
void setRealProblem(CRealProblem &aProb)
Definition: CGA.cpp:201
int mCrossNum
Definition: CGA.h:42
int optimise()
Definition: CGA.cpp:696
unsigned int getGeneration()
Definition: CGA.cpp:275
void copy(unsigned int o, unsigned int d)
Definition: CGA.cpp:352
double * mCandX
Definition: CGA.h:49
double mMin
Definition: CGA.h:43
void shuffle(void)
Definition: CGA.cpp:500
void setMin(double num)
Definition: CGA.cpp:231
~CGA()
Definition: CGA.cpp:189
void setMutVar(double num)
Definition: CGA.cpp:225
unsigned int * mWins
Definition: CGA.h:52
#define max(a, b)
Definition: f2c.h:176