SatSolverObserver.cpp

Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2008 Kamil Dudka <xdudka00@stud.fit.vutbr.cz>
00003  *
00004  * This file is part of fss (Fast SAT Solver).
00005  *
00006  * fss is free software: you can redistribute it and/or modify
00007  * it under the terms of the GNU General Public License as published by
00008  * the Free Software Foundation, either version 3 of the License, or
00009  * any later version.
00010  *
00011  * fss is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  * GNU General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU General Public License
00017  * along with fss.  If not, see <http://www.gnu.org/licenses/>.
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   // SolutionsCountStop implementation
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   // TimedStop implementation
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   // FitnessWatch implementation
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       // Fitness not changed
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     // Save maxFitness for next call
00109     d->maxFitness = maxFitness;
00110 
00111     // Read other statistics
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   // ResultsWatch implementation
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     // Check percentage value
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     // Write out message
00193     d->stream
00194       << Color(C_GREEN) << "--- Progress:"
00195       << std::setw(3) << percents << "%"
00196       << Color() << std::endl;
00197   }
00198 
00199 } // namespace FastSatSolver
00200 

Generated on Wed Nov 5 22:30:22 2008 for Fast SAT Solver by  doxygen 1.5.4