Generated on Mon Aug 25 11:35:33 2008 for Gecode by doxygen 1.5.6

example.icc

Go to the documentation of this file.
00001 /* -*- mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- */
00002 /*
00003  *  Main authors:
00004  *     Christian Schulte <schulte@gecode.org>
00005  *
00006  *  Copyright:
00007  *     Christian Schulte, 2004
00008  *
00009  *  Last modified:
00010  *     $Date: 2008-07-11 10:45:19 +0200 (Fri, 11 Jul 2008) $ by $Author: tack $
00011  *     $Revision: 7344 $
00012  *
00013  *  This file is part of Gecode, the generic constraint
00014  *  development environment:
00015  *     http://www.gecode.org
00016  *
00017  *
00018  *  Permission is hereby granted, free of charge, to any person obtaining
00019  *  a copy of this software and associated documentation files (the
00020  *  "Software"), to deal in the Software without restriction, including
00021  *  without limitation the rights to use, copy, modify, merge, publish,
00022  *  distribute, sublicense, and/or sell copies of the Software, and to
00023  *  permit persons to whom the Software is furnished to do so, subject to
00024  *  the following conditions:
00025  *
00026  *  The above copyright notice and this permission notice shall be
00027  *  included in all copies or substantial portions of the Software.
00028  *
00029  *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
00030  *  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
00031  *  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
00032  *  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
00033  *  LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
00034  *  OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
00035  *  WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
00036  *
00037  */
00038 
00039 #include <iostream>
00040 #include <iomanip>
00041 
00042 #include <ctime>
00043 #include <cmath>
00044 
00045 namespace {
00046 
00051   class FailTimeStop : public Search::Stop {
00052   private:
00053     Search::TimeStop *ts; 
00054     Search::FailStop *fs; 
00055 
00056     FailTimeStop(int fails, int time) {
00057       ts = new Search::TimeStop(time);
00058       fs = new Search::FailStop(fails);
00059     }
00060   public:
00062     virtual bool stop(const Search::Statistics& s) {
00063       return fs->stop(s) || ts->stop(s);
00064     }
00066     static Search::Stop* create(unsigned int fail, unsigned int time) {
00067       if ((fail == 0) && (time == 0)) 
00068         return NULL;
00069       if (fail == 0) 
00070         return new Search::TimeStop(time);
00071       if (time  == 0) 
00072         return new Search::FailStop(fail);
00073       return new FailTimeStop(fail,time);
00074     }
00075   };
00076 
00078   class Timer {
00079   private:
00080     clock_t t0; 
00081   public:
00083     void start(void) {
00084       t0 = clock();
00085     }
00087     double stop(void) {
00088       return (static_cast<double>(clock()-t0) / CLOCKS_PER_SEC) * 1000.0;
00089     }
00091     void stop(std::ostream& os) {
00092       double t = stop();
00093       double sec = floor(t / 1000.0);
00094       int o_msec = static_cast<int>(t - 1000.0*sec);
00095       double min = floor(sec / 60.0);
00096       int o_sec = static_cast<int>(sec - 60.0*min);
00097       double hour = floor(min / 60.0);
00098       int o_min = static_cast<int>(min - 60.0*hour);
00099       double day = floor(hour / 24.0);
00100       int o_hour = static_cast<int>(hour - 24.0*day);
00101       int o_day = static_cast<int>(day);
00102       if (o_day)
00103         os << o_day << " days, ";
00104       if (o_hour)
00105         os << o_hour << ":";
00106       if (o_min) {
00107         if (o_hour) {
00108           os.width(2); os.fill('0');
00109         }
00110         os << o_min << ":";
00111         os.width(2); os.fill('0');
00112       }
00113       os << o_sec << ".";
00114       os.width(3); os.fill('0');
00115       os << o_msec
00116          << " ("
00117          << std::showpoint << std::fixed
00118          << std::setprecision(6) << t << " ms)";
00119     }
00120   };
00121   
00122 }
00123 
00124 
00129 double
00130 am(double t[], int n);
00131 
00136 double
00137 dev(double t[], int n);
00138 
00139 #ifdef GECODE_HAS_GIST
00140 
00144 template <class Engine>
00145 class GistEngine {
00146 };
00147 
00149 template <typename S>
00150 class GistEngine<DFS<S> > {
00151 public:
00152   static void explore(S* root, Gist::Inspector* i) {
00153     (void) Gecode::explore(root, i);
00154   }
00155 };
00156 
00158 template <typename S>
00159 class GistEngine<LDS<S> > {
00160 public:
00161   static void explore(S* root, Gist::Inspector* i) {
00162     (void) Gecode::explore(root, i);
00163   }
00164 };
00165 
00167 template <typename S>
00168 class GistEngine<BAB<S> > {
00169 public:
00170   static void explore(S* root, Gist::Inspector* i) {
00171     (void) exploreBest(root, i);
00172   }
00173 };
00174 
00176 template <typename S>
00177 class GistEngine<Restart<S> > {
00178 public:
00179   static void explore(S* root, Gist::Inspector* i) {
00180     (void) exploreBest(root, i);
00181   }
00182 };
00183 
00184 #endif
00185 
00186 template <class Script, template<class> class Engine, class Options>
00187 void
00188 Example::run(const Options& o) {
00189   using namespace std;
00190   try {
00191     switch (o.mode()) {
00192     case EM_SOLUTION:
00193       {
00194         cout << o.name() << endl;
00195         Timer t;
00196         int i = o.solutions();
00197         t.start();
00198         Script* s = new Script(o);
00199         unsigned int n_p = s->propagators();
00200         unsigned int n_b = s->branchings();
00201         unsigned long int p = 0;
00202         Search::Options so;
00203         so.c_d  = o.c_d();
00204         so.a_d  = o.a_d();
00205         so.stop = FailTimeStop::create(o.fail(), o.time());
00206         Engine<Script> e(s,so);
00207         delete s;
00208         do {
00209           Example* ex = e.next();
00210           if (ex == NULL)
00211             break;
00212           ex->print(std::cout);
00213           delete ex;
00214         } while (--i != 0);
00215         Search::Statistics stat = e.statistics();
00216         cout << endl;
00217         cout << "Initial" << endl
00218              << "\tpropagators:   " << n_p << endl
00219              << "\tbranchings:    " << n_b << endl
00220              << endl
00221              << "Summary" << endl
00222              << "\truntime:       ";
00223         t.stop(cout); 
00224         cout << endl
00225              << "\tsolutions:     " 
00226              << abs(static_cast<int>(o.solutions()) - i) << endl
00227              << "\tpropagations:  " << p+stat.propagate << endl
00228              << "\tfailures:      " << stat.fail << endl
00229              << "\tclones:        " << stat.clone << endl
00230              << "\tcommits:       " << stat.commit << endl
00231              << "\tpeak memory:   "
00232              << static_cast<int>((stat.memory+1023) / 1024) << " KB"
00233              << endl;
00234       }
00235       break;
00236     case EM_STAT:
00237       {
00238         cout << o.name() << endl;
00239         int i = o.solutions();
00240         Script* s = new Script(o);
00241         unsigned int n_p = s->propagators();
00242         unsigned int n_b = s->branchings();
00243         unsigned long int p = 0;
00244         Search::Options so;
00245         so.c_d  = o.c_d();
00246         so.a_d  = o.a_d();
00247         Engine<Script> e(s,so);
00248         delete s;
00249         do {
00250           Example* ex = e.next();
00251           if (ex == NULL)
00252             break;
00253           delete ex;
00254         } while (--i != 0);
00255         Search::Statistics stat = e.statistics();
00256         cout << endl
00257              << "\tpropagators:   " << n_p << endl
00258              << "\tbranchings:    " << n_b << endl
00259              << "\tsolutions:     " 
00260              << abs(static_cast<int>(o.solutions()) - i) << endl
00261              << "\tpropagations:  " << p+stat.propagate << endl
00262              << "\tfailures:      " << stat.fail << endl
00263              << "\tclones:        " << stat.clone << endl
00264              << "\tcommits:       " << stat.commit << endl
00265              << "\tpeak memory:   "
00266              << static_cast<int>((stat.memory+1023) / 1024) << " KB"
00267              << endl;
00268       }
00269       break;
00270     case EM_TIME:
00271       {
00272         cout << o.name() << endl;
00273         Timer t;
00274         GECODE_AUTOARRAY(double,ts,o.samples());
00275         for (unsigned int s = o.samples(); s--; ) {
00276           t.start();
00277           for (unsigned int k = o.iterations(); k--; ) {
00278             unsigned int i = o.solutions();
00279             Script* s = new Script(o);
00280             Search::Options so;
00281             so.c_d  = o.c_d();
00282             so.a_d  = o.a_d();
00283             Engine<Script> e(s,so);
00284             delete s;
00285             do {
00286               Example* ex = e.next();
00287               if (ex == NULL)
00288                 break;
00289               delete ex;
00290             } while (--i != 0);
00291           }
00292           ts[s] = t.stop() / o.iterations();
00293         }
00294         double m = am(ts,o.samples());
00295         double d = dev(ts,o.samples()) * 100.0;
00296         cout << "\tRuntime: "
00297              << setw(20) << right
00298              << showpoint << fixed
00299              << setprecision(6) << m << "ms"
00300              << setprecision(2) << " (" << d << "% deviation)"
00301              << endl;
00302       }
00303       break;
00304 #ifdef GECODE_HAS_GIST
00305     case EM_GIST:
00306       {
00307         Gist::PrintingInspector<Script> pi(o.name());
00308         Script* s = new Script(o);
00309         (void) GistEngine<Engine<Script> >::explore(s, &pi);
00310         delete s;
00311       }
00312       break;
00313 #endif
00314     }
00315   } catch (Exception e) {
00316     cout << "Exception: " << e.what() << "." << endl
00317          << "Stopping..." << endl;
00318   }
00319 }
00320 
00321 // STATISTICS: example-any