00001
00002
00003
00004
00005
00006
00007 #ifndef INCLUDE__CONTROL_H__FILE
00008 #define INCLUDE__CONTROL_H__FILE
00009
00010 #include "defs.h"
00011 #include "env.h"
00012 #include "EGMeasure.h"
00013 #include "EGRandom.h"
00014 #include "EGTCrossover.h"
00015 #include "EGTElitistSel.h"
00016 #include "EGTEvaluation.h"
00017 #include "EGTMutation.h"
00018 #include "EGTRouletteSel.h"
00019 #include "EGTSelection.h"
00020 #include "EGTVector.h"
00021 #include "EGFileIO.h"
00022 #include <iostream>
00023 #include <fstream>
00024
00030 template<class TP>
00031 class EGTControl {
00032 public:
00033 typedef TP Pop;
00034 typedef typename Pop::Graph Graph;
00035 typedef EGTVector<const Graph*> Graphs;
00036 typedef typename Graph::SubGraph SubGraph;
00037 typedef typename Graph::Node Node;
00038 typedef typename Graph::Fitness Fitness;
00039
00040 EGTControl();
00041 virtual ~EGTControl();
00042
00043 virtual void InitControl();
00044 virtual void LoadControl();
00045 virtual void SaveControl() const;
00046 virtual void LoadTarget(const char* filename) = 0;
00047
00049 virtual void SetEvaluation(EGTEvaluation<TP>* =0) = 0;
00050 virtual void SetSelection(EGTSelection<TP>* =0);
00051 virtual void SetSelection2(EGTSelection<TP>* =0);
00052 virtual void SetMutation(EGTMutation<TP>* =0);
00053 virtual void SetCrossover(EGTCrossover<TP>* =0);
00054 virtual void Execute(std::ostream&);
00055
00056 protected:
00058 enum MeasureOp {START, STOP, LAP};
00059
00060 virtual void NextGeneration();
00061
00062 void SaveLogFiles(UInt, MeasureOp);
00063 void SaveTimeLog(UInt, MeasureOp);
00064 void SaveFitnessLog(UInt) const;
00065 void SavePopLog(UInt) const;
00066 virtual void SaveBestLog(UInt) const;
00067 virtual void SaveBestDot(UInt) const;
00068 virtual void SaveGeneration(UInt) const;
00069
00070 Pop* m_tPop;
00071 EGTEvaluation<TP>* m_tEvaluation;
00072 EGTSelection<TP>* m_tSelection;
00073 EGTSelection<TP>* m_tSelection2;
00074 EGTMutation<TP>* m_tMutation;
00075 EGTCrossover<TP>* m_tCrossover;
00076 EGMeasure m_tMeasure;
00077
00079 Node m_Creator;
00081 bool m_bEvolved;
00082 };
00083
00084
00088 template<class TP>
00089 EGTControl<TP>::EGTControl()
00090 : m_tPop(0), m_tEvaluation(0), m_tSelection(0), m_tSelection2(0),
00091 m_tMutation(0), m_tCrossover(0), m_Creator(0, 0, 0), m_bEvolved(false)
00092 {
00093 }
00094
00095
00099 template<class TP>
00100 EGTControl<TP>::~EGTControl()
00101 {
00102 delete m_tPop;
00103 delete m_tEvaluation;
00104 delete m_tSelection;
00105 delete m_tSelection2;
00106 delete m_tMutation;
00107 delete m_tCrossover;
00108 }
00109
00110
00114 template<class TP>
00115 void EGTControl<TP>::InitControl()
00116 {
00117 Graph::m_tCreator = &m_Creator;
00118 SubGraph::m_tCreator = &m_Creator;
00119 m_tPop = new Pop;
00120 m_tPop->InitPopulation();
00121 m_tPop->AssignGraphID();
00122 m_bEvolved = true;
00123 }
00124
00125
00133 template<class TP>
00134 void EGTControl<TP>::SetSelection(EGTSelection<TP>* ps)
00135 {
00136 delete m_tSelection;
00137 m_tSelection = (ps) ? ps : new EGTRouletteSel<TP>;
00138 }
00139
00140
00147 template<class TP>
00148 void EGTControl<TP>::SetSelection2(EGTSelection<TP>* ps)
00149 {
00150 delete m_tSelection2;
00151 m_tSelection2 = (ps) ? ps : new EGTElitistSel<TP>;
00152 }
00153
00154
00159 template<class TP>
00160 void EGTControl<TP>::SetMutation(EGTMutation<TP>* pm)
00161 {
00162 delete m_tMutation;
00163 m_tMutation = (pm) ? pm : new EGTMutation<TP>;
00164 }
00165
00166
00171 template<class TP>
00172 void EGTControl<TP>::SetCrossover(EGTCrossover<TP>* pc)
00173 {
00174 delete m_tCrossover;
00175 m_tCrossover = (pc) ? pc : new EGTCrossover<TP>;
00176 }
00177
00178
00183 template<class TP>
00184 void EGTControl<TP>::Execute(std::ostream& out)
00185 {
00186 std::cout << '\n';
00187 out << '\n';
00188 Env::Instance().Display(std::cout);
00189 Env::Instance().Display(out);
00190 std::cout << "\nNow evolving... " << std::flush;
00191 out << "\nNow evolving... " << std::flush;
00192
00193 SetEvaluation();
00194 SetSelection();
00195 SetSelection2();
00196 SetCrossover();
00197 SetMutation();
00198
00199 const UInt uMaxGen = Env::Instance().MaxGeneration();
00200
00201 m_tEvaluation->Evaluate(*m_tPop);
00202 SaveLogFiles(Env::Instance().CurrentGeneration(), START);
00203
00204 for (UInt i=0; i<uMaxGen; ++i) {
00205 NextGeneration();
00206 SaveLogFiles(Env::Instance().CurrentGeneration(), LAP);
00207 if (Interruption) {
00208 Env::Instance().SetGeneratePopSave(true);
00209 break;
00210 }
00211 }
00212 SaveLogFiles(Env::Instance().CurrentGeneration(), STOP);
00213
00214 std::cout << "done\n" << std::endl;
00215 out << "done\n" << std::endl;
00216 Env::Instance().Display(std::cout);
00217 Env::Instance().Display(out);
00218 std::cout << '\n';
00219 out << '\n';
00220 }
00221
00222
00237 template<class TP>
00238 void EGTControl<TP>::NextGeneration()
00239 {
00240 Env::Instance().NextGeneration();
00241 UInt oldFit = (UInt)(m_tPop->GetBestGraph()->GetFitness() * 10000.0);
00242
00243 Graphs tTempGraphs;
00244 Pop* ptNextPop = new Pop;
00245 UInt uPopSize = Env::Instance().PopSize();
00246 m_tSelection->Selection(*m_tPop, tTempGraphs, uPopSize);
00247 m_tCrossover->Crossover(tTempGraphs, *ptNextPop);
00248 m_tMutation->Mutation(tTempGraphs, *ptNextPop);
00249
00250 Int rest = uPopSize - ptNextPop->GetNumGraphs();
00251 if (rest > 0) {
00252 m_tSelection2->Selection(*m_tPop, *ptNextPop, rest);
00253 }
00254 ptNextPop->AssignGraphID();
00255 m_tEvaluation->Evaluate(*ptNextPop);
00256 delete m_tPop;
00257 m_tPop = ptNextPop;
00258
00259 UInt newFit = (UInt)(m_tPop->GetBestGraph()->GetFitness() * 10000.0);
00260 m_bEvolved = (newFit > oldFit) ? true : false;
00261 }
00262
00263
00267 template<class TP>
00268 void EGTControl<TP>::LoadControl()
00269 {
00270 Graph::m_tCreator = &m_Creator;
00271 SubGraph::m_tCreator = &m_Creator;
00272 m_tPop = new Pop;
00273 m_tPop->LoadPopulation();
00274 m_tPop->AssignGraphID();
00275
00276 const std::string name = EGFileIO::GetSeedFileName();
00277 EGRandom::LoadSeed(name.c_str());
00278 Env::Instance().LoadEnvironment();
00279 }
00280
00281
00285 template<class TP>
00286 void EGTControl<TP>::SaveControl() const
00287 {
00288 m_tPop->SavePopulation();
00289
00290 const std::string name = EGFileIO::GetSeedFileName();
00291 EGRandom::SaveSeed(name.c_str());
00292 Env::Instance().SaveEnvironment();
00293 }
00294
00295
00305 template<class TP>
00306 void EGTControl<TP>::SaveLogFiles(UInt i, MeasureOp op)
00307 {
00308 SaveTimeLog(i, op);
00309 SaveFitnessLog(i);
00310 SavePopLog(i);
00311 SaveBestLog(i);
00312 SaveBestDot(i);
00313 SaveGeneration(i);
00314 }
00315
00316
00322 template<class TP>
00323 void EGTControl<TP>::SaveFitnessLog(UInt i) const
00324 {
00325 if (Env::Instance().GenerateFitnessLog() == false) {
00326 return;
00327 }
00328 const std::string name = EGFileIO::GetFitnessLogFileName();
00329 std::ofstream fout;
00330 if (i == 0) {
00331 fout.open(name.c_str());
00332 }
00333 else {
00334 fout.open(name.c_str(), std::ios::out|std::ios::app);
00335 }
00336 if (!fout) {
00337 throw EGException("Can't open file", __FILE__, __LINE__);
00338 }
00339 if (i == 0) {
00340 fout << "Gen.\tAvg.\tMax(";
00341 m_tPop->GetBestGraph()->DisplayFitness(fout, true);
00342 fout << ")\n";
00343 }
00344
00345 fout << i << '\t' << m_tPop->GetFitnessAvg() << '\t';
00346 m_tPop->GetBestGraph()->DisplayFitness(fout, false);
00347 fout << std::endl;
00348 fout.close();
00349 }
00350
00351
00357 template<class TP>
00358 void EGTControl<TP>::SaveTimeLog(UInt i, MeasureOp ope)
00359 {
00360 if (Env::Instance().GenerateTimeLog() == false) {
00361 return;
00362 }
00363 const std::string name = EGFileIO::GetTimeLogFileName();
00364 std::ofstream fout;
00365 if (i == 0) {
00366 fout.open(name.c_str());
00367 }
00368 else {
00369 fout.open(name.c_str(), std::ios::out|std::ios::app);
00370 }
00371 if (!fout) {
00372 throw EGException("Can't open file", __FILE__, __LINE__);
00373 }
00374 if (ope == START) {
00375 m_tMeasure.Start(fout);
00376 }
00377 else if (ope == LAP) {
00378 fout << i << '\t';
00379 m_tMeasure.Lap(fout);
00380 }
00381 else if (ope == STOP) {
00382 fout << "#Sum\t";
00383 m_tMeasure.Stop(fout);
00384 }
00385 fout.close();
00386 }
00387
00388
00396 template<class TP>
00397 void EGTControl<TP>::SaveGeneration(UInt n) const
00398 {
00399 if (Env::Instance().GenerateEachGeneration() == false) {
00400 return;
00401 }
00402
00403 const std::string dir = EGFileIO::GetGenDirectoryName(n);
00404 EGFileIO::MakeDirectory(dir.c_str());
00405
00406 UInt num_graphs = m_tPop->GetNumGraphs();
00407 for (UInt i=0; i<num_graphs; ++i) {
00408 const std::string name = EGFileIO::GetDotFileName(dir.c_str(), n, i);
00409 std::ofstream fout(name.c_str());
00410 if (!fout) {
00411 throw EGException("Can't open file", __FILE__, __LINE__);
00412 }
00413 m_tPop->GetGraph(i)->DisplayDot(fout);
00414 fout.close();
00415
00416 const std::string name2 = EGFileIO::GetLogFileName(dir.c_str(), n, i);
00417 std::ofstream fout2(name2.c_str());
00418 if (!fout2) {
00419 throw EGException("Can't open file", __FILE__, __LINE__);
00420 }
00421 m_tPop->GetGraph(i)->Display(fout2);
00422 fout2.close();
00423 }
00424 }
00425
00426
00432 template<class TP>
00433 void EGTControl<TP>::SavePopLog(UInt i) const
00434 {
00435
00436 if (Env::Instance().GeneratePopLog() == false) {
00437 return;
00438 }
00439 const std::string name = EGFileIO::GetPopLogFileName(i);
00440 std::ofstream fout(name.c_str());
00441 if (!fout) {
00442 throw EGException("Can't open file", __FILE__, __LINE__);
00443 }
00444 m_tPop->Display(fout);
00445 }
00446
00447
00453 template<class TP>
00454 void EGTControl<TP>::SaveBestLog(UInt i) const
00455 {
00456 if (m_bEvolved == false || Env::Instance().GenerateBestLog() == false) {
00457 return;
00458 }
00459 const std::string name = EGFileIO::GetBestLogFileName(i);
00460 std::ofstream fout(name.c_str());
00461 if (!fout) {
00462 throw EGException("Can't open file", __FILE__, __LINE__);
00463 }
00464 m_tPop->GetBestGraph()->Display(fout);
00465 }
00466
00467
00478 template<class TP>
00479 void EGTControl<TP>::SaveBestDot(UInt i) const
00480 {
00481 if (m_bEvolved == false || Env::Instance().GenerateDot() == false) {
00482 return;
00483 }
00484 const std::string name = EGFileIO::GetBestDotFileName(i);
00485 std::ofstream fout(name.c_str());
00486 if (!fout) {
00487 throw EGException("Can't open file", __FILE__, __LINE__);
00488 }
00489 m_tPop->GetBestGraph()->DisplayDot(fout);
00490 }
00491
00492 #endif //INCLUDE__CONTROL_H__FILE
00493