Generated on Mon Jul 6 18:09:02 2009 for Gecode by doxygen 1.5.9

script.hpp

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: 2009-05-08 20:20:47 +0200 (Fri, 08 May 2009) $ by $Author: schulte $
00011  *     $Revision: 9046 $
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 <gecode/support/timer.hh>
00040 
00041 #include <iostream>
00042 #include <iomanip>
00043 
00044 namespace Gecode { namespace Driver {
00045 
00050   class Cutoff : public Search::Stop {
00051   private:
00052     Search::NodeStop* ns; 
00053     Search::FailStop* fs; 
00054     Search::TimeStop* ts; 
00055 
00056     Cutoff(unsigned int node, unsigned int fail, unsigned int time)
00057       : ns((node > 0) ? new Search::NodeStop(node) : NULL),
00058         fs((fail > 0) ? new Search::FailStop(fail) : NULL),
00059         ts((time > 0) ? new Search::TimeStop(time) : NULL) {}
00060   public:
00062     virtual bool stop(const Search::Statistics& s, const Search::Options& o) {
00063       return
00064         ((ns != NULL) && ns->stop(s,o)) ||
00065         ((fs != NULL) && fs->stop(s,o)) ||
00066         ((ts != NULL) && ts->stop(s,o));
00067     }
00069     static Search::Stop*
00070     create(unsigned int node, unsigned int fail, unsigned int time) {
00071       if ((node == 0) && (fail == 0) && (time == 0))
00072         return NULL;
00073       else
00074         return new Cutoff(node,fail,time);
00075     }
00077     ~Cutoff(void) {
00078       delete ns; delete fs; delete ts;
00079     }
00080   };
00081 
00086   GECODE_DRIVER_EXPORT void 
00087   stop(Support::Timer& t, std::ostream& os);
00088 
00092   GECODE_DRIVER_EXPORT double
00093   am(double t[], int n);
00094   
00098   GECODE_DRIVER_EXPORT double
00099   dev(double t[], int n);
00100   
00101 #ifdef GECODE_HAS_GIST
00102   
00106   template <class Engine>
00107   class GistEngine {
00108   };
00109   
00111   template <typename S>
00112   class GistEngine<DFS<S> > {
00113   public:
00114     static void explore(S* root, const Gist::Options& opt) {
00115       (void) Gist::dfs(root, opt);
00116     }
00117   };
00118   
00120   template <typename S>
00121   class GistEngine<LDS<S> > {
00122   public:
00123     static void explore(S* root, const Gist::Options& opt) {
00124       (void) Gist::dfs(root, opt);
00125     }
00126   };
00127   
00129   template <typename S>
00130   class GistEngine<BAB<S> > {
00131   public:
00132     static void explore(S* root, const Gist::Options& opt) {
00133       (void) Gist::bab(root, opt);
00134     }
00135   };
00136   
00138   template <typename S>
00139   class GistEngine<Restart<S> > {
00140   public:
00141     static void explore(S* root, const Gist::Options& opt) {
00142       (void) Gist::bab(root, opt);
00143     }
00144   };
00145   
00146 #endif
00147 
00148   template <class Space>
00149   template <class Script, template<class> class Engine, class Options>
00150   void
00151   ScriptBase<Space>::run(const Options& o) {
00152     using namespace std;
00153     try {
00154       switch (o.mode()) {
00155       case SM_GIST:
00156 #ifdef GECODE_HAS_GIST
00157         {
00158           Gist::Print<Script> pi(o.name());
00159           Gist::Options opt;
00160           opt.inspect.click(&pi);
00161           opt.clone = false;
00162           opt.c_d   = o.c_d();
00163           opt.a_d   = o.a_d();
00164           Script* s = new Script(o);
00165           (void) GistEngine<Engine<Script> >::explore(s, opt);
00166         }
00167         break;
00168         // If Gist is not available, fall through
00169 #endif
00170       case SM_SOLUTION:
00171         {
00172           cout << o.name() << endl;
00173           Support::Timer t;
00174           int i = o.solutions();
00175           t.start();
00176           Script* s = new Script(o);
00177           unsigned int n_p = s->propagators();
00178           unsigned int n_b = s->branchings();
00179           Search::Options so;
00180           so.threads = o.threads();
00181           so.c_d     = o.c_d();
00182           so.a_d     = o.a_d();
00183           so.stop    = Cutoff::create(o.node(),o.fail(), o.time());
00184           so.clone   = false;
00185           Engine<Script> e(s,so);
00186           do {
00187             Script* ex = e.next();
00188             if (ex == NULL)
00189               break;
00190             ex->print(std::cout);
00191             delete ex;
00192           } while (--i != 0);
00193           Search::Statistics stat = e.statistics();
00194           cout << endl;
00195           cout << "Initial" << endl
00196                << "\tpropagators:  " << n_p << endl
00197                << "\tbranchings:   " << n_b << endl
00198                << endl
00199                << "Summary" << endl
00200                << "\truntime:      ";
00201           stop(t, cout);
00202           cout << endl
00203                << "\tsolutions:    "
00204                << ::abs(static_cast<int>(o.solutions()) - i) << endl
00205                << "\tpropagations: " << stat.propagate << endl
00206                << "\tnodes:        " << stat.node << endl
00207                << "\tfailures:     " << stat.fail << endl
00208                << "\tpeak depth:   " << stat.depth << endl
00209                << "\tpeak memory:  "
00210                << static_cast<int>((stat.memory+1023) / 1024) << " KB"
00211                << endl;
00212         }
00213         break;
00214       case SM_STAT:
00215         {
00216           cout << o.name() << endl;
00217           Support::Timer t;
00218           int i = o.solutions();
00219           t.start();
00220           Script* s = new Script(o);
00221           unsigned int n_p = s->propagators();
00222           unsigned int n_b = s->branchings();
00223           Search::Options so;
00224           so.clone   = false;
00225           so.threads = o.threads();
00226           so.c_d     = o.c_d();
00227           so.a_d     = o.a_d();
00228           so.stop    = Cutoff::create(o.node(),o.fail(), o.time());
00229           Engine<Script> e(s,so);
00230           do {
00231             Script* ex = e.next();
00232             if (ex == NULL)
00233               break;
00234             delete ex;
00235           } while (--i != 0);
00236           Search::Statistics stat = e.statistics();
00237           cout << endl
00238                << "\tpropagators:  " << n_p << endl
00239                << "\tbranchings:   " << n_b << endl
00240                << "\truntime:      ";
00241           stop(t, cout);
00242           cout << endl
00243                << "\tsolutions:    "
00244                << ::abs(static_cast<int>(o.solutions()) - i) << endl
00245                << "\tpropagations: " << stat.propagate << endl
00246                << "\tnodes:        " << stat.node << endl
00247                << "\tfailures:     " << stat.fail << endl
00248                << "\tpeak depth:   " << stat.depth << endl
00249                << "\tpeak memory:  "
00250                << static_cast<int>((stat.memory+1023) / 1024) << " KB"
00251                << endl;
00252         }
00253         break;
00254       case SM_TIME:
00255         {
00256           cout << o.name() << endl;
00257           Support::Timer t;
00258           double* ts = new double[o.samples()];
00259           for (unsigned int s = o.samples(); s--; ) {
00260             t.start();
00261             for (unsigned int k = o.iterations(); k--; ) {
00262               unsigned int i = o.solutions();
00263               Script* s = new Script(o);
00264               Search::Options so;
00265               so.clone   = false;
00266               so.threads = o.threads();
00267               so.c_d     = o.c_d();
00268               so.a_d     = o.a_d();
00269               so.stop    = Cutoff::create(o.node(),o.fail(), o.time());
00270               Engine<Script> e(s,so);
00271               do {
00272                 Script* ex = e.next();
00273                 if (ex == NULL)
00274                   break;
00275                 delete ex;
00276               } while (--i != 0);
00277             }
00278             ts[s] = t.stop() / o.iterations();
00279           }
00280           double m = am(ts,o.samples());
00281           double d = dev(ts,o.samples()) * 100.0;
00282           delete[] ts;
00283           cout << "\tRuntime: "
00284                << setw(20) << right
00285                << showpoint << fixed
00286                << setprecision(6) << m << "ms"
00287                << setprecision(2) << " (" << d << "% deviation)"
00288                << endl;
00289         }
00290         break;
00291       }
00292     } catch (Exception e) {
00293       cout << "Exception: " << e.what() << "." << endl
00294            << "Stopping..." << endl;
00295     }
00296   }
00297 
00298 }}
00299 
00300 // STATISTICS: driver-any