359 lines
		
	
	
		
			10 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
		
		
			
		
	
	
			359 lines
		
	
	
		
			10 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
| 
								 | 
							
								// -*- 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) {}
							 | 
						||
| 
								 | 
							
								    void check_ok() const
							 | 
						||
| 
								 | 
							
								    { if (what!=OPT_NONE)
							 | 
						||
| 
								 | 
							
									throw Exception("gecode-python","too many optimization criteria"); }
							 | 
						||
| 
								 | 
							
								    void maximize(int i)
							 | 
						||
| 
								 | 
							
								    { check_ok(); what = OPT_INT; how = OPT_MAX; num = i; };
							 | 
						||
| 
								 | 
							
								    void maximize(int i,int j)
							 | 
						||
| 
								 | 
							
								    { check_ok(); what = OPT_RATIO; how = OPT_MAX; num = i; den = j; };
							 | 
						||
| 
								 | 
							
								    void minimize(int i)
							 | 
						||
| 
								 | 
							
								    { check_ok(); what = OPT_INT; how = OPT_MIN; num = i; };
							 | 
						||
| 
								 | 
							
								    void minimize(int i,int j)
							 | 
						||
| 
								 | 
							
								    { check_ok(); what = OPT_RATIO; how = OPT_MIN; num = i; den = j; };
							 | 
						||
| 
								 | 
							
								  };
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  struct GenericSpace;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  struct GenericEngine
							 | 
						||
| 
								 | 
							
								  {
							 | 
						||
| 
								 | 
							
								    virtual GenericSpace* next(void)=0;
							 | 
						||
| 
								 | 
							
								    virtual ~GenericEngine() {};
							 | 
						||
| 
								 | 
							
								  };
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  struct GenericDFS: GenericEngine
							 | 
						||
| 
								 | 
							
								  {
							 | 
						||
| 
								 | 
							
								    DFS<GenericSpace> engine;
							 | 
						||
| 
								 | 
							
								    GenericDFS(GenericSpace* s,Search::Options& opt) : engine(s,opt) {}
							 | 
						||
| 
								 | 
							
								    virtual GenericSpace* next(void) { return engine.next(); }
							 | 
						||
| 
								 | 
							
								  };
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  struct GenericBAB: GenericEngine
							 | 
						||
| 
								 | 
							
								  {
							 | 
						||
| 
								 | 
							
								    BAB<GenericSpace> engine;
							 | 
						||
| 
								 | 
							
								    GenericBAB(GenericSpace* s,Search::Options& opt) : engine(s,opt) {}
							 | 
						||
| 
								 | 
							
								    virtual GenericSpace* next(void) { return engine.next(); }
							 | 
						||
| 
								 | 
							
								  };
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  struct GenericRestart: GenericEngine
							 | 
						||
| 
								 | 
							
								  {
							 | 
						||
| 
								 | 
							
								    Restart<GenericSpace> engine;
							 | 
						||
| 
								 | 
							
								    GenericRestart(GenericSpace* s,Search::Options& opt): engine(s,opt) {}
							 | 
						||
| 
								 | 
							
								    virtual GenericSpace* next(void) { return engine.next(); }
							 | 
						||
| 
								 | 
							
								  };
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  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]; }
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  };
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  struct GenericSpace: Space
							 | 
						||
| 
								 | 
							
								  {
							 | 
						||
| 
								 | 
							
								    Optimizing optim;
							 | 
						||
| 
								 | 
							
								    IntVarArray ivars;
							 | 
						||
| 
								 | 
							
								    BoolVarArray bvars;
							 | 
						||
| 
								 | 
							
								    SetVarArray svars;
							 | 
						||
| 
								 | 
							
								    LoadingDock* dock;
							 | 
						||
| 
								 | 
							
								    bool keeping_some;		// iff only SOME of the vars are kept
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    Space* space() { return this; }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    GenericSpace(bool share, GenericSpace& s)
							 | 
						||
| 
								 | 
							
								      : Space(share, s), optim(s.optim), dock(NULL), keeping_some(s.keeping_some)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								      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); }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    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; }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    // freeze the space before handing it off to a search engine
							 | 
						||
| 
								 | 
							
								    void freeze()
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								      if (dock)
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
									  keeping_some = dock->keeping_some();
							 | 
						||
| 
								 | 
							
									  dock->freeze(*this, ivars, bvars, svars, optim.num, optim.den);
							 | 
						||
| 
								 | 
							
									  delete dock;
							 | 
						||
| 
								 | 
							
									  dock = NULL;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    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]; }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    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");
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    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(); }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    GenericEngine* new_engine(bool restart, Search::Options& opt)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								      freeze();
							 | 
						||
| 
								 | 
							
								      return (optim.what == Optimizing::OPT_NONE)
							 | 
						||
| 
								 | 
							
									? static_cast<GenericEngine*>(new GenericDFS(this,opt))
							 | 
						||
| 
								 | 
							
									: (restart
							 | 
						||
| 
								 | 
							
									   ? static_cast<GenericEngine*>(new GenericRestart(this,opt))
							 | 
						||
| 
								 | 
							
									   : static_cast<GenericEngine*>(new GenericBAB(this,opt)));
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    int _new_ivar(IntVar& v)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								      if (dock) return dock->enter_ivar(v);
							 | 
						||
| 
								 | 
							
								      else return ikaboom("too late to create vars");
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    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)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								      if (dock) return dock->enter_bvar(v);
							 | 
						||
| 
								 | 
							
								      else return ikaboom("too late to create vars");
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    int new_bvar()
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								      BoolVar v(*this, 0, 1);
							 | 
						||
| 
								 | 
							
								      return _new_bvar(v);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    int _new_svar(SetVar& v)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								      if (dock) return dock->enter_svar(v);
							 | 
						||
| 
								 | 
							
								      else return ikaboom("too late to create vars");
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    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
							 |