nucad.cpp

Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2009 Kamil Dudka <xdudka00@stud.fit.vutbr.cz>
00003  *
00004  * This file is part of nucad (Non-Uniform CA Designer).
00005  *
00006  * nucad 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  * nucad 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 nucad.  If not, see <http://www.gnu.org/licenses/>.
00018  */
00019 
00024 #include "config.h"
00025 #include "CaDesigner.h"
00026 #include "CaFactory.h"
00027 #include "Color.h"
00028 
00029 #ifndef BUILDING_DOX
00030 #   include <iostream>
00031 #   include <iomanip>
00032 #   include <stdexcept>
00033 #   include <string>
00034 #endif
00035 
00036 #include <ga/GAStatistics.h>
00037 
00038 using std::string;
00039 
00048 template <typename OBSERVER, typename SUBJECT, typename ARG>
00049 inline OBSERVER* createAttached(SUBJECT *subject, ARG &arg) {
00050     OBSERVER *observer = new OBSERVER(subject, arg);
00051     subject->addObserver(observer);
00052     return observer;
00053 }
00054 
00055 int main(int argc, char *argv[]) {
00056     // colorize stderr output if stderr is connected to terminal
00057     // no matter if stdout is or is not connected to terminal
00058     Color::enable(isatty(STDERR_FILENO));
00059 
00060     // TODO: use getopt_long instead of hard-wired src/config.h options
00061     static const int minSlns = GA_MIN_SLNS;
00062     static const int maxSlns = GA_MAX_SLNS;
00063     static const int maxRuns = GA_MAX_RUNS;
00064     static const int maxTime = GA_MAX_TIME_PER_RUN;
00065 
00066     // create factory on stack (it helps to avoid memory leaks)
00067     CaEvaluatorFactory factory;
00068     const char *circuit = "\"\"";
00069 
00070     // TODO: use getopt_long and full-featured --help output
00071     if (1 < argc) {
00072         if (2 < argc || string("--help")==string(argv[1])) {
00073             std::cerr << "Usage: " << argv[0] << " CIRCUIT_NAME" << std::endl;
00074             return 1;
00075         }
00076         circuit = argv[1];
00077     }
00078 
00079     // Used for final clean-up on exit
00080     int ec = 0;
00081     CaEvaluator         *evaluator          = 0;
00082     CaDesigner          *designer           = 0;
00083     SolutionsCountStop  *slnsCountStop      = 0;
00084     TimedStop           *timedStop          = 0;
00085     FitnessWatch        *fitnessWatch       = 0;
00086     ResultsWatch        *resultsWatch       = 0;
00087 
00088     try {
00089         // try to create evaluator for desired circuit
00090         // this might fail if circuit name is not valid
00091         evaluator = factory.create(circuit);
00092 
00093         // create GAlib-powered CA designer
00094         designer = CaDesigner::create(evaluator);
00095 
00096         // display message if maxFitness is increased
00097         fitnessWatch = createAttached<FitnessWatch>(designer, std::cerr);
00098 
00099         // display message if solution is discovered
00100         resultsWatch = createAttached<ResultsWatch>(designer, std::cerr);
00101 
00102         // stop progress after maxSlns solutions are found
00103         slnsCountStop = createAttached<SolutionsCountStop>(designer, maxSlns);
00104 
00105         if (maxTime)
00106             // nun will be stopped if its time exceeds
00107             timedStop = createAttached<TimedStop>(designer, maxTime);
00108 
00109         // grand total
00110         int totalSolutions = 0;
00111         float totalTime = 0.0;
00112 
00113         // for each run...
00114         for (int i = 0; i < maxRuns && totalSolutions < minSlns; i++) {
00115             std::cerr << Color(C_LIGHT_GREEN)
00116                 << ">>> Run " << std::setw(6) << i+1
00117                 << " of " << std::setw(6) << maxRuns
00118                 << Color(C_NO_COLOR) << std::endl;
00119 
00120             // initialization
00121             designer->reset();
00122             fitnessWatch->reset();
00123 
00124             // run designer
00125             designer->start();
00126 
00127             // update solutions count
00128             const int runSolutions= designer->getSolutionsCount() - totalSolutions;
00129             totalSolutions+= runSolutions;
00130 
00131             // update elapsed time
00132             const float timeElapsed= designer->getTimeElapsed()/1000.0;
00133             totalTime+= timeElapsed;
00134 
00135             // print partial statistics
00136             std::cerr << Color(C_LIGHT_GREEN)
00137                 << "--- Found " << std::setw(6) << runSolutions << " solutions"
00138                 << " in " << FixedFloat(6,2) << timeElapsed << " s"
00139                 << Color(C_NO_COLOR) << std::endl;
00140 
00141             // print up-to-now total statistics
00142             if (1 < maxRuns)
00143                 std::cerr << Color(C_LIGHT_RED)
00144                     << "--- Total " << std::setw(6) << totalSolutions
00145                     << " solutions in " << FixedFloat(6,2) << totalTime << " s"
00146                     << Color(C_NO_COLOR) << std::endl << std::endl;
00147 
00148             // end of run
00149         }
00150 
00151 #if GA_VERBOSE_MODE
00152         // print GAlib statistics in verbose mode
00153         // TODO: turn on this by cmd-line argument
00154         GAStatistics stats = designer->getStatistics();
00155         std::cerr << std::endl << Color(C_YELLOW) << stats << Color() << std::endl;
00156 #endif
00157     }
00158     catch (std::runtime_error &e) {
00159         std::cerr << argv[0] << ": "
00160             << Color(C_LIGHT_RED) << "error: " << Color(C_NO_COLOR)
00161             << e.what() << std::endl;
00162         ec = 1;
00163     }
00164 
00165     // destroy objects in reverse order
00166     delete resultsWatch;
00167     delete fitnessWatch;
00168     delete timedStop;
00169     delete slnsCountStop;
00170     delete designer;
00171     delete evaluator;
00172 
00173     return ec;
00174 }
00175 

Generated on Sat May 2 16:39:31 2009 for nucad by  doxygen 1.5.4