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

branch.cpp

Go to the documentation of this file.
00001 /* -*- mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- */
00002 /*
00003  *  Main authors:
00004  *     Mikael Lagerkvist <lagerkvist@gecode.org>
00005  *
00006  *  Copyright:
00007  *     Mikael Lagerkvist, 2005
00008  *
00009  *  Last modified:
00010  *     $Date: 2009-05-14 00:24:31 +0200 (Thu, 14 May 2009) $ by $Author: tack $
00011  *     $Revision: 9095 $
00012  *
00013  *  This file is part of Gecode, the generic constraint
00014  *  development environment:
00015  *     http://www.gecode.org
00016  *
00017  *  Permission is hereby granted, free of charge, to any person obtaining
00018  *  a copy of this software and associated documentation files (the
00019  *  "Software"), to deal in the Software without restriction, including
00020  *  without limitation the rights to use, copy, modify, merge, publish,
00021  *  distribute, sublicense, and/or sell copies of the Software, and to
00022  *  permit persons to whom the Software is furnished to do so, subject to
00023  *  the following conditions:
00024  *
00025  *  The above copyright notice and this permission notice shall be
00026  *  included in all copies or substantial portions of the Software.
00027  *
00028  *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
00029  *  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
00030  *  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
00031  *  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
00032  *  LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
00033  *  OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
00034  *  WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
00035  *
00036  */
00037 
00038 #include "test/branch.hh"
00039 
00040 #include <algorithm>
00041 #include <map>
00042 #include <vector>
00043 #include <iostream>
00044 
00045 #include <gecode/kernel.hh>
00046 #include <gecode/int.hh>
00047 #ifdef GECODE_HAS_SET_VARS
00048 #include <gecode/set.hh>
00049 #endif
00050 
00051 #include <gecode/search.hh>
00052 
00053 namespace Test { namespace Branch {
00054 
00056   class IntTestSpace : public Gecode::Space {
00057   public:
00059     Gecode::IntVarArray x;
00061     Gecode::IntVarBranch vara, varb;
00063     Gecode::IntValBranch val;
00065     IntTestSpace(int n, Gecode::IntSet& d)
00066       : x(*this, n, d), 
00067         vara(Gecode::INT_VAR_NONE), varb(Gecode::INT_VAR_NONE),
00068         val(Gecode::INT_VAL_MIN) {}
00070     IntTestSpace(bool share, IntTestSpace& s)
00071       : Gecode::Space(share,s), vara(s.vara), varb(s.varb), val(s.val) {
00072       x.update(*this, share, s.x);
00073     }
00075     virtual Gecode::Space* copy(bool share) {
00076       return new IntTestSpace(share,*this);
00077     }
00079     static void branch(Gecode::Space& _home) {
00080       IntTestSpace& home =
00081         static_cast<IntTestSpace&>(_home);
00082       Gecode::branch(home, home.x, 
00083                      Gecode::tiebreak(home.vara,home.varb), 
00084                      home.val);
00085     }
00086   };
00087 
00089   class BoolTestSpace : public Gecode::Space {
00090   public:
00092     Gecode::BoolVarArray x;
00094     BoolTestSpace(int n)
00095       : x(*this, n, 0, 1) {}
00097     BoolTestSpace(bool share, BoolTestSpace& s)
00098       : Gecode::Space(share,s) {
00099       x.update(*this, share, s.x);
00100     }
00102     virtual Gecode::Space* copy(bool share) {
00103       return new BoolTestSpace(share,*this);
00104     }
00105   };
00106 
00107 #ifdef GECODE_HAS_SET_VARS
00109   class SetTestSpace : public Gecode::Space {
00110   public:
00112     Gecode::SetVarArray x;
00114     SetTestSpace(int n, Gecode::IntSet& d)
00115       : x(*this, n, Gecode::IntSet::empty, d) {}
00117     SetTestSpace(bool share, SetTestSpace& s)
00118       : Gecode::Space(share,s) {
00119       x.update(*this, share, s.x);
00120     }
00122     virtual Gecode::Space* copy(bool share) {
00123       return new SetTestSpace(share,*this);
00124     }
00125   };
00126 #endif
00127 
00133 
00134   const Gecode::IntVarBranch int_var_branch[] = {
00135     Gecode::INT_VAR_NONE,
00136     Gecode::INT_VAR_RND,
00137     Gecode::INT_VAR_DEGREE_MIN,
00138     Gecode::INT_VAR_DEGREE_MAX,
00139     Gecode::INT_VAR_MIN_MIN,
00140     Gecode::INT_VAR_MIN_MAX,
00141     Gecode::INT_VAR_MAX_MIN,
00142     Gecode::INT_VAR_MAX_MAX,
00143     Gecode::INT_VAR_SIZE_MIN,
00144     Gecode::INT_VAR_SIZE_MAX,
00145     Gecode::INT_VAR_SIZE_DEGREE_MIN,
00146     Gecode::INT_VAR_SIZE_DEGREE_MAX,
00147     Gecode::INT_VAR_REGRET_MIN_MIN,
00148     Gecode::INT_VAR_REGRET_MIN_MAX,
00149     Gecode::INT_VAR_REGRET_MAX_MIN,
00150     Gecode::INT_VAR_REGRET_MAX_MAX
00151   };
00153   const int n_int_var_branch =
00154     sizeof(int_var_branch)/sizeof(Gecode::IntVarBranch);
00156   const char* int_var_branch_name[] = {
00157     "INT_VAR_NONE",
00158     "INT_VAR_RND",
00159     "INT_VAR_DEGREE_MIN",
00160     "INT_VAR_DEGREE_MAX",
00161     "INT_VAR_MIN_MIN",
00162     "INT_VAR_MIN_MAX",
00163     "INT_VAR_MAX_MIN",
00164     "INT_VAR_MAX_MAX",
00165     "INT_VAR_SIZE_MIN",
00166     "INT_VAR_SIZE_MAX",
00167     "INT_VAR_SIZE_DEGREE_MIN",
00168     "INT_VAR_SIZE_DEGREE_MAX",
00169     "INT_VAR_REGRET_MIN_MIN",
00170     "INT_VAR_REGRET_MIN_MAX",
00171     "INT_VAR_REGRET_MAX_MIN",
00172     "INT_VAR_REGRET_MAX_MAX"
00173   };
00175   const Gecode::IntValBranch int_val_branch[] = {
00176     Gecode::INT_VAL_MIN,
00177     Gecode::INT_VAL_MED,
00178     Gecode::INT_VAL_MAX,
00179     Gecode::INT_VAL_RND,
00180     Gecode::INT_VAL_SPLIT_MIN,
00181     Gecode::INT_VAL_SPLIT_MAX,
00182     Gecode::INT_VALUES_MIN,
00183     Gecode::INT_VALUES_MAX
00184   };
00186   const int n_int_val_branch =
00187     sizeof(int_val_branch)/sizeof(Gecode::IntValBranch);
00189   const char* int_val_branch_name[] = {
00190     "INT_VAL_MIN",
00191     "INT_VAL_MED",
00192     "INT_VAL_MAX",
00193     "INT_VAL_RND",
00194     "INT_VAL_SPLIT_MIN",
00195     "INT_VAL_SPLIT_MAX",
00196     "INT_VALUES_MIN",
00197     "INT_VALUES_MAX"
00198   };
00200 
00201 #ifdef GECODE_HAS_SET_VARS
00202 
00207 
00208   const Gecode::SetVarBranch set_var_branch[] = {
00209     Gecode::SET_VAR_NONE,
00210     Gecode::SET_VAR_RND,
00211     Gecode::SET_VAR_DEGREE_MIN,
00212     Gecode::SET_VAR_DEGREE_MAX,
00213     Gecode::SET_VAR_MIN_MIN,
00214     Gecode::SET_VAR_MIN_MAX,
00215     Gecode::SET_VAR_MAX_MIN,
00216     Gecode::SET_VAR_MAX_MAX,
00217     Gecode::SET_VAR_SIZE_MIN,
00218     Gecode::SET_VAR_SIZE_MAX,
00219     Gecode::SET_VAR_SIZE_DEGREE_MIN,
00220     Gecode::SET_VAR_SIZE_DEGREE_MAX
00221   };
00223   const int n_set_var_branch =
00224     sizeof(set_var_branch)/sizeof(Gecode::SetVarBranch);
00226   const char* set_var_branch_name[] = {
00227     "SET_VAR_NONE",
00228     "SET_VAR_RND",
00229     "SET_VAR_DEGREE_MIN",
00230     "SET_VAR_DEGREE_MAX",
00231     "SET_VAR_MIN_MIN",
00232     "SET_VAR_MIN_MAX",
00233     "SET_VAR_MAX_MIN",
00234     "SET_VAR_MAX_MAX",
00235     "SET_VAR_SIZE_MIN",
00236     "SET_VAR_SIZE_MAX",
00237     "SET_VAR_SIZE_DEGREE_MIN",
00238     "SET_VAR_SIZE_DEGREE_MAX"
00239   };
00241   const Gecode::SetValBranch set_val_branch[] = {
00242     Gecode::SET_VAL_MIN_INC,
00243     Gecode::SET_VAL_MIN_EXC,
00244     Gecode::SET_VAL_MED_INC,
00245     Gecode::SET_VAL_MED_EXC,
00246     Gecode::SET_VAL_MAX_INC,
00247     Gecode::SET_VAL_MAX_EXC,
00248     Gecode::SET_VAL_RND_INC,
00249     Gecode::SET_VAL_RND_EXC
00250   };
00252   const int n_set_val_branch =
00253     sizeof(set_val_branch)/sizeof(Gecode::SetValBranch);
00255   const char* set_val_branch_name[] = {
00256     "SET_VAL_MIN_INC",
00257     "SET_VAL_MIN_EXC",
00258     "SET_VAL_MED_INC",
00259     "SET_VAL_MED_EXC",
00260     "SET_VAL_MAX_INC",
00261     "SET_VAL_MAX_EXC",
00262     "SET_VAL_RND_INC",
00263     "SET_VAL_RND_EXC"
00264   };
00266 #endif
00267 
00269   class RunInfo {
00270   public:
00271     std::string var, val;
00272     unsigned int a_d, c_d;
00273     RunInfo(const std::string& vara, const std::string& varb,
00274             const std::string& valname,
00275             const Gecode::Search::Options& o)
00276       : var(vara + "::" + varb), val(valname), a_d(o.a_d), c_d(o.c_d) {}
00277     void print(std::ostream& o) const {
00278       o << "(" << var << ", " << val << ", " << a_d << ", " << c_d << ")";
00279     }
00280   };
00281 
00282 }}
00283 
00284 std::ostream&
00285 operator<<(std::ostream& os, const Test::Branch::RunInfo& ri) {
00286   ri.print(os);
00287   return os;
00288 }
00289 
00290 
00291 namespace Test { namespace Branch {
00292 
00294   template <class TestSpace>
00295   int solutions(TestSpace* c, Gecode::Search::Options& o) {
00296     o.a_d = Base::rand(10);
00297     o.c_d = Base::rand(10);
00298     Gecode::DFS<TestSpace> e_s(c, o);
00299     delete c;
00300 
00301     // Find number of solutions
00302     int s = 0;
00303     do {
00304       Gecode::Space* ex = e_s.next();
00305       if (ex == NULL) break;
00306       delete ex;
00307       ++s;
00308     } while (true);
00309     return s;
00310   }
00311 
00312   IntTest::IntTest(const std::string& s, int a, const Gecode::IntSet& d)
00313     : Base("Int::Branch::"+s), arity(a), dom(d) {
00314   }
00315 
00316   bool
00317   IntTest::run(void) {
00318     using std::map;
00319     using std::vector;
00320     using std::string;
00321     using std::ostream;
00322     using namespace Gecode;
00323 
00324     // Results of tests run
00325     map<int, vector<RunInfo> > results;
00326     // Set up root space
00327     IntTestSpace* root = new IntTestSpace(arity,dom);
00328     post(*root, root->x);
00329     results.clear();
00330 
00331     for (int vara = n_int_var_branch; vara--; ) {
00332       for (int varb = n_int_var_branch; varb--; ) {
00333         for (int val = n_int_val_branch; val--; ) {
00334           IntTestSpace* c = static_cast<IntTestSpace*>(root->clone(false));
00335           c->vara = int_var_branch[vara];
00336           c->varb = int_var_branch[varb];
00337           c->val  = int_val_branch[val];
00338           branch(*c, &IntTestSpace::branch);
00339           Gecode::Search::Options o;
00340           results[solutions(c,o)].push_back
00341             (RunInfo(int_var_branch_name[vara],
00342                      int_var_branch_name[varb],
00343                      int_val_branch_name[val],
00344                      o));
00345         }
00346       }
00347     }
00348     if (results.size() > 1)
00349       goto failed;
00350     delete root;
00351     return true;
00352   failed:
00353     std::cout   << "FAILURE" << std::endl;
00354     for (map<int, vector<RunInfo> >::iterator it = results.begin();
00355          it != results.end(); ++it) {
00356       std::cout << "Number of solutions: " << it->first << std::endl;
00357       for (unsigned int i = 0; i < it->second.size(); ++i)
00358         std::cout << it->second[i] << " ";
00359       std::cout << std::endl;
00360     }
00361 
00362     delete root;
00363     return results.size() == 1;
00364   }
00365 
00366   BoolTest::BoolTest(const std::string& s, int a)
00367     : Base("Bool::Branch::"+s), arity(a) {
00368   }
00369 
00370   bool
00371   BoolTest::run(void) {
00372     using std::map;
00373     using std::vector;
00374     using std::string;
00375     using std::ostream;
00376     using namespace Gecode;
00377 
00378     // Results of tests run
00379     map<int, vector<RunInfo> > results;
00380     // Set up root space
00381     BoolTestSpace* root = new BoolTestSpace(arity);
00382     post(*root, root->x);
00383     results.clear();
00384 
00385     for (int vara = n_int_var_branch; vara--; ) {
00386       for (int varb = n_int_var_branch; varb--; ) {
00387         for (int val = n_int_val_branch; val--; ) {
00388           BoolTestSpace* c = static_cast<BoolTestSpace*>(root->clone(false));
00389           branch(*c, c->x,
00390                  tiebreak(int_var_branch[vara], int_var_branch[varb]),
00391                  int_val_branch[val]);
00392           Gecode::Search::Options o;
00393           results[solutions(c,o)].push_back
00394             (RunInfo(int_var_branch_name[vara],
00395                      int_var_branch_name[varb],
00396                      int_val_branch_name[val],
00397                      o));
00398         }
00399       }
00400     }
00401     if (results.size() > 1)
00402       goto failed;
00403     delete root;
00404     return true;
00405   failed:
00406     std::cout   << "FAILURE" << std::endl;
00407     for (map<int, vector<RunInfo> >::iterator it = results.begin();
00408          it != results.end(); ++it) {
00409       std::cout << "Number of solutions: " << it->first << std::endl;
00410       for (unsigned int i = 0; i < it->second.size(); ++i)
00411         std::cout << it->second[i] << " ";
00412       std::cout << std::endl;
00413     }
00414 
00415     delete root;
00416     return results.size() == 1;
00417   }
00418 
00419 #ifdef GECODE_HAS_SET_VARS
00420   SetTest::SetTest(const std::string& s, int a, const Gecode::IntSet& d)
00421     : Base("Set::Branch::"+s), arity(a), dom(d) {
00422   }
00423 
00424   bool
00425   SetTest::run(void) {
00426     using std::map;
00427     using std::vector;
00428     using std::string;
00429     using std::ostream;
00430     using namespace Gecode;
00431 
00432     // Results of tests run
00433     map<int, vector<RunInfo> > results;
00434     // Set up root space
00435     SetTestSpace* root = new SetTestSpace(arity,dom);
00436     post(*root, root->x);
00437     root->status();
00438     results.clear();
00439 
00440     for (int vara = n_set_var_branch; vara--; ) {
00441       for (int varb = n_set_var_branch; varb--; ) {
00442         for (int val = n_set_val_branch; val--; ) {
00443           SetTestSpace* c = static_cast<SetTestSpace*>(root->clone(false));
00444           branch(*c, c->x,
00445                  tiebreak(set_var_branch[vara], set_var_branch[varb]),
00446                  set_val_branch[val]);
00447           Gecode::Search::Options o;
00448           results[solutions(c,o)].push_back
00449             (RunInfo(set_var_branch_name[vara],
00450                      set_var_branch_name[varb],
00451                      set_val_branch_name[val],
00452                      o));
00453         }
00454       }
00455     }
00456     if (results.size() > 1)
00457       goto failed;
00458     delete root;
00459     return true;
00460   failed:
00461     std::cout   << "FAILURE" << std::endl;
00462     for (map<int, vector<RunInfo> >::iterator it = results.begin();
00463          it != results.end(); ++it) {
00464       std::cout << "Number of solutions: " << it->first << std::endl;
00465       for (unsigned int i = 0; i < it->second.size(); ++i)
00466         std::cout << it->second[i] << " ";
00467       std::cout << std::endl;
00468     }
00469 
00470     delete root;
00471     return results.size() == 1;
00472   }
00473 #endif
00474 
00475 }}
00476 
00477 // STATISTICS: test-branch