Generated on Thu Mar 22 10:39:35 2012 for Gecode by doxygen 1.6.3

circuit.cpp

Go to the documentation of this file.
00001 /* -*- mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- */
00002 /*
00003  *  Main authors:
00004  *     Christian Schulte <schulte@gecode.org>
00005  *     Guido Tack <tack@gecode.org>
00006  *
00007  *  Copyright:
00008  *     Christian Schulte, 2006
00009  *     Guido Tack, 2011
00010  *
00011  *  Last modified:
00012  *     $Date: 2011-06-01 18:12:15 +0200 (Wed, 01 Jun 2011) $ by $Author: schulte $
00013  *     $Revision: 12036 $
00014  *
00015  *  This file is part of Gecode, the generic constraint
00016  *  development environment:
00017  *     http://www.gecode.org
00018  *
00019  *  Permission is hereby granted, free of charge, to any person obtaining
00020  *  a copy of this software and associated documentation files (the
00021  *  "Software"), to deal in the Software without restriction, including
00022  *  without limitation the rights to use, copy, modify, merge, publish,
00023  *  distribute, sublicense, and/or sell copies of the Software, and to
00024  *  permit persons to whom the Software is furnished to do so, subject to
00025  *  the following conditions:
00026  *
00027  *  The above copyright notice and this permission notice shall be
00028  *  included in all copies or substantial portions of the Software.
00029  *
00030  *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
00031  *  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
00032  *  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
00033  *  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
00034  *  LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
00035  *  OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
00036  *  WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
00037  *
00038  */
00039 
00040 #include <gecode/int/circuit.hh>
00041 
00042 namespace Gecode {
00043 
00044   void
00045   circuit(Home home, int offset, const IntVarArgs& x, IntConLevel icl) {
00046     Int::Limits::nonnegative(offset,"Int::circuit");
00047     if (x.size() == 0)
00048       throw Int::TooFewArguments("Int::circuit");
00049     if (x.same(home))
00050       throw Int::ArgumentSame("Int::circuit");
00051     if (home.failed()) return;
00052     ViewArray<Int::IntView> xv(home,x);
00053     
00054     if (offset == 0) {
00055       typedef Int::NoOffset<Int::IntView> NOV;
00056       NOV no;
00057       if (icl == ICL_DOM) {
00058         GECODE_ES_FAIL((Int::Circuit::Dom<Int::IntView,NOV>
00059                         ::post(home,xv,no)));
00060       } else {
00061         GECODE_ES_FAIL((Int::Circuit::Val<Int::IntView,NOV>
00062                         ::post(home,xv,no)));
00063       }
00064     } else {
00065       typedef Int::Offset OV;
00066       OV off(-offset);
00067       if (icl == ICL_DOM) {
00068         GECODE_ES_FAIL((Int::Circuit::Dom<Int::IntView,OV>
00069                         ::post(home,xv,off)));
00070       } else {
00071         GECODE_ES_FAIL((Int::Circuit::Val<Int::IntView,OV>
00072                         ::post(home,xv,off)));
00073       }
00074     }
00075   }
00076   void
00077   circuit(Home home, const IntVarArgs& x, IntConLevel icl) {
00078     circuit(home,0,x,icl);
00079   }
00080   
00081   void
00082   circuit(Home home, const IntArgs& c, int offset,
00083           const IntVarArgs& x, const IntVarArgs& y, IntVar z,
00084           IntConLevel icl) {
00085     Int::Limits::nonnegative(offset,"Int::circuit");
00086     int n = x.size();
00087     if (n == 0)
00088       throw Int::TooFewArguments("Int::circuit");
00089     if (x.same(home))
00090       throw Int::ArgumentSame("Int::circuit");
00091     if ((y.size() != n) || (c.size() != n*n))
00092       throw Int::ArgumentSizeMismatch("Int::circuit");
00093     circuit(home, offset, x, icl);
00094     if (home.failed()) return;
00095     IntArgs cx(offset+n);
00096     for (int i=0; i<offset; i++)
00097       cx[i] = 0;
00098     for (int i=n; i--; ) {
00099       for (int j=0; j<n; j++)
00100         cx[offset+j] = c[i*n+j];
00101       element(home, cx, x[i], y[i]);
00102     }
00103     linear(home, y, IRT_EQ, z);
00104   }
00105   void
00106   circuit(Home home, const IntArgs& c,
00107           const IntVarArgs& x, const IntVarArgs& y, IntVar z,
00108           IntConLevel icl) {
00109     circuit(home,c,0,x,y,z,icl);
00110   }
00111   void
00112   circuit(Home home, const IntArgs& c, int offset,
00113           const IntVarArgs& x, IntVar z, 
00114           IntConLevel icl) {
00115     Int::Limits::nonnegative(offset,"Int::circuit");
00116     if (home.failed()) return;
00117     IntVarArgs y(home, x.size(), Int::Limits::min, Int::Limits::max);
00118     circuit(home, c, offset, x, y, z, icl);
00119   }
00120   void
00121   circuit(Home home, const IntArgs& c,
00122           const IntVarArgs& x, IntVar z, 
00123           IntConLevel icl) {
00124     circuit(home,c,0,x,z,icl);
00125   }
00126 
00127   void
00128   path(Home home, int offset, const IntVarArgs& x, IntVar s, IntVar e,
00129        IntConLevel icl) {
00130     Int::Limits::nonnegative(offset,"Int::path");
00131     int n=x.size();
00132     if (n == 0)
00133       throw Int::TooFewArguments("Int::path");
00134     if (x.same(home))
00135       throw Int::ArgumentSame("Int::path");
00136     if (home.failed()) return;
00137     ViewArray<Int::IntView> xv(home,n+1);
00138     for (int i=n; i--; )
00139       xv[i] = Int::IntView(x[i]);
00140     xv[n] = s;
00141 
00142     if (offset == 0) {
00143       element(home, x, e, n);
00144       typedef Int::NoOffset<Int::IntView> NOV;
00145       NOV no;
00146       if (icl == ICL_DOM) {
00147         GECODE_ES_FAIL((Int::Circuit::Dom<Int::IntView,NOV>
00148                         ::post(home,xv,no)));
00149       } else {
00150         GECODE_ES_FAIL((Int::Circuit::Val<Int::IntView,NOV>
00151                         ::post(home,xv,no)));
00152       }
00153     } else {
00154       IntVarArgs ox(n+offset);
00155       IntVar y(home, -1,-1);
00156       for (int i=offset; i--; )
00157         ox[i] = y;
00158       for (int i=n; i--; )
00159         ox[offset + i] = x[i];
00160       element(home, ox, e, offset+n);
00161       typedef Int::Offset OV;
00162       OV off(-offset);
00163       if (icl == ICL_DOM) {
00164         GECODE_ES_FAIL((Int::Circuit::Dom<Int::IntView,OV>
00165                         ::post(home,xv,off)));
00166       } else {
00167         GECODE_ES_FAIL((Int::Circuit::Val<Int::IntView,OV>
00168                         ::post(home,xv,off)));
00169       }
00170     }
00171   }
00172   void
00173   path(Home home, const IntVarArgs& x, IntVar s, IntVar e,
00174        IntConLevel icl) {
00175     path(home,0,x,s,e,icl);
00176   }
00177   
00178   void
00179   path(Home home, const IntArgs& c, int offset,
00180        const IntVarArgs& x, IntVar s, IntVar e,
00181        const IntVarArgs& y, IntVar z,
00182        IntConLevel icl) {
00183     Int::Limits::nonnegative(offset,"Int::path");
00184     int n = x.size();
00185     if (n == 0)
00186       throw Int::TooFewArguments("Int::path");
00187     if (x.same(home))
00188       throw Int::ArgumentSame("Int::path");
00189     if ((y.size() != n) || (c.size() != n*n))
00190       throw Int::ArgumentSizeMismatch("Int::path");
00191     if (home.failed()) return;
00192     path(home, offset, x, s, e, icl);
00193     IntArgs cx(offset+n+1);
00194     for (int i=0; i<offset; i++)
00195       cx[i] = 0;
00196     cx[offset+n] = 0;
00197     for (int i=n; i--; ) {
00198       for (int j=0; j<n; j++)
00199         cx[offset+j] = c[i*n+j];
00200       element(home, cx, x[i], y[i]);
00201     }
00202     linear(home, y, IRT_EQ, z);
00203   }
00204   void
00205   path(Home home, const IntArgs& c,
00206        const IntVarArgs& x, IntVar s, IntVar e,
00207        const IntVarArgs& y, IntVar z,
00208        IntConLevel icl) {
00209     path(home,c,0,x,s,e,y,z,icl);
00210   }
00211   void
00212   path(Home home, const IntArgs& c, int offset,
00213        const IntVarArgs& x, IntVar s, IntVar e, IntVar z, 
00214        IntConLevel icl) {
00215     Int::Limits::nonnegative(offset,"Int::path");
00216     if (home.failed()) return;
00217     IntVarArgs y(home, x.size(), Int::Limits::min, Int::Limits::max);
00218     path(home, c, offset, x, s, e, y, z, icl);
00219   }
00220   void
00221   path(Home home, const IntArgs& c,
00222        const IntVarArgs& x, IntVar s, IntVar e, IntVar z, 
00223        IntConLevel icl) {
00224     path(home,c,0,x,s,e,z,icl);
00225   }
00226 
00227 }
00228 
00229 // STATISTICS: int-post