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

branch.cc

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: 2008-02-27 04:53:59 +0100 (Wed, 27 Feb 2008) $ by $Author: schulte $
00011  *     $Revision: 6318 $
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     IntTestSpace(int n, Gecode::IntSet& d)
00062       : x(this, n, d) {}
00064     IntTestSpace(bool share, IntTestSpace& s) 
00065       : Gecode::Space(share,s) {
00066       x.update(this, share, s.x);
00067     }
00069     virtual Gecode::Space* copy(bool share) {
00070       return new IntTestSpace(share,*this);
00071     }
00072   };
00073 
00075   class BoolTestSpace : public Gecode::Space {
00076   public:
00078     Gecode::BoolVarArray x;
00080     BoolTestSpace(int n)
00081       : x(this, n, 0, 1) {}
00083     BoolTestSpace(bool share, BoolTestSpace& s) 
00084       : Gecode::Space(share,s) {
00085       x.update(this, share, s.x);
00086     }
00088     virtual Gecode::Space* copy(bool share) {
00089       return new BoolTestSpace(share,*this);
00090     }
00091   };
00092 
00093 #ifdef GECODE_HAS_SET_VARS
00095   class SetTestSpace : public Gecode::Space {
00096   public:
00098     Gecode::SetVarArray x;
00100     SetTestSpace(int n, Gecode::IntSet& d)
00101       : x(this, n, Gecode::IntSet::empty, d) {}
00103     SetTestSpace(bool share, SetTestSpace& s) 
00104       : Gecode::Space(share,s) {
00105       x.update(this, share, s.x);
00106     }
00108     virtual Gecode::Space* copy(bool share) {
00109       return new SetTestSpace(share,*this);
00110     }
00111   };
00112 #endif
00113 
00114 #ifdef GECODE_HAS_CPLTSET_VARS
00116   class CpltSetTestSpace : public Gecode::Space {
00117   public:
00119     Gecode::CpltSetVarArray x;
00121     CpltSetTestSpace(int n, Gecode::IntSet& d)
00122       : x(this, n, Gecode::IntSet::empty, d) {}
00124     CpltSetTestSpace(bool share, CpltSetTestSpace& s) 
00125       : Gecode::Space(share,s) {
00126       x.update(this, share, s.x);
00127     }
00129     virtual Gecode::Space* copy(bool share) {
00130       return new CpltSetTestSpace(share,*this);
00131     }
00132   };
00133 #endif
00134 
00140 
00141   const Gecode::IntVarBranch int_var_branch[] = {
00142     Gecode::INT_VAR_NONE,
00143     Gecode::INT_VAR_MIN_MIN,       
00144     Gecode::INT_VAR_MIN_MAX,
00145     Gecode::INT_VAR_MAX_MIN,
00146     Gecode::INT_VAR_MAX_MAX,
00147     Gecode::INT_VAR_SIZE_MIN,
00148     Gecode::INT_VAR_SIZE_MAX,
00149     Gecode::INT_VAR_DEGREE_MIN,
00150     Gecode::INT_VAR_DEGREE_MAX,
00151     Gecode::INT_VAR_SIZE_DEGREE_MIN,
00152     Gecode::INT_VAR_SIZE_DEGREE_MAX,
00153     Gecode::INT_VAR_REGRET_MIN_MIN,
00154     Gecode::INT_VAR_REGRET_MIN_MAX,
00155     Gecode::INT_VAR_REGRET_MAX_MIN,
00156     Gecode::INT_VAR_REGRET_MAX_MAX
00157   };
00159   const int n_int_var_branch = 
00160     sizeof(int_var_branch)/sizeof(Gecode::IntVarBranch);
00162   const char* int_var_branch_name[] = {
00163     "INT_VAR_NONE",
00164     "INT_VAR_MIN_MIN",       
00165     "INT_VAR_MIN_MAX",
00166     "INT_VAR_MAX_MIN",
00167     "INT_VAR_MAX_MAX",
00168     "INT_VAR_SIZE_MIN",
00169     "INT_VAR_SIZE_MAX",
00170     "INT_VAR_DEGREE_MIN",
00171     "INT_VAR_DEGREE_MAX",
00172     "INT_VAR_SIZE_DEGREE_MIN",
00173     "INT_VAR_SIZE_DEGREE_MAX",
00174     "INT_VAR_REGRET_MIN_MIN",
00175     "INT_VAR_REGRET_MIN_MAX",
00176     "INT_VAR_REGRET_MAX_MIN",
00177     "INT_VAR_REGRET_MAX_MAX"
00178   };
00180   const Gecode::IntValBranch int_val_branch[] = {
00181     Gecode::INT_VAL_MIN,
00182     Gecode::INT_VAL_MED,
00183     Gecode::INT_VAL_MAX,
00184     Gecode::INT_VAL_SPLIT_MIN,
00185     Gecode::INT_VAL_SPLIT_MAX
00186   };
00188   const int n_int_val_branch =
00189     sizeof(int_val_branch)/sizeof(Gecode::IntValBranch);
00191   const char* int_val_branch_name[] = {
00192     "INT_VAL_MIN",
00193     "INT_VAL_MED",
00194     "INT_VAL_MAX",
00195     "INT_VAL_SPLIT_MIN",
00196     "INT_VAL_SPLIT_MAX"
00197   };
00199 
00200 #ifdef GECODE_HAS_SET_VARS
00201 
00206 
00207   const Gecode::SetVarBranch set_var_branch[] = {
00208     Gecode::SET_VAR_NONE,
00209     Gecode::SET_VAR_MIN_CARD,
00210     Gecode::SET_VAR_MAX_CARD,
00211     Gecode::SET_VAR_MIN_UNKNOWN_ELEM,
00212     Gecode::SET_VAR_MAX_UNKNOWN_ELEM
00213   };
00215   const int n_set_var_branch = 
00216     sizeof(set_var_branch)/sizeof(Gecode::SetVarBranch);
00218   const char* set_var_branch_name[] = {
00219     "SET_VAR_NONE",
00220     "SET_VAR_MIN_CARD",
00221     "SET_VAR_MAX_CARD",
00222     "SET_VAR_MIN_UNKNOWN_ELEM",
00223     "SET_VAR_MAX_UNKNOWN_ELEM"
00224   };
00226   const Gecode::SetValBranch set_val_branch[] = {
00227     Gecode::SET_VAL_MIN,
00228     Gecode::SET_VAL_MAX
00229   };
00231   const int n_set_val_branch =
00232     sizeof(set_val_branch)/sizeof(Gecode::SetValBranch);
00234   const char* set_val_branch_name[] = {
00235     "SET_VAL_MIN",
00236     "SET_VAL_MAX"
00237   };
00239 #endif
00240 
00241 #ifdef GECODE_HAS_CPLTSET_VARS
00242 
00247 
00248   const Gecode::CpltSetVarBranch cpltset_var_branch[] = {
00249     Gecode::CPLTSET_VAR_NONE,
00250     Gecode::CPLTSET_VAR_MIN_CARD,
00251     Gecode::CPLTSET_VAR_MAX_CARD,
00252     Gecode::CPLTSET_VAR_MIN_UNKNOWN_ELEM,
00253     Gecode::CPLTSET_VAR_MAX_UNKNOWN_ELEM
00254   };
00256   const int n_cpltset_var_branch = 
00257     sizeof(cpltset_var_branch)/sizeof(Gecode::CpltSetVarBranch);
00259   const char* cpltset_var_branch_name[] = {
00260     "CPLTSET_VAR_NONE",
00261     "CPLTSET_VAR_MIN_CARD",
00262     "CPLTSET_VAR_MAX_CARD",
00263     "CPLTSET_VAR_MIN_UNKNOWN_ELEM",
00264     "CPLTSET_VAR_MAX_UNKNOWN_ELEM"
00265   };
00267   const Gecode::CpltSetValBranch cpltset_val_branch[] = {
00268     Gecode::CPLTSET_VAL_MIN_UNKNOWN,
00269     Gecode::CPLTSET_VAL_MAX_UNKNOWN,
00270     Gecode::CPLTSET_VAL_MIN_UNKNOWN_EX_FIRST,
00271     Gecode::CPLTSET_VAL_MAX_UNKNOWN_EX_FIRST
00272   };
00274   const int n_cpltset_val_branch =
00275     sizeof(cpltset_val_branch)/sizeof(Gecode::CpltSetValBranch);
00277   const char* cpltset_val_branch_name[] = {
00278     "CPLTSET_VAL_MIN_UNKNOWN",
00279     "CPLTSET_VAL_MAX_UNKNOWN",
00280     "CPLTSET_VAL_MIN_UNKNOWN_EX_FIRST",
00281     "CPLTSET_VAL_MAX_UNKNOWN_EX_FIRST"
00282   };
00284 #endif
00285 
00287   class RunInfo {
00288   public:
00289     std::string var, val;
00290     unsigned int a_d, c_d;
00291     RunInfo(const char* varname, const char* valname,
00292             int a_d_val, int c_d_val)
00293       : var(varname), val(valname), a_d(a_d_val), c_d(c_d_val) {}
00294     void print(std::ostream& o) const {
00295       o << "(" << var << ", " << val << ", " << a_d << ", " << c_d << ")";
00296     }
00297   };
00298 
00299 }}
00300 
00301 std::ostream&
00302 operator<<(std::ostream& os, const Test::Branch::RunInfo& ri) {
00303   ri.print(os);
00304   return os;
00305 }
00306 
00307 
00308 namespace Test { namespace Branch {
00309 
00310 
00311   IntTest::IntTest(const std::string& s, int a, const Gecode::IntSet& d)
00312     : Base("Branch::Int::"+s), arity(a), dom(d) {
00313   }
00314 
00315   bool
00316   IntTest::run(void) {
00317     using std::map;
00318     using std::vector;
00319     using std::string;
00320     using std::ostream;
00321     using namespace Gecode;
00322     
00323     // Results of tests run
00324     map<int, vector<RunInfo> > results;
00325     // Set up root space
00326     IntTestSpace* root = new IntTestSpace(arity,dom);
00327     post(root, root->x);
00328     results.clear();
00329 
00330     for (int var = n_int_var_branch; var--; ) {
00331       for (int val = n_int_val_branch; val--; ) {
00332         IntTestSpace* clone = static_cast<IntTestSpace*>(root->clone(false));
00333         Gecode::Search::Options o;
00334         o.a_d = Base::rand(10);
00335         o.c_d = Base::rand(10);
00336         branch(clone, clone->x, int_var_branch[var], int_val_branch[val]);
00337         Gecode::DFS<IntTestSpace> e_s(clone, o);
00338         delete clone;
00339         
00340         // Find number of solutions
00341         int solutions = 0;
00342         do {
00343           Space *ex = e_s.next();
00344           if (ex == NULL) break;
00345           delete ex;
00346           ++solutions;
00347         } while(true);
00348         results[solutions].push_back(RunInfo(int_var_branch_name[var], 
00349                                              int_val_branch_name[val],
00350                                              o.a_d, o.c_d));
00351       }
00352     }
00353     if (results.size() > 1) 
00354       goto failed;
00355     delete root;
00356     return true;
00357   failed:
00358     std::cout   << "FAILURE" << std::endl;
00359     for (map<int, vector<RunInfo> >::iterator it = results.begin();
00360          it != results.end(); ++it) {
00361       std::cout << "Number of solutions: " << it->first << std::endl;
00362       for (unsigned int i = 0; i < it->second.size(); ++i)
00363         std::cout << it->second[i] << " ";
00364       std::cout << std::endl;
00365     }
00366     
00367     delete root;
00368     return results.size() == 1;
00369   }
00370 
00371   BoolTest::BoolTest(const std::string& s, int a)
00372     : Base("Branch::Bool::"+s), arity(a) {
00373   }
00374 
00375   bool
00376   BoolTest::run(void) {
00377     using std::map;
00378     using std::vector;
00379     using std::string;
00380     using std::ostream;
00381     using namespace Gecode;
00382     
00383     // Results of tests run
00384     map<int, vector<RunInfo> > results;
00385     // Set up root space
00386     BoolTestSpace* root = new BoolTestSpace(arity);
00387     post(root, root->x);
00388     results.clear();
00389 
00390     for (int var = n_int_var_branch; var--; ) {
00391       for (int val = n_int_val_branch; val--; ) {
00392         BoolTestSpace* clone = 
00393           static_cast<BoolTestSpace*>(root->clone(false));
00394         Gecode::Search::Options o;
00395         o.a_d = Base::rand(10);
00396         o.c_d = Base::rand(10);
00397         branch(clone, clone->x, int_var_branch[var], int_val_branch[val]);
00398         Gecode::DFS<BoolTestSpace> e_s(clone, o);
00399         delete clone;
00400         
00401         // Find number of solutions
00402         int solutions = 0;
00403         do {
00404           Space *ex = e_s.next();
00405           if (ex == NULL) break;
00406           delete ex;
00407           ++solutions;
00408         } while(true);
00409         results[solutions].push_back(RunInfo(int_var_branch_name[var], 
00410                                              int_val_branch_name[val],
00411                                              o.a_d, o.c_d));
00412       }
00413     }
00414     if (results.size() > 1) 
00415       goto failed;
00416     delete root;
00417     return true;
00418   failed:
00419     std::cout   << "FAILURE" << std::endl;
00420     for (map<int, vector<RunInfo> >::iterator it = results.begin();
00421          it != results.end(); ++it) {
00422       std::cout << "Number of solutions: " << it->first << std::endl;
00423       for (unsigned int i = 0; i < it->second.size(); ++i)
00424         std::cout << it->second[i] << " ";
00425       std::cout << std::endl;
00426     }
00427     
00428     delete root;
00429     return results.size() == 1;
00430   }
00431 
00432 #ifdef GECODE_HAS_SET_VARS
00433   SetTest::SetTest(const std::string& s, int a, const Gecode::IntSet& d)
00434     : Base("Branch::Set::"+s), arity(a), dom(d) {
00435   }
00436 
00437   bool
00438   SetTest::run(void) {
00439     using std::map;
00440     using std::vector;
00441     using std::string;
00442     using std::ostream;
00443     using namespace Gecode;
00444     
00445     // Results of tests run
00446     map<int, vector<RunInfo> > results;
00447     // Set up root space
00448     SetTestSpace* root = new SetTestSpace(arity,dom);
00449     post(root, root->x);
00450     root->status();
00451     results.clear();
00452 
00453     for (int var = n_set_var_branch; var--; ) {
00454       for (int val = n_set_val_branch; val--; ) {
00455         SetTestSpace* clone = static_cast<SetTestSpace*>(root->clone(false));
00456         Gecode::Search::Options o;
00457         o.a_d = Base::rand(10);
00458         o.c_d = Base::rand(10);
00459         branch(clone, clone->x, set_var_branch[var], set_val_branch[val]);
00460         Gecode::DFS<SetTestSpace> e_s(clone, o);
00461         delete clone;
00462         
00463         // Find number of solutions
00464         int solutions = 0;
00465         do {
00466           Space *ex = e_s.next();
00467           if (ex == NULL) break;
00468           delete ex;
00469           ++solutions;
00470         } while(true);
00471         results[solutions].push_back(RunInfo(set_var_branch_name[var], 
00472                                              set_val_branch_name[val],
00473                                              o.a_d, o.c_d));
00474       }
00475     }
00476     if (results.size() > 1) 
00477       goto failed;
00478     delete root;
00479     return true;
00480   failed:
00481     std::cout   << "FAILURE" << std::endl;
00482     for (map<int, vector<RunInfo> >::iterator it = results.begin();
00483          it != results.end(); ++it) {
00484       std::cout << "Number of solutions: " << it->first << std::endl;
00485       for (unsigned int i = 0; i < it->second.size(); ++i)
00486         std::cout << it->second[i] << " ";
00487       std::cout << std::endl;
00488     }
00489     
00490     delete root;
00491     return results.size() == 1;
00492   }
00493 #endif
00494 
00495 #ifdef GECODE_HAS_CPLTSET_VARS
00496   CpltSetTest::CpltSetTest(const std::string& s, int a,
00497                            const Gecode::IntSet& d)
00498     : Base("Branch::CpltSet::"+s), arity(a), dom(d) {
00499   }
00500 
00501   bool
00502   CpltSetTest::run(void) {
00503     using std::map;
00504     using std::vector;
00505     using std::string;
00506     using std::ostream;
00507     using namespace Gecode;
00508     
00509     // Results of tests run
00510     map<int, vector<RunInfo> > results;
00511     // Set up root space
00512     CpltSetTestSpace* root = new CpltSetTestSpace(arity,dom);
00513     post(root, root->x);
00514     root->status();
00515     results.clear();
00516 
00517     for (int var = n_cpltset_var_branch; var--; ) {
00518       for (int val = n_cpltset_val_branch; val--; ) {
00519         CpltSetTestSpace* clone = 
00520           static_cast<CpltSetTestSpace*>(root->clone(false));
00521         Gecode::Search::Options o;
00522         o.a_d = Base::rand(10);
00523         o.c_d = Base::rand(10);
00524         branch(clone, clone->x, cpltset_var_branch[var], 
00525                cpltset_val_branch[val]);
00526         Gecode::DFS<CpltSetTestSpace> e_s(clone, o);
00527         delete clone;
00528         
00529         // Find number of solutions
00530         int solutions = 0;
00531         do {
00532           Space *ex = e_s.next();
00533           if (ex == NULL) break;
00534           delete ex;
00535           ++solutions;
00536         } while(true);
00537         results[solutions].push_back(RunInfo(cpltset_var_branch_name[var], 
00538                                              cpltset_val_branch_name[val],
00539                                              o.a_d, o.c_d));
00540       }
00541     }
00542     if (results.size() > 1) 
00543       goto failed;
00544     delete root;
00545     return true;
00546   failed:
00547     std::cout   << "FAILURE" << std::endl;
00548     for (map<int, vector<RunInfo> >::iterator it = results.begin();
00549          it != results.end(); ++it) {
00550       std::cout << "Number of solutions: " << it->first << std::endl;
00551       for (unsigned int i = 0; i < it->second.size(); ++i)
00552         std::cout << it->second[i] << " ";
00553       std::cout << std::endl;
00554     }
00555     
00556     delete root;
00557     return results.size() == 1;
00558   }
00559 #endif
00560 
00561 }}
00562 
00563 // STATISTICS: test-branch