00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include <iostream>
00021 #include <iomanip>
00022 #include <ga/GAStatistics.h>
00023 #include "fssIO.h"
00024 #include "SatSolver.h"
00025 #include "GaSatSolver.h"
00026 #include "SatSolverObserver.h"
00027
00028 namespace FastSatSolver {
00029
00030
00031
00032 struct SolutionsCountStop::Private {
00033 AbstractSatSolver *solver;
00034 int minCountOfSolutions;
00035 };
00036 SolutionsCountStop::SolutionsCountStop(AbstractSatSolver *solver, int minCountOfSolutions):
00037 d(new Private)
00038 {
00039 d->solver = solver;
00040 d->minCountOfSolutions = minCountOfSolutions;
00041 }
00042 SolutionsCountStop::~SolutionsCountStop() {
00043 delete d;
00044 }
00045 void SolutionsCountStop::notify() {
00046 const int nSolutions= d->solver->getSolutionsCount();
00047 if (nSolutions >= d->minCountOfSolutions)
00048 d->solver->stop();
00049 }
00050
00051
00052
00053
00054 struct TimedStop::Private {
00055 AbstractProcessWatched *process;
00056 long msec;
00057 };
00058 TimedStop::TimedStop(AbstractProcessWatched *process, long msec):
00059 d(new Private)
00060 {
00061 d->process = process;
00062 d->msec = msec;
00063 }
00064 TimedStop::~TimedStop() {
00065 delete d;
00066 }
00067 void TimedStop::notify() {
00068 long elapsed = d->process->getTimeElapsed();
00069 if (elapsed > d->msec)
00070 d->process->stop();
00071 }
00072
00073
00074
00075
00076 struct FitnessWatch::Private {
00077 AbstractSatSolver *solver;
00078 std::ostream &stream;
00079 float maxFitness;
00080
00081 Private(std::ostream &streamTo): stream(streamTo) { }
00082 };
00083 FitnessWatch::FitnessWatch(AbstractSatSolver *solver, std::ostream &streamTo):
00084 d(new Private(streamTo))
00085 {
00086 d->solver = solver;
00087 d->maxFitness = 0.0;
00088 }
00089 FitnessWatch::~FitnessWatch() {
00090 delete d;
00091 }
00092 void FitnessWatch::notify() {
00093 AbstractSatSolver *solver= d->solver;
00094 float maxFitness = solver->maxFitness();
00095 if (maxFitness <= d->maxFitness)
00096
00097 return;
00098
00099 int generation = 0;
00100 GaSatSolver *gaSolver= dynamic_cast<GaSatSolver *>(solver);
00101 if (gaSolver) {
00102 GAStatistics stats= gaSolver->getStatistics();
00103 generation = stats.generation();
00104 if (0 == generation)
00105 return;
00106 }
00107
00108
00109 d->maxFitness = maxFitness;
00110
00111
00112 const float minFitness= solver->minFitness();
00113 const float avgFitness= solver->avgFitness();
00114 const float timeElapsed= d->solver->getTimeElapsed()/1000.0;
00115
00116 using StreamDecorator::FixedFloat;
00117 d->stream
00118 << "--- satisfaction:" << FixedFloat(3,1) << maxFitness*100.0 << "%"
00119 << "(avg:" << FixedFloat(3,1) << avgFitness*100.0
00120 << ", min:" << FixedFloat(3,1) << minFitness*100.0 << ")"
00121 << ", generation " << std::setw(5) << generation
00122 << ", time elapsed: " << FixedFloat(5,2) << timeElapsed << " s"
00123 << std::endl;
00124 }
00125 void FitnessWatch::reset() {
00126 d->maxFitness = 0.0;
00127 }
00128
00129
00130
00131 struct ResultsWatch::Private {
00132 AbstractSatSolver *solver;
00133 std::ostream &stream;
00134 int nResults;
00135
00136 Private(std::ostream &streamTo): stream(streamTo) { }
00137 };
00138 ResultsWatch::ResultsWatch(AbstractSatSolver *solver, std::ostream &streamTo):
00139 d(new Private(streamTo))
00140 {
00141 d->solver = solver;
00142 d->nResults = 0;
00143 }
00144 ResultsWatch::~ResultsWatch() {
00145 delete d;
00146 }
00147 void ResultsWatch::notify() {
00148 using namespace StreamDecorator;
00149 AbstractSatSolver *solver= d->solver;
00150 const int nResults= solver->getSolutionsCount();
00151 if (nResults <= d->nResults)
00152 return;
00153 d->nResults = nResults;
00154
00155 const float timeElapsed= solver->getTimeElapsed()/1000.0;
00156 d->stream
00157 << Color(C_LIGHT_BLUE) << "--- " << nResults
00158 << ". solution found in " << FixedFloat(5,2) << timeElapsed << " s"
00159 << Color() << std::endl;
00160 }
00161
00162 struct ProgressWatch::Private {
00163 AbstractProcess *process;
00164 int stepsTotal;
00165 int last;
00166 std::ostream &stream;
00167
00168 Private(std::ostream &streamTo): stream(streamTo) { }
00169 };
00170 ProgressWatch::ProgressWatch(AbstractProcess *process, int stepsTotal, std::ostream &streamTo):
00171 d(new Private(streamTo))
00172 {
00173 d->process = process;
00174 d->stepsTotal = stepsTotal;
00175 d->last = 0;
00176 }
00177 ProgressWatch::~ProgressWatch() {
00178 delete d;
00179 }
00180 void ProgressWatch::notify() {
00181 using namespace StreamDecorator;
00182
00183
00184 const int currentStep= d->process->getStepsCount();
00185 const int percents=
00186 currentStep*100 /
00187 d->stepsTotal;
00188 if (percents == d->last)
00189 return;
00190 d->last = percents;
00191
00192
00193 d->stream
00194 << Color(C_GREEN) << "--- Progress:"
00195 << std::setw(3) << percents << "%"
00196 << Color() << std::endl;
00197 }
00198
00199 }
00200