Luca Di Gaspero <l.digasp...@uniud.it> writes: > is there the possibility to define and use set variables with the python > bindings? Could you provide a small example?
All is (succinctly) documented in the README file which I attach below:
========================================== gecode-python - Gecode bindings for Python ========================================== Requirements ============ * Python 2.6, 2.7, or 3.2 * Gecode >= 3.6.0 Installation ============ To install globally: python setup.py install or to install in your home directory: python setup.py install --prefix $HOME which would install the package under ~/lib/python2.7/site-packages (if using version 2.7 of Python). If you install in your home, you also need to adjust environment variable PYTHONPATH to search in $HOME/python2.7 and $HOME/python2.7/size-packages. If Gecode is installed in a non standard location, before you can build and install, you need to adjust environment variables CXXFLAGS, LDFLAGS, and LD_LIBRARY_PATH. Documentation ============= There are many constants in the gecode package. It is probably easiest to import everything: from gecode import * IntSet ~~~~~~ intset(int,int) intset(SPEC) returns an IntSet for the corresponding domain. SPEC is a list of ints and pairs of ints (interval). It might be tempting to simply represent an intset as a list of specs, but this would be ambiguous with IntArgs which, here, are represented as lists of ints. Space ~~~~~ space() this function creates a Space. Variables ~~~~~~~~~ Unlike in Gecode, variable objects are not bound to a specific Space. Each one actually contains an index with which it is possible to access a Space-bound Gecode variable. Variables can be created using the following methods of a Space: Space.intvar(int,int) Space.intvar(IntSet) returns an IntVar initialized with the corresponding domain. Space.boolvar() returns a BoolVar initialized with the domain [0,1] Space.setvar(int glbMin, int glbMax, int lubMin, int lubMax, int cardMin=MIN, int cardMax=MAX) Space.setvar(int glbMin, int glbMax, IntSet lub, int cardMin=MIN, int cardMax=MAX) Space.setvar(IntSet glb, int lubMin, int lubMax, int cardMin=MIN, int cardMax=MAX) Space.setvar(IntSet glb, IntSet lub, int cardMin=MIN, int cardMax=MAX) returns a SetVar initialized with the corresponding domain. Space.intvars(int N, ...) Space.boolvars(int N) Space.setvars(int N, ...) returns a list of N variables initialized with the domain as stipulated by the remaining arguments "...". An advantage of non Space-bound variables, is that you can use them both to post constraints in the original space AND to consult their values in solutions. Below are Space methods for looking up information about variables. Each of these methods can either take a variable as argument, or a list (or tuple) of variables, and returns resp. either a value, or a list of values: Space.assigned(X) returns True if variable X is assigned (determined) in the Space, False otherwise. Space.min(X) Space.max(X) Space.med(X) Space.val(X) Space.size(X) Space.width(X) Space.regret_min(X) Space.regret_max(X) These can be used for both IntVars and BoolVars and have the same meaning as in Gecode. Space.ranges(IntVar) Space.values(IntVar) Return resp. a list of pairs and a list of ints representing the domain of the argument variable. Space.glbSize(SetVar) Space.lubSize(SetVar) Space.unknownSize(SetVar) Space.cardMin(SetVar) Space.cardMax(SetVar) Space.lubMin(SetVar) Space.lubMax(SetVar) Space.glbMin(SetVar) Space.glbMax(SetVar) These can be used for SetVars and have the same meaning as in Gecode. Space.glbRanges(SetVar) Space.lubRanges(SetVar) Space.unknownRanges(SetVar) These return lists of pairs of ints representing the corresponding set bounds. Space.glbValues(SetVar) Space.lubValues(SetVar) Space.unknownValues(SetVar) These return lists of ints representing the corresponding set bounds. Space.keep(Var) Space.keep(Vars) Variables can be marked as "kept". In this case, only such variables will be explicitly copied during search. This could bring substantial benefits in memory usage. Of course, in a solution, you can then only look at variables that have been "kept". If no variable is marked as "kept", then they are all kept. Thus marking variables as "kept" is purely an optimization. Search ~~~~~~ Space.search(restart=False, threads=None, c_d=None, a_d=None) returns an iterator of solutions. Each solution is a Space. The restart option selects the Restart search engine, but only if an optimization criterion has been specified. The threads option selects and controls the parallel variant of the search engine. The c_d and a_d options control recomputation. In order to search for optimal solutions, it is necessary to indicate what needs to be optimized: Space.minimize(IntVar x) Space.maximize(IntVar x) search for a solution minimizing (resp. maximizing) x. Space.minimize(IntVar x,IntVar y) Space.maximize(IntVar x,IntVar y) search for a solution minimizing (resp. maximizing) the ratio x/y. Gist ~~~~ Space.gist(onclick=None, threads=None, c_d=None, a_d=None) if your installation of Gecode has Gist support, then this will invoke it. onclick is an inspector or an iterable of inspectors. An inspector is a callable, or a class whose instances are callables, that has/have been specially annoted by a decorator: @inspector("My Inspector 1") def show1(s2): print s2.values([X1,X2]) Note that s2 is not necessarily a solution! You may also define a textinspector to show textual output in a graphical window: @textinspector("My Inspector 2") def show2(s2): return "X1=%s X2=%s" % s2.values([X1,X2]) A textinspector must return a string. Bound Variables ~~~~~~~~~~~~~~~ A bound variable is essentially a pair of a non-bound variable and a Space. IntVal.__call__(Space) BoolVar.__call__(Space) SetVar.__call__(Space) a bound variable can be created by applying a non-bound variable to a Space. Space.bind(X) returns a bound variable for X, bound to this space; if X is a list of variables, this returns a list of bound variables. Constants ~~~~~~~~~ All constants used in Gecode are available with the same names in these bindings. Constraints ~~~~~~~~~~~ In Gecode, all constraints take a space as first argument. In these bindings, all constraints are methods of Space. Everywhere Gecode would use an XXXArgs argument, here, you should simply use a list (or tuple) of XXX. All gecode constraints are available (except "extensional", which are not yet implemented). All branchings are available except those with parameters that require additional implementation in C++. Please refer to the Gecode documentation. DISJUNCTORS ~~~~~~~~~~~ Disjunctors are an experimental extension to Gecode implemented by the gecode-python bindings. They provide support for disjunctions of clauses, where each clause is a conjunction of constraints: C1 or C2 or ... or Cn Each clause is executed "speculatively": this means it does not affect the main space. When a clause becomes failed, it is discarded. When only one clause remains, it is committed: this means that it now affects the main space. Example: Consider the problem where either X=Y=0 or X=Y+(1 or 2) for variable X and Y that take values in 0..3. s = space() x,y = s.intvars(2,0,3), First, we must create a disjunctor as a manager for our 2 clauses: d = s.disjunctor() We can now create our first clause: c1 = d.clause() This clause wants to constrain x and y to 0. However, since it must be executed "speculatively", it must operate on new variables x1 and y1 that shadow x and y: x1,y1 = c1.intvars(2,0,3) c1.forward([x,y],[x1,y1]) The forward(...) stipulation indicates which global variable is shadowed by which clause-local variable. Now we can post the speculative clause-local constraints for X=Y=0: c1.rel(x1,IRT_EQ,0), c1.rel(y1,IRT_EQ,0), We now create the second clause which uses x2 and y2 to shadow x and y: c2 = d.clause() x2,y2 = c2.intvars(2,0,3) c2.forward([x,y],[x2,y2]) However, this clause also needs a clause-local variable z2 taking values 1 or 2 in order to post the clause-local constraint x2=y2+z2: z2 = c2.intvar(1,2) c2.linear([-1,1,1],[x2,y2,z2],IRT_EQ,0) Finally, we can branch and search: s.branch([x,y],INT_VAR_SIZE_MIN,INT_VAL_MIN) for sol in s.search(): print sol.val([x,y])
The constraints are exactly the same as in Gecode, except that they are methods of the space rather than take the space as first argument. Please, let me know if something is still unclear. Eventually, I will provide more extensive documentation, but I haven't had time to work on that yet, sorry :-/ Cheers, --Denys
_______________________________________________ Gecode users mailing list users@gecode.org https://www.gecode.org/mailman/listinfo/gecode-users