• Main Page
  • Namespaces
  • Classes
  • Files
  • File List
  • File Members

D:/LIACS/mies/SerialES/MixedIntegerES.cpp

Go to the documentation of this file.
00001 #include "MixedIntegerES.h"
00002 
00003 //------------------------------------------------------------------------------
00004 // Class MixedIntegerES
00005 //-------------------------------------------------
00006 // Public Members
00007 
00008 MixedIntegerES::MixedIntegerES(unsigned n_r_, unsigned n_z_, unsigned n_d_, unsigned n_sigma_r_, unsigned n_sigma_z_, unsigned n_prob_, unsigned n_f_, 
00009                                 unsigned mu_, unsigned rho_, unsigned kappa_, unsigned lambda_, 
00010                                   vector<double>& lBound_r_, vector<double>& uBound_r_, vector<int>& lBound_z_, vector<int>& uBound_z_, 
00011                                     vector<int>& lBound_d_, vector<int>& uBound_d_, double prob_min_, double prob_max_,
00012                                       bool disRec_r_, bool disRec_z_, bool disRec_sigma_r_, bool disRec_sigma_z_, bool disRec_prob_,
00013                                         bool selfAdaptation_, vector<int>& direction_, 
00014                                           unsigned evaluations_, vector<double>& optimalF_, 
00015                                             double initialSigma_r_, double initialSigma_z_, double initialProb_,
00016                                               ifstream* initialPopFile_, int randomSeed_, bool feedback_) 
00017 {
00018   n_r = n_r_; n_z = n_z_; n_d = n_d_; n_sigma_r = n_sigma_r_; n_sigma_z = n_sigma_z_; n_prob = n_prob_; n_f = n_f_; 
00019   mu = mu_; rho = rho_; kappa = kappa_; lambda = lambda_;
00020   lBound_r = lBound_r_; uBound_r = uBound_r_; lBound_z = lBound_z_; uBound_z = uBound_z_; lBound_d = lBound_d_; uBound_d = uBound_d_; 
00021   prob_min = prob_min_; prob_max = prob_max_;
00022   disRec_r = disRec_r_; disRec_z = disRec_z_; disRec_sigma_r = disRec_sigma_r; disRec_sigma_z = disRec_sigma_z_; disRec_prob = disRec_prob_; 
00023   selfAdaptation = selfAdaptation_; direction = direction_; 
00024   evaluations = evaluations_; optimalF = optimalF_; 
00025   initialSigma_r = initialSigma_r_; initialSigma_z = initialSigma_z_; initialProb = initialProb_;
00026   initialPopFile = initialPopFile_; randomSeed = randomSeed_; feedback = feedback_;
00027 
00028   debug = false;
00029 
00030   /* Insert direction and optimalF value for product/sum of (optionally normalized) F values */
00031   if (direction[0] == 1) // Product in case of F values to be maximized
00032   {
00033     direction.push_back(1); // Product->MAX
00034 
00035     optimalF.push_back(1);
00036     for (unsigned i = 0; i < n_f; i++)
00037       optimalF[n_f] *= optimalF[i];
00038   }
00039   else                   // Sum in case of F values to be minimized
00040   {
00041     direction.push_back(-1); // Sum->min
00042 
00043     optimalF.push_back(0);
00044     for (unsigned i = 0; i < n_f; i++)
00045       optimalF[n_f] += optimalF[i];
00046   }
00047 
00048   P.assign(mu, NULL);
00049   O.assign(lambda, NULL);
00050   bestF.resize(n_f+1); // Reserve space for product/sum of (optionally normalized) F values as well
00051 
00052   /* Determine number of generations possible with current parameter settings */
00053   if (evaluations > 0)
00054     generations = (evaluations - ((initialPopFile == NULL) ? mu : 0)) / lambda; 
00055   else
00056     generations = USHRT_MAX; // OptimalF supplied, convergence behavoir study 
00057 
00058   currGen = 0;
00059 
00060   /* In case of no self-adaptation, set maximum stepsize values to (fraction of which) stepsizes will be constrained */
00061   if (!selfAdaptation)
00062   {
00063     /* Maximum stepsize values for real-valued variables */
00064     maxSigma_r.assign(n_sigma_r, 0);
00065 
00066     for (unsigned i = 0; i < n_sigma_r; i++)
00067     {
00068       if (i == n_sigma_r - 1) // maxSigma_r for last S_r:
00069       {
00070         for (unsigned j = i; j < n_r; j++) // Take equal to the average rough distance to optimum (=delta) of variables R[i...n_r-1]
00071           maxSigma_r[i] += uBound_r[j] - lBound_r[j];
00072 
00073         maxSigma_r[i] /= n_r - n_sigma_r + 1;
00074         maxSigma_r[i] /= sqrt(n_r);
00075       }
00076       else // Take maxSigma_r equal to rough distance to optimum (=delta) of variable R[i] 
00077         maxSigma_r[i] = (uBound_r[i] - lBound_r[i]) / sqrt(n_r);
00078     }
00079 
00080     /* Maximum stepsize values for integer variables */
00081     maxSigma_z.assign(n_sigma_z, 0);
00082 
00083     for (unsigned i = 0; i < n_sigma_z; i++)
00084     {
00085       if (i == n_sigma_z - 1) // maxSigma_z for last S_z:
00086       {
00087         for (unsigned j = i; j < n_z; j++) // Take equal to the average rough distance to optimum (=delta) of variables Z[i...n_z-1]
00088           maxSigma_z[i] += uBound_z[j] - lBound_z[j];
00089 
00090         maxSigma_z[i] /= n_z - n_sigma_z + 1;
00091         maxSigma_z[i] /= sqrt(n_z);
00092       }
00093       else // Take maxSigma_z equal to rough distance to optimum (=delta) of variable Z[i] 
00094         maxSigma_z[i] = (uBound_z[i] - lBound_z[i]) / sqrt(n_z);
00095     }
00096   }
00097 }
00098 
00099 MixedIntegerES::~MixedIntegerES()
00100 {
00101 #ifdef DEBUG
00102   cout << "MixedIntegerES::~MixedIntegerES()" << endl;
00103 #endif
00104 
00105   for (unsigned i = 0; i < mu; i++)
00106     delete P[i];
00107 
00108   for (unsigned i = 0; i < lambda; i++)
00109     delete O[i];
00110 }
00111 
00112 /* Execute the MIES */
00113 void MixedIntegerES::run()
00114 {
00115 #ifdef DEBUG
00116   cout << "MixedIntegerES::run()" << endl;
00117 #endif
00118 
00119   time_t start = time(NULL); 
00120   time_t startGen = start;
00121 
00122   /* Random seed: if -1 use system clock, else use supplied seed */
00123   id = (randomSeed == -1) ? start : randomSeed; 
00124 
00125   /* Initialize random number generator */
00126   randGenerator.seed(static_cast<unsigned int>(id));
00127 
00128   /* Generate and evaluate initial population or read in from file */
00129   initialize();
00130 
00131   /* Write current population to file */
00132   writePop(id);
00133 
00134   time_t elapsed = time(NULL) - startGen;
00135   writeLog(elapsed, id);
00136  
00137   for (currGen = 1; currGen <= generations; currGen++)
00138   {
00139     /* Print debug info in case of slow convergence */  
00140     if (currGen > DEBUG_FROM_GEN)
00141       debug = true;
00142 
00143     /* Log time needed to complete generation */          
00144     startGen = time(NULL);
00145 
00146     increaseAge();
00147 
00148     recombineMutate();
00149 
00150     if (feedback)
00151       cout << endl << "Evaluating generation " << currGen << "/" << generations << endl;
00152 
00153     evaluate();
00154 
00155     select();
00156 
00157     /* Write current population to file */
00158     writePop(id);
00159 
00160     elapsed = time(NULL) - startGen;
00161     writeLog(elapsed, id);
00162 
00163 #ifdef LHSR
00164     updateTotalGen(generations, currGen, evaluations, lambda);
00165 #endif
00166 
00167     if (optimumReached())
00168     {
00169       cout << endl << "Optimum reached in generation " << currGen << endl;
00170       return;
00171     }
00172   } 
00173   
00174   /* Optimization complete: print total elapsed time, and best objective value(s) */
00175   cout << endl;
00176 
00177   elapsed = time(NULL) - start;
00178   writeLog(elapsed, id);
00179 
00180   for (unsigned i = 0; i < n_f+1; i++)
00181   {
00182     if (direction[i] == 1)
00183     {
00184       if (bestF[i] == 0)
00185         continue;
00186     }       
00187     else
00188     {
00189       if (bestF[i] == DBL_MAX)
00190         continue;
00191     } 
00192 
00193     if (i == n_f)
00194       cout << "Optimal " << ((direction[i] == 1) ? "product" : "sum") << " of F values = " << bestF[i] << endl;
00195     else
00196       cout << "bestF[" << i << "] = " << bestF[i] << endl;      
00197   }
00198 }
00199 
00200 //-------------------------------------------------
00201 // Protected Members
00202 
00203 /* Initialize Individuals in population P with uniform randomly 
00204  * chosen values within various variable and parameter domains
00205  * or read previously generated population in from file
00206  */
00207 void MixedIntegerES::initialize()
00208 {
00209 #ifdef DEBUG
00210   cout << "MixedIntegerES::initialize()" << endl;
00211 #endif
00212 
00213   /* Generate and evaluate if initial population not supplied in file */
00214   if (initialPopFile == NULL)
00215   {          
00216     if (feedback)
00217       cout << "Generating initial population" << endl;
00218      
00219     for (unsigned i = 0; i < mu; i++) 
00220       P[i] = new Individual(n_r, n_z, n_d, n_sigma_r, n_sigma_z, n_prob, n_f,
00221                              lBound_r, uBound_r, lBound_z, uBound_z, lBound_d, uBound_d, prob_min, prob_max,
00222                                initialSigma_r, initialSigma_z, initialProb);
00223 
00224     if (feedback)
00225       cout << "Evaluating initial population" << endl;
00226 
00227     evaluate(); // currGen = 0
00228   }
00229   else
00230   {
00231     if (feedback)
00232       cout << "Loading initial population from file" << endl;
00233 
00234     /* Reset best fitness values */
00235     for (unsigned i = 0; i < n_f+1; i++)
00236     {
00237       if (direction[i] == 1)
00238         bestF[i] = 0;
00239       else
00240         bestF[i] = DBL_MAX;
00241     }
00242 
00243     vector<double> R, S_r, S_z, Prob, F;
00244     vector<int> Z, D;
00245     bool feasible;
00246     char line[LEN], * next;
00247 
00248     for (unsigned i = 0; i < mu; i++) 
00249     {
00250       R.assign(n_r, 0);
00251       Z.assign(n_z, 0);
00252       D.assign(n_d, 0);
00253 
00254       S_r.assign(n_sigma_r, 0);
00255       S_z.assign(n_sigma_z, 0);
00256       Prob.assign(n_prob, 0);
00257 
00258       F.assign(3*n_f+1, 0); 
00259 
00260       /* Read in Individual */
00261 
00262       feasible = (initialPopFile->get() == 'F') ? true : false;
00263 
00264       initialPopFile->getline(line, LEN);
00265 
00266       /* Fitness values */
00267       F[0] = strtod(line, &next);
00268 #ifdef MASPROJ
00269       for (unsigned j = 1; j < 3*n_f+1; j++)
00270 #else
00271       for (unsigned j = 1; j < n_f; j++)
00272 #endif
00273         F[j] = strtod(next, &next);
00274 
00275       /* Object variables */
00276       for (unsigned j = 0; j < n_r; j++)
00277               R[j] = strtod(next, &next);
00278 
00279       for (unsigned j = 0; j < n_z; j++)
00280               Z[j] = (int) strtod(next, &next);
00281 
00282       for (unsigned j = 0; j < n_d; j++)
00283               D[j] = (int) strtod(next, &next);
00284 
00285       /* Strategy parameters */
00286       for (unsigned j = 0; j < n_sigma_r; j++)
00287               S_r[j] = strtod(next, &next);
00288 
00289       for (unsigned j = 0; j < n_sigma_z; j++)
00290               S_z[j] = strtod(next, &next);
00291 
00292       for (unsigned j = 0; j < n_prob; j++)
00293               Prob[j] = strtod(next, &next);
00294 
00295       P[i] = new Individual(R, Z, D, S_r, S_z, Prob, F, feasible);
00296 
00297       /* Skip two white lines */
00298       initialPopFile->getline(line, LEN);
00299       initialPopFile->getline(line, LEN);
00300     }
00301 
00302     initialPopFile->close();
00303   }
00304 }
00305 
00306 /* Determine fitness values for population P or O */
00307 void MixedIntegerES::evaluate()
00308 {
00309 #ifdef DEBUG
00310   cout << "MixedIntegerES::evaluate()" << endl;
00311 #endif
00312 
00313   /* Reset best fitness values */
00314   for (unsigned i = 0; i < n_f+1; i++)
00315   {
00316     if (direction[i] == 1)
00317       bestF[i] = 0;
00318     else
00319       bestF[i] = DBL_MAX;
00320   }
00321 
00322   if (currGen == 0)
00323   {
00324     for (unsigned i = 0; i < mu; i++)
00325     {
00326       if (feedback)
00327               cout << endl << "Running simulator for generation " << currGen 
00328                << "/" << generations << ", Individual " << i+1 << "/" << mu << endl << endl;
00329       simulate(P[i]);
00330     }
00331   }
00332   else
00333   {
00334     for (unsigned i = 0; i < lambda; i++)
00335     {
00336       if (feedback)
00337               cout << endl << "Running simulator for generation " << currGen 
00338                << "/" << generations << ", Individual " << i+1 << "/" << lambda << endl << endl;
00339       simulate(O[i]);
00340     }
00341   }
00342 }
00343 
00344 /* Increase age of Individuals in population P by one */
00345 void MixedIntegerES::increaseAge()
00346 {
00347   for (unsigned i = 0; i < mu; i++)
00348     P[i]->age++;
00349 }
00350 
00351 /* Create lambda offspring by recombination and mutation */
00352 void MixedIntegerES::recombineMutate() 
00353 {
00354 #ifdef DEBUG
00355   cout << "MixedIntegerES::recombineMutate()" << endl;
00356 #endif
00357 
00358   vector<int> parents;
00359 
00360   /* Generate lambda offspring */
00361   for (unsigned i = 0; i < lambda; i++)
00362   {
00363     /* Draw uniform randomly rho parent indices from population P */
00364     for (unsigned j = 0; j < rho; j++) 
00365       parents.push_back(uniInt() % mu);
00366 
00367     O[i] = new Individual();
00368  
00369     /* Recombine object variables and strategy parameters */
00370     applyRecomb(O[i], parents);
00371 
00372     /* Mutate strategy parameters and object variables */
00373     applyMut(O[i]);
00374 
00375     /* Fitness values */
00376     O[i]->F.assign(3*n_f+1, 0); // Reserve space for, in case of
00377                                 // A posteriori method: normalized+penalized F values, (sum/product), normalized F values, original F values 
00378                                 // A priori method:     (norm+pen), sum/product of normalized F values, normalized F values, original F values
00379                                 // (see SingleAisle_MIES)  
00380     parents.clear();
00381   }
00382 }
00383 
00384 /* Create lambda offspring by mutation of a single (recombined) parent */
00385 void MixedIntegerES::recombineMutateSingleParent() 
00386 {
00387 #ifdef DEBUG
00388   cout << "MixedIntegerES::recombineMutateSingleParent()" << endl;
00389 #endif
00390 
00391   Individual* singleParent;
00392 
00393   /* Draw random parent from population P to use as singleParent, and place at position 0
00394    * so it can be excluded in comparison score calculation, see NSGAII_Steady_MIES) */
00395   if (rho == 1)
00396   {
00397     int rand = uniInt() % mu;
00398     Individual* temp = P[0];
00399     P[0] = P[rand];
00400     P[rand] = temp;
00401     
00402     singleParent = P[0];
00403   }
00404   /* Draw uniform randomly rho parent indices from population P and recombine into singleParent */
00405   else
00406   {
00407     vector<int> parents;
00408     for (unsigned j = 0; j < rho; j++) 
00409       parents.push_back(uniInt() % mu);
00410 
00411     singleParent = new Individual();
00412     applyRecomb(singleParent, parents);
00413   }
00414 
00415   /* Generate lambda offspring */
00416   for (unsigned i = 0; i < lambda; i++)
00417   { 
00418     O[i] = new Individual(singleParent);
00419 
00420     /* Mutate strategy parameters and object variables */
00421     applyMut(O[i]);
00422 
00423     /* Fitness values */
00424     O[i]->F.assign(3*n_f+1, 0); // Reserve space for, in case of
00425                                 // A posteriori method: normalized+penalized F values, (sum/product), normalized F values, original F values 
00426                                 // A priori method:     (norm+pen), sum/product of normalized F values, normalized F values, original F values
00427                                             // (see SingleAisle_MIES)  
00428   }
00429 
00430   if (rho > 1)
00431     delete singleParent;
00432 }
00433 
00434 void MixedIntegerES::applyRecomb(Individual* I, vector<int>& parents)
00435 {
00436 #ifdef DEBUG
00437   cout << "MixedIntegerES::applyRecomb()" << endl;
00438 #endif
00439 
00440   /* Real-valued */
00441   if (n_r > 0) 
00442   {
00443     /* Real-valued: object variables */
00444     I->R.assign(n_r, 0);
00445 
00446     if (disRec_r) // Discrete recombination
00447     {
00448       for (unsigned i = 0; i < n_r; i++) // Per variable select the value of one of the rho parents
00449         I->R[i] = P[parents[uniInt() % rho]]->R[i];
00450     } 
00451     else // Intermediary recombination
00452     {
00453       for (unsigned i = 0; i < n_r; i++) // Per variable:
00454       {
00455         for (unsigned j = 0; j < rho; j++) // 1) add values of the rho parents
00456           I->R[i] += P[parents[j]]->R[i];
00457 
00458         I->R[i] /= rho;                    // 2) divide by the number of parents
00459       }
00460     }
00461 
00462     /* Real-valued: strategy parameters */
00463     I->S_r.assign(n_sigma_r, 0);
00464 
00465     if (disRec_sigma_r) // Discrete recombination
00466     {
00467       for (unsigned i = 0; i < n_sigma_r; i++) // Per parameter the select value of one of the rho parents
00468         I->S_r[i] = P[parents[uniInt() % rho]]->S_r[i];
00469     } 
00470     else // Intermediary recombination
00471     {
00472       for (unsigned i = 0; i < n_sigma_r; i++) // Per parameter:
00473       {
00474         for (unsigned j = 0; j < rho; j++) // 1) add values of the rho parents
00475           I->S_r[i] += P[parents[j]]->S_r[i];
00476 
00477         I->S_r[i] /= rho;                  // 2) divide by the number of parents
00478       }
00479     }
00480   }
00481   
00482   /* Integer */
00483   if (n_z > 0) 
00484   {
00485     /* Integer: object variables */
00486     I->Z.assign(n_z, 0);
00487 
00488     if (disRec_z) // Discrete recombination
00489     {
00490       for (unsigned i = 0; i < n_z; i++) // Per variable select the value of one of the rho parents
00491         I->Z[i] = P[parents[uniInt() % rho]]->Z[i];
00492     } 
00493     else // Intermediary recombination
00494     {
00495       for (unsigned i = 0; i < n_z; i++) // Per variable:
00496       {
00497         for (unsigned j = 0; j < rho; j++)        // 1) add values of the rho parents
00498           I->Z[i] += P[parents[j]]->Z[i];
00499 
00500         I->Z[i] = lround((double) I->Z[i] / rho); // 2) divide by the number of parents
00501       }
00502     }
00503 
00504     /* Integer: strategy parameters */
00505     I->S_z.assign(n_sigma_z, 0);
00506 
00507     if (disRec_sigma_z) // Discrete recombination
00508     {
00509       for (unsigned i = 0; i < n_sigma_z; i++) // Per parameter select the value of one of the rho parents
00510         I->S_z[i] = P[parents[uniInt() % rho]]->S_z[i];
00511     } 
00512     else // Intermediary recombination
00513     {
00514       for (unsigned i = 0; i < n_sigma_z; i++) // Per parameter:
00515       {
00516         for (unsigned j = 0; j < rho; j++) // 1) add values of the rho parents
00517           I->S_z[i] += P[parents[j]]->S_z[i];
00518 
00519         I->S_z[i] /= rho;                  // 2) divide by the number of parents
00520       }
00521     }
00522   }
00523 
00524   /* Discrete */
00525   if (n_d > 0) 
00526   {  
00527     /* Discrete: object variables */
00528     I->D.assign(n_d, 0);
00529 
00530     for (unsigned i = 0; i < n_d; i++) // Discrete recombination: per variable select the value of one of the rho parents
00531       I->D[i] = P[parents[uniInt() % rho]]->D[i];
00532    
00533     /* Discrete: strategy parameters */
00534     I->Prob.assign(n_prob, 0);
00535 
00536     if (disRec_prob) // Discrete recombination
00537     {
00538       for (unsigned i = 0; i < n_prob; i++) // Per parameter select the value of one of the rho parents
00539         I->Prob[i] = P[parents[uniInt() % rho]]->Prob[i];
00540     } 
00541     else // Intermediary recombination
00542     {
00543       for (unsigned i = 0; i < n_prob; i++) // Per parameter:
00544       {
00545         for (unsigned j = 0; j < rho; j++) // 1) add values of the rho parents
00546           I->Prob[i] += P[parents[j]]->Prob[i];
00547 
00548         I->Prob[i] /= rho;                 // 2) divide by the number of parents
00549       }
00550     }
00551   }
00552 }
00553 
00554 void MixedIntegerES::applyMut(Individual* I) 
00555 {
00556 #ifdef DEBUG
00557   cout << "MixedIntegerES::applyMut()" << endl;
00558 #endif
00559 
00560   double N_c;
00561   double tau, tau1;
00562   double epsilon;
00563  
00564   /* 1: Mutation of real-valued variables */
00565   N_c  = normReal();
00566   tau  = 1.0/sqrt(2.0*n_r);
00567   tau1 = 1.0/sqrt(2.0*sqrt(n_r));
00568   epsilon = 1e-30;
00569 
00570   /* Real-valued: strategy parameters */
00571   if (n_sigma_r == 1)
00572   {
00573     I->S_r[0] = max(epsilon, I->S_r[0] * exp(tau*N_c));
00574 
00575     if (!selfAdaptation) // Fixed convergence of real-vars stepsize
00576       I->S_r[0] = fixedConvergence(I->S_r[0], epsilon, maxSigma_r[0]-epsilon);  
00577   }
00578   else
00579   {
00580     for (unsigned i = 0; i < n_sigma_r; i++)
00581       I->S_r[i] = max(epsilon, I->S_r[i] * exp(tau*N_c + tau1*normReal()));
00582 
00583     if (!selfAdaptation) // Fixed convergence of real-vars stepsizes
00584     {
00585       for (unsigned i = 0; i < n_sigma_r; i++)
00586         I->S_r[i] = fixedConvergence(I->S_r[i], epsilon, maxSigma_r[i]-epsilon);  
00587     }
00588   }
00589 
00590   /* Real-valued: object variables */
00591   for (unsigned i = 0; i < n_r; i++)
00592   {
00593     I->R[i] += I->S_r[min(n_sigma_r-1, i)] * normReal();
00594     
00595     /* Boundary rules for keeping variables within bounds */
00596     I->R[i] = transformR(I->R[i], lBound_r[i], uBound_r[i]);
00597   }
00598 
00599   /* 2: Mutation of integer variables */
00600   N_c  = normReal();
00601   tau  = 1.0/sqrt(2.0*n_z);
00602   tau1 = 1.0/sqrt(2.0*sqrt(n_z));
00603 
00604   /* Integer: strategy parameters */
00605   if (n_sigma_z == 1)
00606   {
00607     I->S_z[0] = max(1.0, I->S_z[0] * exp(tau*N_c)); 
00608 
00609     if (!selfAdaptation) // Fixed convergence of integer-vars stepsize
00610       I->S_z[0] = fixedConvergence(I->S_z[0], 1.0, maxSigma_z[0]-1.0); 
00611   }
00612   else
00613   {
00614     for (unsigned i = 0; i < n_sigma_z; i++)
00615       I->S_z[i] = max(1.0, I->S_z[i] * exp(tau*N_c + tau1*normReal()));
00616 
00617     if (!selfAdaptation) // Fixed convergence of integer-vars stepsizes
00618     {
00619       for (unsigned i = 0; i < n_sigma_z; i++)
00620         I->S_z[i] = fixedConvergence(I->S_z[i], 1.0, maxSigma_z[i]-1.0);  
00621     }
00622   }
00623 
00624   /* Integer: object variables */
00625   double u1, u2, p, s;
00626   int G1, G2;
00627   for (unsigned i = 0; i < n_z; i++)
00628   {
00629     u1 = uniReal();
00630     u2 = uniReal();
00631     s = I->S_z[min(n_sigma_z-1, i)];
00632 
00633     p = 1.0 - (s/n_z) / (1.0 + sqrt(1.0+pow(s/n_z, 2.0))); 
00634     G1 = (int) floor(log(1.0-u1) / log(1.0-p));
00635     G2 = (int) floor(log(1.0-u2) / log(1.0-p));
00636 
00637     I->Z[i] += G1 - G2;
00638 
00639     /* Boundary rules for keeping variables within bounds */
00640     I->Z[i] = transformZ(I->Z[i], lBound_z[i], uBound_z[i]);
00641   } 
00642 
00643   /* 3: Mutation of discrete variables */
00644   N_c  = normReal();
00645   double gamma = 0.4;
00646   tau  = 1.0/sqrt(2.0*n_d); 
00647   tau1 = 1.0/sqrt(2.0*sqrt(n_d));
00648   
00649   /* Discrete: strategy parameters */
00650   if (n_prob == 1)
00651   {
00652     I->Prob[0] = 1.0 / (1.0 + ((1.0-I->Prob[0]) / I->Prob[0]) * exp(-gamma*N_c)); 
00653 
00654     if (selfAdaptation) // Boundary rules for keeping probabilities within bounds
00655     {
00656       if (I->Prob[0] > prob_max - 1.0/n_d) 
00657         I->Prob[0] = prob_max - 1.0/n_d;
00658     }
00659     else                // Fixed convergence of probability
00660       I->Prob[0] = fixedConvergence(I->Prob[0], prob_min, prob_max);
00661   }
00662   else // TODO: fix multiple stepsize case (like single probability case)
00663   {
00664     for (unsigned i = 0; i < n_prob; i++)
00665     {
00666       I->Prob[i] = 1.0 / (1.0 + ((1.0-I->Prob[i]) / I->Prob[i]) * exp(-tau*N_c - tau1*normReal()));
00667 
00668       if (selfAdaptation) // Boundary rules for keeping probabilities within bounds
00669         I->Prob[i] = transformR(I->Prob[i], prob_min, prob_max);
00670       else                // Fixed convergence of probabilities
00671         I->Prob[i] = fixedConvergence(I->Prob[i], prob_min, prob_max);
00672     }
00673   } 
00674 
00675   /* Discrete: object variables */
00676   int D_old;
00677   for (unsigned i = 0; i < n_d; i++)
00678   {
00679     if (uniReal() < (1.0/n_d + I->Prob[min( n_prob-1, i)])) 
00680     {
00681       D_old = I->D[i];
00682 
00683       do 
00684       {
00685         I->D[i] = uniInt() % (uBound_d[i] - lBound_d[i] + 1) + lBound_d[i];
00686       }
00687       while (I->D[i] == D_old);
00688     }
00689   }
00690 }
00691 
00692 /* Reflect double x back into domain [a,b]; b must be strictly greater than a */
00693 double MixedIntegerES::transformR(double x, double a, double b)
00694 {
00695   double y, y1, x1;
00696 
00697   y = (x-a) / (b-a);
00698 
00699   if ((int) floor(y) % 2 == 0)
00700     y1 = abs(y - floor(y));
00701   else
00702     y1 = 1 - abs(y - floor(y));
00703 
00704   x1 = a + (b-a)*y1;
00705   
00706 #ifdef DEBUG
00707   cout << "MixedIntegerES::transformR(): x=" << x << ", a=" << a << ", b=" << b << ", x1=" << x1 << endl; 
00708 #endif
00709 
00710   return x1;
00711 }
00712 
00713 /* Reflect integer x back into domain [a,b]; b must be strictly greater than a */
00714 int MixedIntegerES::transformZ(int x, int a, int b)
00715 {
00716   int x1 = (int) floor(transformR(x, a, b));
00717 
00718 #ifdef DEBUG
00719   cout << "MixedIntegerES::transformZ(): x=" << x << ", a=" << a << ", b=" << b << ", x1=" << x1 << endl; 
00720 #endif
00721 
00722   return x1;
00723 }
00724 
00725 /* Fixed convergence for supplied stepsize or probability */ // TODO: change to determinstic schedule from Bäck, 1996 - Intelligent Mutation
00726 double MixedIntegerES::fixedConvergence(double x, double threshold, double varPart)
00727 {
00728   double a = 3.0; // set a to generations*100 for normal reflection (i.e, for all generations, maxValue = varPart + threshold)
00729   double maxValue = (1 - pow((double)currGen/(generations+1), a)) * varPart + threshold; // generations+1 to make sure maxValue is always > threshold
00730                                                                                         
00731 #ifdef DEBUG
00732   cout << "MixedIntegerES::fixedConvergence(): " << maxValue << endl; 
00733 #endif
00734 
00735   if (x < threshold)
00736     x = threshold;
00737   else if (x > maxValue)
00738     x = maxValue;         
00739 
00740   return x;
00741 }       
00742 
00743 //------------------------------------------------------------------------------
00744 // Class Individual
00745 //-------------------------------------------------
00746 // Public Members
00747 
00748 Individual::Individual(unsigned n_r, unsigned n_z, unsigned n_d, unsigned n_sigma_r, unsigned n_sigma_z, unsigned n_prob, unsigned n_f, 
00749                         vector<double>& lBound_r, vector<double>& uBound_r, vector<int>& lBound_z, vector<int>& uBound_z, 
00750                           vector<int>& lBound_d, vector<int>& uBound_d, double prob_min, double prob_max,
00751                             double initialSigma_r, double initialSigma_z, double initialProb)
00752 {
00753   /* Initialize object variables */
00754   for (unsigned i = 0; i < n_r; i++) // Real-valued: random double within [lBound_r[i],uBound_r[i]]
00755     R.push_back(uniReal() * (uBound_r[i] - lBound_r[i]) + lBound_r[i]);
00756 
00757   for (unsigned i = 0; i < n_z; i++) // Integer: random int within [lBound_z[i],uBound_z[i]]
00758     Z.push_back(uniInt() % (uBound_z[i] - lBound_z[i] + 1) + lBound_z[i]);
00759 
00760   for (unsigned i = 0; i < n_d; i++) // Discrete: random int within [lBound_d[i],uBound_d[i]]
00761     D.push_back(uniInt() % (uBound_d[i] - lBound_d[i] + 1) + lBound_d[i]);
00762 
00763   /* Strategy parameters */
00764   for (unsigned i = 0; i < n_sigma_r; i++) // Stepsizes for real-valued variables: delta/sqrt(n_r) 
00765     S_r.push_back((initialSigma_r == 0) ? (uBound_r[i] - lBound_r[i]) / sqrt(n_r) : initialSigma_r); // delta = uBound_r[i]-lBound_r[i], i.e., 
00766                                                                                                      // rough distance to optimum
00767   for (unsigned i = 0; i < n_sigma_z; i++) // Stepsizes for integer variables: delta/sqrt(n_z) 
00768     S_z.push_back((initialSigma_z == 0) ? (uBound_z[i] - lBound_z[i]) / sqrt(n_z) : initialSigma_z); // delta = uBound_z[i]-lBound_z[i], i.e., 
00769                                                                                                      // rough distance to optimum
00770   for (unsigned i = 0; i < n_prob; i++) // Mutation probabilities for discrete variables
00771     Prob.push_back((initialProb == 0) ? uniReal() * (prob_max - prob_min) + prob_min : initialProb - 1.0/n_d); 
00772 
00773   /* Fitness values */
00774   F.assign(3*n_f+1, 0); // Reserve space for, in case of
00775                         // A posteriori method: normalized+penalized F values, (sum/product), normalized F values, original F values 
00776                         // A priori method:     (norm+pen), sum/product of normalized F values, normalized F values, original F values
00777                         // (see SingleAisle_MIES)  
00778 
00779   /* Initialize feasibility flag */
00780   feasible = true;
00781 
00782   /* Initialize age */
00783   age = 0;
00784 
00785   /* Initialize number of Individuals by which this Individual is dominated */
00786   numDominating = 0;
00787 }
00788 
00789 Individual::Individual(vector<double>& R_, vector<int>& Z_, vector<int>& D_, 
00790                         vector<double>& S_r_, vector<double>& S_z_, vector<double>& Prob_,
00791                           vector<double>& F_, bool feasible_)
00792 {
00793   /* Object variables */
00794   R = R_; Z = Z_; D = D_;
00795 
00796   /* Strategy parameters */ 
00797   S_r = S_r_; S_z = S_z_; Prob = Prob_;
00798 
00799   /* Fitness values */
00800   F = F_;
00801 
00802   /* Feasibility flag */
00803   feasible = feasible_;
00804 
00805   /* Initialize age */
00806   age = 0;
00807 
00808   /* Initialize number of Individuals by which this Individual is dominated */
00809   numDominating = 0;
00810 }
00811 
00812 Individual::Individual(Individual* original)
00813 {
00814   if (original != NULL)
00815   {
00816     /* Object variables */
00817     R = original->R; 
00818     Z = original->Z; 
00819     D = original->D;
00820 
00821     /* Strategy parameters */ 
00822     S_r = original->S_r; 
00823     S_z = original->S_z; 
00824     Prob = original->Prob;
00825 
00826     /* Fitness values */
00827     F = original->F;
00828   }
00829 
00830   /* Feasibility flag */
00831   feasible = true;
00832 
00833   /* Initialize age */
00834   age = 0;
00835 
00836   /* Initialize number of Individuals by which this Individual is dominated */
00837   numDominating = 0;
00838 }
00839 
00840 void Individual::dump()
00841 {
00842   int size = R.size();
00843   if (size > 0)
00844     cout << "Real-valued object variables" << endl;
00845   for (int i = 0; i < size; i++)
00846   {
00847     cout << "r" << i << "=" << R[i] << endl;
00848   }
00849 
00850   size = Z.size();
00851   if (size > 0)
00852     cout << "Integer object variables" << endl;
00853   for (int i = 0; i < size; i++)
00854   {
00855     cout << "z" << i << "=" << Z[i] << endl;
00856   }
00857 
00858   size = D.size();
00859   if (size > 0)
00860     cout << "Discrete object variables" << endl;
00861   for (int i = 0; i < size; i++)
00862   {
00863     cout << "d" << i << "=" << D[i] << endl;
00864   }
00865 
00866   size = S_r.size();
00867   if (size > 0)
00868     cout << "Strategy parameters for real-valued object variables" << endl;
00869   for (int i = 0; i < size; i++)
00870   {
00871     cout << "S_r[" << i << "]=" << S_r[i] << endl;
00872   }
00873 
00874   size = S_z.size();
00875   if (size > 0)
00876     cout << "Strategy parameters for integer object variables" << endl;
00877   for (int i = 0; i < size; i++)
00878   {
00879     cout << "S_z[" << i << "]=" << S_z[i] << endl;
00880   }
00881 
00882   size = Prob.size();
00883   if (size > 0)
00884     cout << "Strategy parameters for discrete object variables" << endl;
00885   for (int i = 0; i < size; i++)
00886   {
00887     cout << "Prob[" << i << "]=" << Prob[i] << endl;
00888   }
00889 
00890   cout << "Age=" << age << endl; 
00891 
00892   cout << "numDominating=" << numDominating << endl; 
00893 }
00894 

Generated on Tue Oct 4 2011 16:25:19 for WDN by  doxygen 1.7.2