00001
00019 #include "lscross.h"
00020 #include <realea/common/distance.h>
00021 #include <realea/common/random.h>
00022 #include <realea/common/populationreal.h>
00023 #include <cmath>
00024
00025 using namespace realea;
00026
00027 class LSCrossParams: public ILSParameters {
00028 public:
00029 tChromosomeReal *parents;
00030 tFitness *fitness;
00031 bool init;
00032
00033 LSCrossParams(int num, int dim) {
00034 parents = new tChromosomeReal[num];
00035
00036 for (int i = 0; i < num; i++) {
00037 parents[i].reserve(dim);
00038 }
00039 fitness = new tFitness [num];
00040 init = false;
00041 }
00042
00043 ~LSCrossParams(void) {
00044 delete[] parents;
00045 delete[] fitness;
00046 }
00047 };
00048
00049 LSCross::LSCross(double alpha) {
00050 m_alpha = alpha;
00051 }
00052
00053 ILSParameters *LSCross::getInitOptions(tChromosomeReal &sol) {
00054 int size = m_pop->size();
00055 LSCrossParams *params=new LSCrossParams(3, sol.size());
00056 tIndividualReal *ind;
00057 int sample[size], pos;
00058
00059 initSample(sample, size);
00060
00061
00062 pos = m_random->getSample(sample, &size);
00063 ind = m_pop->getInd(pos);
00064 params->parents[1] = ind->sol();
00065 params->fitness[1] = ind->perf();
00066 pos = m_random->getSample(sample, &size);
00067 ind = m_pop->getInd(pos);
00068 params->parents[2] = ind->sol();
00069 params->fitness[2] = ind->perf();
00070
00071 return params;
00072 }
00073
00074 void crossoverSPX(Random *random, tChromosomeReal *parents,unsigned np, unsigned dim, tChromosomeReal &off) {
00075 tChromosomeReal o(dim);
00076 tChromosomeReal r(np);
00077 tChromosomeReal y(np),C(np);
00078 double u;
00079 unsigned d, i, E=1;
00080
00081 for (d = 0; d < dim; d++) {
00082 o[d] = 0;
00083
00084 for (i = 0; i < np; ++i) {
00085 o[d] += parents[i][d];
00086 }
00087 o[d] /= np;
00088 }
00089
00090 for (i = 0; i < np; i++) {
00091 u = random->rand();
00092 r[i] = pow(u, 1.0/(i+1));
00093 }
00094
00095 for (d = 0; d < np; d++) {
00096 y[0] = parents[0][d];
00097 C[0] = 0;
00098
00099 for (i = 1; i < np; i++) {
00100 y[i] = o[d]+E*(parents[i][d]-o[d]);
00101 C[i] = r[i-1]*(y[i-1]-y[i]+C[i-1]);
00102 }
00103
00104 off[d] = y[np-1]+C[np-1];
00105 }
00106
00107 }
00108
00109 unsigned LSCross::apply(ILSParameters *opt, tChromosomeReal &sol, tFitness &fitness, unsigned maxeval) {
00110 LSCrossParams *p = (LSCrossParams *) opt;
00111 unsigned numEval;
00112 int ndim = sol.size();
00113
00114 if (!p->init) {
00115 p->parents[0] = sol;
00116 p->fitness[0] = fitness;
00117 p->init = true;
00118 }
00119
00120 for (numEval = 0; numEval < maxeval && !m_running->isFinish(); ) {
00121 tChromosomeReal offspring(ndim);
00122 tFitness off_fitness;
00123
00124 crossoverSPX(m_random, p->parents, 3, ndim, offspring);
00125 off_fitness = m_eval->eval(offspring);
00126 numEval++;
00127
00128 if (m_problem->isBetter(off_fitness, p->fitness[0])) {
00129 p->fitness[0] = off_fitness;
00130 p->parents[0] = offspring;
00131 }
00132 }
00133
00134 m_running->reset();
00135 sol = p->parents[0];
00136 fitness = p->fitness[0];
00137 return numEval;
00138 }
00139
00140 unsigned LSCross::applyNeigh(tChromosomeReal &sol, PopulationReal *pop, tFitness &fitness, unsigned maxeval) {
00141 int ndim = sol.size();
00142 LSCrossParams *params = new LSCrossParams(3, ndim);
00143 unsigned pos,numEval;
00144 double dist;
00145 tIndividualReal *ind;
00146
00147 params->parents[0] = sol;
00148 params->fitness[0] = fitness;
00149 pos = getNeigh(sol, pop, 0);
00150 ind = m_pop->getInd(pos);
00151 params->parents[1] = ind->sol();
00152 params->fitness[1] = ind->perf();
00153 dist = distreal(sol, ind->sol());
00154 pos = getNeigh(sol, pop, dist);
00155 ind = m_pop->getInd(pos);
00156 params->parents[2] = ind->sol();
00157 params->fitness[2] = ind->perf();
00158
00159 for (numEval = 0; numEval < maxeval && !m_running->isFinish(); ) {
00160 tChromosomeReal offspring(ndim);
00161 tFitness off_fitness;
00162
00163 crossoverSPX(m_random, params->parents, 3, ndim, offspring);
00164 off_fitness = m_eval->eval(offspring);
00165 numEval++;
00166
00167 if (m_problem->isBetter(off_fitness, params->fitness[0])) {
00168 params->fitness[0] = off_fitness;
00169 params->parents[0] = offspring;
00170 }
00171 }
00172
00173 m_running->reset();
00174 sol = params->parents[0];
00175 fitness = params->fitness[0];
00176 return numEval;
00177 }
00178