00001
00019 #include "selectlsimp.h"
00020 #include <realea/common/distance.h>
00021 #include <algorithm>
00022 #include <cassert>
00023
00024 using namespace realea;
00025
00026 bool isBetter(tIndividualReal *a, tIndividualReal *b) {
00027 if (a->isBetter(b)) {
00028 return true;
00029 }
00030 else {
00031 return false;
00032 }
00033 }
00034
00035 unsigned SelectBestToImprove::selectIndToImprove(deque<tIndividualReal*> &individuals) {
00036 deque<tIndividualReal*>::iterator elem;
00037
00038 assert(individuals.size()>0);
00039
00040 elem = min_element(individuals.begin(), individuals.end(), isBetter);
00041
00042 return ( (*elem)->getId());
00043 }
00044
00045 void SelectBestToImprove::getIndsToImprove(PopulationReal *pop, deque<tIndividualReal*> &subpop) {
00046 unsigned popsize = pop->size();
00047 tIndividualReal* ind;
00048 unsigned i, max;
00049
00050 subpop.clear();
00051
00052
00053 for(i = 0, max=0; i < popsize; i++) {
00054 ind = pop->getInd(i);
00055
00056 if (ind->getCount("non_improved")==0 && ind->isEval()) {
00057 subpop.push_back(ind);
00058 max++;
00059 }
00060 }
00061 }
00062
00063 void SelectWithDiversityToImprove::getIndsToImprove(PopulationReal *pop, deque<tIndividualReal*> &subpop) {
00064 unsigned popsize = pop->size();
00065 tIndividualReal* ind;
00066 unsigned i, max;
00067
00068 subpop.clear();
00069 m_previous.clear();
00070
00071
00072 for(i = 0, max=0; i < popsize; i++) {
00073 ind = pop->getInd(i);
00074
00075 if (!ind->isEval()) {
00076 continue;
00077 }
00078
00079 if (ind->getCount("non_improved")==0) {
00080 subpop.push_back(ind);
00081 max++;
00082 }
00083 else {
00084 m_previous.push_back(ind);
00085 }
00086 }
00087 }
00088
00089
00090 class GetDistant {
00091 public:
00092 GetDistant(deque<tIndividualReal*> references) : m_references(references) {}
00093 bool operator()(tIndividualReal *a, tIndividualReal *b) {
00094 double distA, distB;
00095
00096 distA = minDistance(a);
00097 distB = minDistance(b);
00098
00099 if (distA > distB) {
00100 return true;
00101 }
00102 else if (distA < distB) {
00103 return false;
00104 }
00105 else {
00106 return isBetter(a, b);
00107 }
00108 }
00109
00110 double minDistance(tIndividualReal *ind);
00111
00112 private:
00113 deque<tIndividualReal *> m_references;
00114 };
00115
00116 double GetDistant::minDistance(tIndividualReal *ind) {
00117 double dist, distMin=-1;
00118 deque<tIndividualReal*>::iterator pos_ref;
00119 tIndividualReal *ind_ref;
00120
00121 for (pos_ref = m_references.begin(); pos_ref != m_references.end(); ++pos_ref) {
00122 ind_ref = (*pos_ref);
00123
00124 if (ind->isEval()==false) {
00125 continue;
00126 }
00127
00128 if (ind_ref->perf() == ind->perf())
00129 continue;
00130
00131 dist = distreal(ind_ref->sol(), ind->sol());
00132
00133 if (distMin < 0 || dist < distMin) {
00134 distMin = dist;
00135 }
00136
00137 }
00138
00139 return distMin;
00140 }
00141
00142 bool isImproving(tIndividualReal *ind) {
00143 return (ind->getCount("ls") > 0);
00144 }
00145
00146 deque<tIndividualReal*>::iterator more_distant(deque<tIndividualReal*> &individuals, GetDistant &distant) {
00147 deque<tIndividualReal*>::iterator posi, greater;
00148 double dist, distMax;
00149
00150 if (individuals.empty())
00151 return individuals.end();
00152
00153 posi = individuals.begin();
00154 greater = posi;
00155 distMax = distant.minDistance(*greater);
00156 posi++;
00157
00158 while (posi != individuals.end()) {
00159 dist = distant.minDistance(*posi);
00160
00161 if (dist > distMax) {
00162 greater = posi;
00163 distMax = dist;
00164 }
00165 posi++;
00166 }
00167
00168 return greater;
00169 }
00170
00171 unsigned SelectDiverseToImprove::selectIndToImprove(deque<tIndividualReal*> &individuals) {
00172 deque<tIndividualReal*>::iterator elem;
00173
00174 assert(individuals.size()>0);
00175
00176 if (m_previous.empty()) {
00177 elem = min_element(individuals.begin(), individuals.end(), isBetter);
00178 }
00179 else {
00180 elem = find_if(individuals.begin(), individuals.end(), isImproving);
00181
00182 if (elem == individuals.end()) {
00183 GetDistant distant(m_previous);
00184 elem = more_distant(individuals, distant);
00185 }
00186 }
00187
00188 return ( (*elem)->getId());
00189 }
00190
00191 class SortInd{
00192 public:
00193 bool operator()(tIndividualReal *a, tIndividualReal *b) {
00194 if (a->isEval() && b->isEval())
00195 return (a->isBetter(b));
00196 else if (a->isEval())
00197 return true;
00198 else
00199 return false;
00200 }
00201 };
00202
00203
00204 unsigned SelectDistantBestToImprove::selectIndToImprove(deque<tIndividualReal*> &individuals) {
00205 deque<tIndividualReal*>::iterator elem;
00206 unsigned elem_id;
00207
00208 assert(individuals.size()>0);
00209
00210 if (m_previous.empty()) {
00211 elem = min_element(individuals.begin(), individuals.end(), isBetter);
00212 elem_id = (*elem)->getId();
00213 }
00214 else {
00215 elem = find_if(individuals.begin(), individuals.end(), isImproving);
00216 deque<tIndividualReal*>::iterator posi_max;
00217
00218 if (elem != individuals.end()) {
00219 elem_id = (*elem)->getId();
00220 }
00221 else {
00222 vector<tIndividualReal*> list_bests(individuals.size());
00223 vector<tIndividualReal*>::iterator elem_dist;
00224 unsigned max = m_maxbests;
00225
00226 if (max > individuals.size()) {
00227 max = individuals.size();
00228 }
00229
00230 copy(individuals.begin(), individuals.end(), list_bests.begin());
00231 partial_sort(list_bests.begin(), list_bests.begin()+max, list_bests.end(), SortInd());
00232 GetDistant distant(m_previous);
00233 elem_dist = min_element(list_bests.begin(), list_bests.begin()+max, distant);
00234 elem_id = (*elem_dist)->getId();
00235 }
00236 }
00237
00238 return elem_id;
00239 }
00240
00241 unsigned SelectBestDistantToImprove::selectIndToImprove(deque<tIndividualReal*> &individuals) {
00242 deque<tIndividualReal*>::iterator elem;
00243 unsigned elem_id;
00244
00245 assert(individuals.size()>0);
00246
00247 if (m_previous.empty()) {
00248 elem = min_element(individuals.begin(), individuals.end(), isBetter);
00249 elem_id = (*elem)->getId();
00250 }
00251 else {
00252 elem = find_if(individuals.begin(), individuals.end(), isImproving);
00253 deque<tIndividualReal*>::iterator posi_max;
00254
00255 if (elem != individuals.end()) {
00256 elem_id = (*elem)->getId();
00257 }
00258 else {
00259 vector<tIndividualReal*> list_bests(individuals.size());
00260 vector<tIndividualReal*>::iterator elem_dist;
00261 unsigned max = m_maxdists;
00262
00263 if (max > individuals.size()) {
00264 max = individuals.size();
00265 }
00266
00267
00268 copy(individuals.begin(), individuals.end(), list_bests.begin());
00269
00270 GetDistant distant(m_previous);
00271 partial_sort(list_bests.begin(), list_bests.begin()+max, list_bests.end(), distant);
00272 elem_dist = min_element(list_bests.begin(), list_bests.begin()+max, SortInd());
00273 elem_id = (*elem_dist)->getId();
00274 }
00275 }
00276
00277 return elem_id;
00278 }
00279