00001
00020 #include "cross.h"
00021 #include "problem.h"
00022 #include "random.h"
00023 #include <cassert>
00024 #include <cmath>
00025
00026 using namespace realea;
00027 using namespace realea::internal;
00028
00029 void CrossBinary::operator()(tIndividualReal *mom, tIndividualReal *dad, tChromosomeReal &child) {
00030 mom->incremCount("cross");
00031 dad->incremCount("cross");
00032 operator()(mom->sol(), mom->perf(), dad->sol(), dad->perf(), child);
00033 }
00034
00035 void CrossBinary::operator()(const tChromosomeReal &mom, tFitness fit_mom, const tChromosomeReal &dad, tFitness fit_dad, tChromosomeReal &children) {
00036 (*m_cross)(mom,fit_mom, dad, fit_dad, children);
00037 }
00038
00039 CrossBinary::CrossBinary(ICrossBinaryPtr cross) : m_cross(cross) {
00040 }
00041
00042 CrossBinary::~CrossBinary(void) {
00043 delete m_cross;
00044 }
00045
00046
00047 CrossBLX::CrossBLX(double alpha) : m_alpha(alpha) {
00048 assert(alpha > 0);
00049 }
00050
00051 CrossBLX::~CrossBLX(void) {
00052 }
00053
00054
00055
00056 void CrossBLX::operator()(const tChromosomeReal &mom, tFitness fit_mom, const tChromosomeReal &dad, tFitness fit_dad, tChromosomeReal &children) {
00057 double puntox, puntoy, I, A1, B1;
00058 double rate;
00059 unsigned i, size = dad.size();
00060 tGen min, max;
00061
00062 assert(dad.size() == mom.size());
00063
00064 copy(mom.begin(), mom.end(), children.begin());
00065
00066 if (fit_mom == fit_dad) {
00067 rate = 0.5;
00068 }
00069 else {
00070 rate = fit_dad/(fit_mom+fit_dad);
00071 }
00072 rate = 0.5;
00073
00074
00075 for (i=0; i< size; i++)
00076 {
00077 if (!m_domain->canBeChanged(i)) {
00078 if (m_random->rand() <= rate) {
00079 children[i] = mom[i];
00080 }
00081 else {
00082 children[i] = dad[i];
00083 }
00084
00085 }
00086
00087 m_domain->getValues(i, &min, &max);
00088 puntox=mom[i]; puntoy=dad[i];
00089 if (puntox > puntoy) {
00090 swap(puntox,puntoy);
00091 }
00092
00093 I=(puntoy-puntox)*m_alpha;
00094 assert(I >= 0);
00095
00096 A1 = puntox-I;
00097
00098 if (A1 < min)
00099 A1 = min;
00100
00101 B1 = puntoy+I;
00102
00103 if (B1 > max) {
00104 B1 = max;
00105 }
00106
00107 children[i]=A1 + m_random->rand()*(B1-A1);
00108 }
00109
00110 }
00111
00112
00113 CrossPBLX::CrossPBLX(double alpha) : m_alpha(alpha) {
00114 }
00115
00116 CrossPBLX::~CrossPBLX(void) {
00117 }
00118
00130 unsigned getNGen(double ratiocurrent, double mintotal, unsigned dim) {
00131 if (ratiocurrent >= mintotal) {
00132 return dim;
00133 }
00134 else {
00135 return (int)ceil(dim*(ratiocurrent/mintotal));
00136 }
00137 }
00138
00139
00140 void CrossPBLX::operator()(const tChromosomeReal &mom, tFitness fit_mom, const tChromosomeReal &dad, tFitness fit_dad, tChromosomeReal &children) {
00141 double puntox, puntoy, I, A1, B1;
00142 unsigned i, dim = dad.size();
00143 tGen min, max;
00144
00145 assert(dad.size() == mom.size());
00146
00147
00148 unsigned dim_ini = (unsigned) ceil(m_dim_ini*dim);
00149 unsigned dim_fin = (unsigned) ceil(m_dim_fin*dim);
00150 assert(dim_ini < dim_fin);
00151
00152
00153 copy(mom.begin(), mom.end(), children.begin());
00154
00155
00156 for (i=dim_ini; i< dim_fin; i++)
00157 {
00158 if (!m_domain->canBeChanged(i)) {
00159 continue;
00160 }
00161
00162 m_domain->getValues(i, &min, &max);
00163 puntox=mom[i]; puntoy=dad[i];
00164 I=fabs(puntoy-puntox)*m_alpha;
00165
00166 A1 = mom[i]-I;
00167
00168 if (A1 < min)
00169 A1 = min;
00170
00171 B1 = mom[i]+I;
00172
00173 if (B1 > max) {
00174 B1 = max;
00175 }
00176
00177 children[i]=A1 + m_random->rand()*(B1-A1);
00178 }
00179
00180 }
00181