| 
									
										
										
										
											2011-08-08 15:21:36 +02:00
										 |  |  | // -*- c++ -*- | 
					
						
							|  |  |  | //============================================================================= | 
					
						
							|  |  |  | // Copyright (C) 2011 by Denys Duchier | 
					
						
							|  |  |  | // | 
					
						
							|  |  |  | // This program is free software: you can redistribute it and/or modify it | 
					
						
							|  |  |  | // under the terms of the GNU Lesser General Public License as published by the | 
					
						
							|  |  |  | // Free Software Foundation, either version 3 of the License, or (at your | 
					
						
							|  |  |  | // option) any later version. | 
					
						
							|  |  |  | //  | 
					
						
							|  |  |  | // This program is distributed in the hope that it will be useful, but WITHOUT | 
					
						
							|  |  |  | // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | 
					
						
							|  |  |  | // FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for | 
					
						
							|  |  |  | // more details. | 
					
						
							|  |  |  | //  | 
					
						
							|  |  |  | // You should have received a copy of the GNU Lesser General Public License | 
					
						
							|  |  |  | // along with this program.  If not, see <http://www.gnu.org/licenses/>. | 
					
						
							|  |  |  | //============================================================================= | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #ifndef GECODE_COMMON | 
					
						
							|  |  |  | #define GECODE_COMMON | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "gecode/int.hh" | 
					
						
							|  |  |  | #include "gecode/set.hh" | 
					
						
							|  |  |  | #include "gecode/search.hh" | 
					
						
							|  |  |  | #include <vector> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | namespace generic_gecode | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   using namespace std; | 
					
						
							|  |  |  |   using namespace Gecode; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // description of the optimization criterion | 
					
						
							|  |  |  |   struct Optimizing | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     enum What { OPT_NONE, OPT_INT, OPT_RATIO }; | 
					
						
							|  |  |  |     enum How { OPT_MIN, OPT_MAX }; | 
					
						
							|  |  |  |     int num; | 
					
						
							|  |  |  |     int den; | 
					
						
							|  |  |  |     What what; | 
					
						
							|  |  |  |     How how; | 
					
						
							|  |  |  |     Optimizing(): num(-1), den(-1), what(OPT_NONE), how(OPT_MAX) {} | 
					
						
							|  |  |  |     Optimizing(Optimizing& o) | 
					
						
							|  |  |  |       : num(o.num), den(o.den), what(o.what), how(o.how) {} | 
					
						
							| 
									
										
										
										
											2011-12-03 23:31:28 +01:00
										 |  |  |     void check_ok() const | 
					
						
							|  |  |  |     { if (what!=OPT_NONE) | 
					
						
							|  |  |  | 	throw Exception("gecode-python","too many optimization criteria"); } | 
					
						
							| 
									
										
										
										
											2011-08-08 15:21:36 +02:00
										 |  |  |     void maximize(int i) | 
					
						
							| 
									
										
										
										
											2011-12-03 23:31:28 +01:00
										 |  |  |     { check_ok(); what = OPT_INT; how = OPT_MAX; num = i; }; | 
					
						
							| 
									
										
										
										
											2011-08-08 15:21:36 +02:00
										 |  |  |     void maximize(int i,int j) | 
					
						
							| 
									
										
										
										
											2011-12-03 23:31:28 +01:00
										 |  |  |     { check_ok(); what = OPT_RATIO; how = OPT_MAX; num = i; den = j; }; | 
					
						
							| 
									
										
										
										
											2011-08-08 15:21:36 +02:00
										 |  |  |     void minimize(int i) | 
					
						
							| 
									
										
										
										
											2011-12-03 23:31:28 +01:00
										 |  |  |     { check_ok(); what = OPT_INT; how = OPT_MIN; num = i; }; | 
					
						
							| 
									
										
										
										
											2011-08-08 15:21:36 +02:00
										 |  |  |     void minimize(int i,int j) | 
					
						
							| 
									
										
										
										
											2011-12-03 23:31:28 +01:00
										 |  |  |     { check_ok(); what = OPT_RATIO; how = OPT_MIN; num = i; den = j; }; | 
					
						
							| 
									
										
										
										
											2011-08-08 15:21:36 +02:00
										 |  |  |   }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   struct GenericSpace; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   struct GenericEngine | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     virtual GenericSpace* next(void)=0; | 
					
						
							|  |  |  |     virtual ~GenericEngine() {}; | 
					
						
							|  |  |  |   }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   struct GenericDFS: GenericEngine | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     DFS<GenericSpace> engine; | 
					
						
							| 
									
										
										
										
											2011-12-03 22:04:04 +01:00
										 |  |  |     GenericDFS(GenericSpace* s,Search::Options& opt) : engine(s,opt) {} | 
					
						
							| 
									
										
										
										
											2011-08-08 15:21:36 +02:00
										 |  |  |     virtual GenericSpace* next(void) { return engine.next(); } | 
					
						
							|  |  |  |   }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   struct GenericBAB: GenericEngine | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     BAB<GenericSpace> engine; | 
					
						
							| 
									
										
										
										
											2011-12-03 22:04:04 +01:00
										 |  |  |     GenericBAB(GenericSpace* s,Search::Options& opt) : engine(s,opt) {} | 
					
						
							| 
									
										
										
										
											2011-08-08 15:21:36 +02:00
										 |  |  |     virtual GenericSpace* next(void) { return engine.next(); } | 
					
						
							|  |  |  |   }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-01 22:48:28 +01:00
										 |  |  |   struct GenericRestart: GenericEngine | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     Restart<GenericSpace> engine; | 
					
						
							| 
									
										
										
										
											2011-12-03 22:04:04 +01:00
										 |  |  |     GenericRestart(GenericSpace* s,Search::Options& opt): engine(s,opt) {} | 
					
						
							| 
									
										
										
										
											2011-12-01 22:48:28 +01:00
										 |  |  |     virtual GenericSpace* next(void) { return engine.next(); } | 
					
						
							|  |  |  |   }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-03 23:31:28 +01:00
										 |  |  |   struct LoadingDock | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     vector<IntVar>  ivars; | 
					
						
							|  |  |  |     vector<BoolVar> bvars; | 
					
						
							|  |  |  |     vector<SetVar>  svars; | 
					
						
							|  |  |  |     vector<int> ikeep; | 
					
						
							|  |  |  |     vector<int> bkeep; | 
					
						
							|  |  |  |     vector<int> skeep; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     bool keeping_some() const | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       return (ikeep.size() != 0) | 
					
						
							|  |  |  | 	||   (bkeep.size() != 0) | 
					
						
							|  |  |  | 	||   (skeep.size() != 0); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     IntVar  get_ivar(int i) const { return ivars[i]; } | 
					
						
							|  |  |  |     BoolVar get_bvar(int i) const { return bvars[i]; } | 
					
						
							|  |  |  |     SetVar  get_svar(int i) const { return svars[i]; } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     int enter_ivar(const IntVar& v) | 
					
						
							|  |  |  |     { ivars.push_back(v); return static_cast<int>(ivars.size()-1); } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     int enter_bvar(const BoolVar& v) | 
					
						
							|  |  |  |     { bvars.push_back(v); return static_cast<int>(bvars.size()-1); } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     int enter_svar(const SetVar& v) | 
					
						
							|  |  |  |     { svars.push_back(v); return static_cast<int>(svars.size()-1); } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     int keep_ivar(int i) { ikeep.push_back(i); return static_cast<int>(ikeep.size()-1); } | 
					
						
							|  |  |  |     int keep_bvar(int i) { bkeep.push_back(i); return static_cast<int>(bkeep.size()-1); } | 
					
						
							|  |  |  |     int keep_svar(int i) { skeep.push_back(i); return static_cast<int>(skeep.size()-1); } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     void freeze(Space& home, | 
					
						
							|  |  |  | 		IntVarArray& iarr, BoolVarArray& barr, SetVarArray& sarr, | 
					
						
							|  |  |  | 		int& num, int& den) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       if (keeping_some()) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 	  // make sure that optimization vars (if any) are kept | 
					
						
							|  |  |  | 	  if (num != -1) | 
					
						
							|  |  |  | 	    { | 
					
						
							|  |  |  | 	      const int _num(num); | 
					
						
							|  |  |  | 	      const int _den(den); | 
					
						
							|  |  |  | 	      int n = static_cast<int>(ikeep.size()); | 
					
						
							|  |  |  | 	      bool num_found(false); | 
					
						
							|  |  |  | 	      bool den_found(false); | 
					
						
							|  |  |  | 	      for (;n--;) | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 		  const int idx(ikeep[n]); | 
					
						
							|  |  |  | 		  if (idx==_num) | 
					
						
							|  |  |  | 		    { num_found=true; if (den_found) break; } | 
					
						
							|  |  |  | 		  if (idx==_den) | 
					
						
							|  |  |  | 		    { den_found=true; if (num_found) break; } | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	      if (!num_found) | 
					
						
							|  |  |  | 		{ ikeep.push_back(_num); | 
					
						
							|  |  |  | 		  num=static_cast<int>(ikeep.size()-1); } | 
					
						
							|  |  |  | 	      if (_den != -1 && !den_found) | 
					
						
							|  |  |  | 		{ ikeep.push_back(_den); | 
					
						
							|  |  |  | 		  den=static_cast<int>(ikeep.size()-1); } | 
					
						
							|  |  |  | 	    } | 
					
						
							|  |  |  | 	  { int n = static_cast<int>(ikeep.size()); | 
					
						
							|  |  |  | 	    iarr = IntVarArray(home, n); | 
					
						
							|  |  |  | 	    for (;n--;) iarr[n]=ivars[ikeep[n]]; } | 
					
						
							|  |  |  | 	  { int n = static_cast<int>(bkeep.size()); | 
					
						
							|  |  |  | 	    barr = BoolVarArray(home, n); | 
					
						
							|  |  |  | 	    for (;n--;) barr[n]=bvars[bkeep[n]]; } | 
					
						
							|  |  |  | 	  { int n = static_cast<int>(skeep.size()); | 
					
						
							|  |  |  | 	    sarr = SetVarArray(home, n); | 
					
						
							|  |  |  | 	    for (;n--;) sarr[n]=svars[skeep[n]]; } | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  |       else | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 	  { int n = static_cast<int>(ivars.size()); | 
					
						
							|  |  |  | 	    iarr = IntVarArray(home, n); | 
					
						
							|  |  |  | 	    for (;n--;) iarr[n]=ivars[n]; } | 
					
						
							|  |  |  | 	  { int n = static_cast<int>(bvars.size()); | 
					
						
							|  |  |  | 	    barr = BoolVarArray(home, n); | 
					
						
							|  |  |  | 	    for (;n--;) barr[n]=bvars[n]; } | 
					
						
							|  |  |  | 	  { int n = static_cast<int>(svars.size()); | 
					
						
							|  |  |  | 	    sarr = SetVarArray(home, n); | 
					
						
							|  |  |  | 	    for (;n--;) sarr[n]=svars[n]; } | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-08-08 15:21:36 +02:00
										 |  |  |   struct GenericSpace: Space | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     Optimizing optim; | 
					
						
							|  |  |  |     IntVarArray ivars; | 
					
						
							|  |  |  |     BoolVarArray bvars; | 
					
						
							|  |  |  |     SetVarArray svars; | 
					
						
							| 
									
										
										
										
											2011-12-03 23:31:28 +01:00
										 |  |  |     LoadingDock* dock; | 
					
						
							|  |  |  |     bool keeping_some;		// iff only SOME of the vars are kept | 
					
						
							| 
									
										
										
										
											2011-08-08 15:21:36 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     Space* space() { return this; } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     GenericSpace(bool share, GenericSpace& s) | 
					
						
							| 
									
										
										
										
											2011-12-03 23:31:28 +01:00
										 |  |  |       : Space(share, s), optim(s.optim), dock(NULL), keeping_some(s.keeping_some) | 
					
						
							| 
									
										
										
										
											2011-08-08 15:21:36 +02:00
										 |  |  |     { | 
					
						
							|  |  |  |       ivars.update(*this, share, s.ivars); | 
					
						
							|  |  |  |       bvars.update(*this, share, s.bvars); | 
					
						
							|  |  |  |       svars.update(*this, share, s.svars); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     Space* copy(bool share) | 
					
						
							|  |  |  |     { freeze(); return new GenericSpace(share, *this); } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-03 23:31:28 +01:00
										 |  |  |     GenericSpace() : dock(new LoadingDock()), keeping_some(false) {} | 
					
						
							|  |  |  |     ~GenericSpace() { delete dock; } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // throw some C++ exception on behalf of glue code | 
					
						
							|  |  |  |     void kaboom(const char* s) | 
					
						
							|  |  |  |     { throw Exception("gecode-python", s); } | 
					
						
							|  |  |  |     int ikaboom(const char* s) | 
					
						
							|  |  |  |     { kaboom(s); return 0; } | 
					
						
							| 
									
										
										
										
											2011-08-08 15:21:36 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     // freeze the space before handing it off to a search engine | 
					
						
							|  |  |  |     void freeze() | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2011-12-03 23:31:28 +01:00
										 |  |  |       if (dock) | 
					
						
							| 
									
										
										
										
											2011-08-08 15:21:36 +02:00
										 |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2011-12-03 23:31:28 +01:00
										 |  |  | 	  keeping_some = dock->keeping_some(); | 
					
						
							|  |  |  | 	  dock->freeze(*this, ivars, bvars, svars, optim.num, optim.den); | 
					
						
							|  |  |  | 	  delete dock; | 
					
						
							|  |  |  | 	  dock = NULL; | 
					
						
							| 
									
										
										
										
											2011-08-08 15:21:36 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2011-12-03 23:31:28 +01:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2011-08-08 15:21:36 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-03 23:31:28 +01:00
										 |  |  |     IntVar  get_ivar(int i) const { return (dock)?dock->get_ivar(i):ivars[i]; } | 
					
						
							|  |  |  |     BoolVar get_bvar(int i) const { return (dock)?dock->get_bvar(i):bvars[i]; } | 
					
						
							|  |  |  |     SetVar  get_svar(int i) const { return (dock)?dock->get_svar(i):svars[i]; } | 
					
						
							| 
									
										
										
										
											2011-08-08 15:21:36 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-03 23:31:28 +01:00
										 |  |  |     int keep_ivar(int i) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       if (dock) return dock->keep_ivar(i); | 
					
						
							|  |  |  |       else return ikaboom("too late to keep"); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     int keep_bvar(int i) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       if (dock) return dock->keep_bvar(i); | 
					
						
							|  |  |  |       else return ikaboom("too late to keep"); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     int keep_svar(int i) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       if (dock) return dock->keep_svar(i); | 
					
						
							|  |  |  |       else return ikaboom("too late to keep"); | 
					
						
							| 
									
										
										
										
											2011-08-08 15:21:36 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-03 23:31:28 +01:00
										 |  |  |     bool frozen() const { return dock==NULL; } | 
					
						
							|  |  |  |     bool has_keepers() const { return keeping_some; } | 
					
						
							|  |  |  |     // when frozen and has_keepers: which is just has_keepers actually | 
					
						
							|  |  |  |     bool use_keep_index() const { return has_keepers(); } | 
					
						
							| 
									
										
										
										
											2011-08-08 15:21:36 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-03 22:04:04 +01:00
										 |  |  |     GenericEngine* new_engine(bool restart, Search::Options& opt) | 
					
						
							| 
									
										
										
										
											2011-08-08 15:21:36 +02:00
										 |  |  |     { | 
					
						
							|  |  |  |       freeze(); | 
					
						
							|  |  |  |       return (optim.what == Optimizing::OPT_NONE) | 
					
						
							| 
									
										
										
										
											2011-12-03 22:04:04 +01:00
										 |  |  | 	? static_cast<GenericEngine*>(new GenericDFS(this,opt)) | 
					
						
							| 
									
										
										
										
											2011-12-01 22:48:28 +01:00
										 |  |  | 	: (restart | 
					
						
							| 
									
										
										
										
											2011-12-03 22:04:04 +01:00
										 |  |  | 	   ? static_cast<GenericEngine*>(new GenericRestart(this,opt)) | 
					
						
							|  |  |  | 	   : static_cast<GenericEngine*>(new GenericBAB(this,opt))); | 
					
						
							| 
									
										
										
										
											2011-08-08 15:21:36 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     int _new_ivar(IntVar& v) | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2011-12-03 23:31:28 +01:00
										 |  |  |       if (dock) return dock->enter_ivar(v); | 
					
						
							|  |  |  |       else return ikaboom("too late to create vars"); | 
					
						
							| 
									
										
										
										
											2011-08-08 15:21:36 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     int new_ivar(int lo, int hi) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       IntVar v(*this, lo, hi); | 
					
						
							|  |  |  |       return _new_ivar(v); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     int new_ivar(IntSet& s) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       IntVar v(*this, s); | 
					
						
							|  |  |  |       return _new_ivar(v); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     int _new_bvar(BoolVar& v) | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2011-12-03 23:31:28 +01:00
										 |  |  |       if (dock) return dock->enter_bvar(v); | 
					
						
							|  |  |  |       else return ikaboom("too late to create vars"); | 
					
						
							| 
									
										
										
										
											2011-08-08 15:21:36 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     int new_bvar() | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       BoolVar v(*this, 0, 1); | 
					
						
							|  |  |  |       return _new_bvar(v); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     int _new_svar(SetVar& v) | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2011-12-03 23:31:28 +01:00
										 |  |  |       if (dock) return dock->enter_svar(v); | 
					
						
							|  |  |  |       else return ikaboom("too late to create vars"); | 
					
						
							| 
									
										
										
										
											2011-08-08 15:21:36 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     int new_svar(int glbMin, int glbMax, int lubMin, int lubMax, | 
					
						
							|  |  |  | 		 unsigned int cardMin=0, | 
					
						
							|  |  |  | 		 unsigned int cardMax=Set::Limits::card) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       SetVar v(*this, glbMin, glbMax, lubMin, lubMax, cardMin, cardMax); | 
					
						
							|  |  |  |       return _new_svar(v); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     int new_svar(IntSet glb, int lubMin, int lubMax, | 
					
						
							|  |  |  | 		 unsigned int cardMin=0, | 
					
						
							|  |  |  | 		 unsigned int cardMax=Set::Limits::card) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       SetVar v(*this, glb, lubMin, lubMax, cardMin, cardMax); | 
					
						
							|  |  |  |       return _new_svar(v); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     int new_svar(int glbMin, int glbMax, IntSet lub, | 
					
						
							|  |  |  | 		 unsigned int cardMin=0, | 
					
						
							|  |  |  | 		 unsigned int cardMax=Set::Limits::card) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       SetVar v(*this, glbMin, glbMax, lub, cardMin, cardMax); | 
					
						
							|  |  |  |       return _new_svar(v); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     int new_svar(IntSet glb, IntSet lub, | 
					
						
							|  |  |  | 		 unsigned int cardMin=0, | 
					
						
							|  |  |  | 		 unsigned int cardMax=Set::Limits::card) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       SetVar v(*this, glb, lub, cardMin, cardMax); | 
					
						
							|  |  |  |       return _new_svar(v); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     void minimize(int i) { optim.minimize(i); } | 
					
						
							|  |  |  |     void minimize(int i, int j) { optim.minimize(i,j); } | 
					
						
							|  |  |  |     void maximize(int i) { optim.maximize(i); } | 
					
						
							|  |  |  |     void maximize(int i, int j) { optim.maximize(i,j); } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     virtual void constrain(const Space& s) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       const GenericSpace& sol = static_cast<const GenericSpace&>(s); | 
					
						
							|  |  |  |       switch (optim.what) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 	case Optimizing::OPT_NONE: | 
					
						
							|  |  |  | 	  break; | 
					
						
							|  |  |  | 	case Optimizing::OPT_INT: | 
					
						
							|  |  |  | 	  rel(*this, ivars[optim.num], | 
					
						
							|  |  |  | 	      ((optim.how==Optimizing::OPT_MIN) ? IRT_LE : IRT_GR), | 
					
						
							|  |  |  | 	      sol.ivars[optim.num].val()); | 
					
						
							|  |  |  | 	  break; | 
					
						
							|  |  |  | 	case Optimizing::OPT_RATIO: | 
					
						
							|  |  |  | 	  { | 
					
						
							|  |  |  | 	    IntArgs c(2, sol.ivars[optim.den].val(), | 
					
						
							|  |  |  | 		      -  sol.ivars[optim.num].val()); | 
					
						
							|  |  |  | 	    IntVarArgs v(2); | 
					
						
							|  |  |  | 	    v[0] = ivars[optim.num]; | 
					
						
							|  |  |  | 	    v[1] = ivars[optim.den]; | 
					
						
							|  |  |  | 	    linear(*this, c, v, | 
					
						
							|  |  |  | 		   ((optim.how==Optimizing::OPT_MIN) ? IRT_LE : IRT_GR), 0); | 
					
						
							|  |  |  | 	    break; | 
					
						
							|  |  |  | 	  } | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   }; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #ifdef DISJUNCTOR | 
					
						
							|  |  |  | #include "disjunctor.icc" | 
					
						
							|  |  |  | #endif | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #endif |