Generated on Fri Mar 20 15:55:56 2015 for Gecode by doxygen 1.6.3

arithmetic.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  *
00006  *  Copyright:
00007  *     Christian Schulte, 2002
00008  *
00009  *  Last modified:
00010  *     $Date: 2015-01-16 14:10:48 +0100 (Fri, 16 Jan 2015) $ by $Author: schulte $
00011  *     $Revision: 14362 $
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 <gecode/int/arithmetic.hh>
00039 
00040 namespace Gecode {
00041 
00042   void
00043   abs(Home home, IntVar x0, IntVar x1, IntConLevel icl) {
00044     using namespace Int;
00045     if (home.failed()) return;
00046     if (icl == ICL_DOM) {
00047       GECODE_ES_FAIL(Arithmetic::AbsDom<IntView>::post(home,x0,x1));
00048     } else {
00049       GECODE_ES_FAIL(Arithmetic::AbsBnd<IntView>::post(home,x0,x1));
00050     }
00051   }
00052 
00053 
00054   void
00055   max(Home home, IntVar x0, IntVar x1, IntVar x2,
00056       IntConLevel icl) {
00057     using namespace Int;
00058     if (home.failed()) return;
00059     if (icl == ICL_DOM) {
00060       GECODE_ES_FAIL(Arithmetic::MaxDom<IntView>::post(home,x0,x1,x2));
00061     } else {
00062       GECODE_ES_FAIL(Arithmetic::MaxBnd<IntView>::post(home,x0,x1,x2));
00063     }
00064   }
00065 
00066   void
00067   max(Home home, const IntVarArgs& x, IntVar y,
00068       IntConLevel icl) {
00069     using namespace Int;
00070     if (x.size() == 0)
00071       throw TooFewArguments("Int::max");
00072     if (home.failed()) return;
00073     ViewArray<IntView> xv(home,x);
00074     if (icl == ICL_DOM) {
00075       GECODE_ES_FAIL(Arithmetic::NaryMaxDom<IntView>::post(home,xv,y));
00076     } else {
00077       GECODE_ES_FAIL(Arithmetic::NaryMaxBnd<IntView>::post(home,xv,y));
00078     }
00079   }
00080 
00081   void
00082   min(Home home, IntVar x0, IntVar x1, IntVar x2,
00083       IntConLevel icl) {
00084     using namespace Int;
00085     if (home.failed()) return;
00086     MinusView m0(x0); MinusView m1(x1); MinusView m2(x2);
00087     if (icl == ICL_DOM) {
00088       GECODE_ES_FAIL(Arithmetic::MaxDom<MinusView>::post(home,m0,m1,m2));
00089     } else {
00090       GECODE_ES_FAIL(Arithmetic::MaxBnd<MinusView>::post(home,m0,m1,m2));
00091     }
00092   }
00093 
00094   void
00095   min(Home home, const IntVarArgs& x, IntVar y,
00096       IntConLevel icl) {
00097     using namespace Int;
00098     if (x.size() == 0)
00099       throw TooFewArguments("Int::min");
00100     if (home.failed()) return;
00101     ViewArray<MinusView> m(home,x.size());
00102     for (int i=x.size(); i--; )
00103       m[i] = MinusView(x[i]);
00104     MinusView my(y);
00105     if (icl == ICL_DOM) {
00106       GECODE_ES_FAIL(Arithmetic::NaryMaxDom<MinusView>::post(home,m,my));
00107     } else {
00108       GECODE_ES_FAIL(Arithmetic::NaryMaxBnd<MinusView>::post(home,m,my));
00109     }
00110   }
00111 
00112 
00113   void
00114   argmax(Home home, const IntVarArgs& x, IntVar y, bool tiebreak,
00115          IntConLevel) {
00116     using namespace Int;
00117     if (x.size() == 0)
00118       throw TooFewArguments("Int::argmax");
00119     if (x.same(home,y))
00120       throw ArgumentSame("Int::argmax");
00121     if (home.failed()) return;
00122     // Constrain y properly
00123     IntView yv(y);
00124     GECODE_ME_FAIL(yv.gq(home,0));
00125     GECODE_ME_FAIL(yv.le(home,x.size()));
00126     // Construct index view array
00127     IdxViewArray<IntView> ix(home,x.size());
00128     for (int i=x.size(); i--; ) {
00129       ix[i].idx=i; ix[i].view=x[i];
00130     }
00131     if (tiebreak)
00132         GECODE_ES_FAIL((Arithmetic::ArgMax<IntView,IntView,true>
00133                         ::post(home,ix,yv)));
00134     else
00135         GECODE_ES_FAIL((Arithmetic::ArgMax<IntView,IntView,false>
00136                         ::post(home,ix,yv)));
00137   }
00138 
00139   void
00140   argmin(Home home, const IntVarArgs& x, IntVar y, bool tiebreak,
00141          IntConLevel) {
00142     using namespace Int;
00143     if (x.size() == 0)
00144       throw TooFewArguments("Int::argmin");
00145     if (x.same(home,y))
00146       throw ArgumentSame("Int::argmin");
00147     if (home.failed()) return;
00148     // Constrain y properly
00149     IntView yv(y);
00150     GECODE_ME_FAIL(yv.gq(home,0));
00151     GECODE_ME_FAIL(yv.le(home,x.size()));
00152     // Construct index view array
00153     IdxViewArray<MinusView> ix(home,x.size());
00154     for (int i=x.size(); i--; ) {
00155       ix[i].idx=i; ix[i].view=MinusView(x[i]);
00156     }
00157     if (tiebreak)
00158         GECODE_ES_FAIL((Arithmetic::ArgMax<MinusView,IntView,true>
00159                         ::post(home,ix,yv)));
00160     else
00161         GECODE_ES_FAIL((Arithmetic::ArgMax<MinusView,IntView,false>
00162                         ::post(home,ix,yv)));
00163   }
00164 
00165 
00166   void
00167   mult(Home home, IntVar x0, IntVar x1, IntVar x2,
00168        IntConLevel icl) {
00169     using namespace Int;
00170     if (home.failed()) return;
00171     if (icl == ICL_DOM) {
00172       GECODE_ES_FAIL(Arithmetic::MultDom::post(home,x0,x1,x2));
00173     } else {
00174       GECODE_ES_FAIL(Arithmetic::MultBnd::post(home,x0,x1,x2));
00175     }
00176   }
00177 
00178 
00179   void
00180   divmod(Home home, IntVar x0, IntVar x1, IntVar x2, IntVar x3,
00181          IntConLevel) {
00182     using namespace Int;
00183     if (home.failed()) return;
00184 
00185     IntVar prod(home, Int::Limits::min, Int::Limits::max);
00186     GECODE_ES_FAIL(Arithmetic::MultBnd::post(home,x1,x2,prod));
00187     Linear::Term<IntView> t[3];
00188     t[0].a = 1; t[0].x = prod;
00189     t[1].a = 1; t[1].x = x3;
00190     int min, max;
00191     Linear::estimate(t,2,0,min,max);
00192     IntView x0v(x0);
00193     GECODE_ME_FAIL(x0v.gq(home,min));
00194     GECODE_ME_FAIL(x0v.lq(home,max));
00195     t[2].a=-1; t[2].x=x0;
00196     Linear::post(home,t,3,IRT_EQ,0);
00197     if (home.failed()) return;
00198     IntView x1v(x1);
00199     GECODE_ES_FAIL(
00200       Arithmetic::DivMod<IntView>::post(home,x0,x1,x3));
00201   }
00202 
00203   void
00204   div(Home home, IntVar x0, IntVar x1, IntVar x2,
00205       IntConLevel) {
00206     using namespace Int;
00207     if (home.failed()) return;
00208     GECODE_ES_FAIL(
00209       (Arithmetic::DivBnd<IntView>::post(home,x0,x1,x2)));
00210   }
00211 
00212   void
00213   mod(Home home, IntVar x0, IntVar x1, IntVar x2,
00214       IntConLevel icl) {
00215     using namespace Int;
00216     if (home.failed()) return;
00217     IntVar _div(home, Int::Limits::min, Int::Limits::max);
00218     divmod(home, x0, x1, _div, x2, icl);
00219   }
00220 
00221   void
00222   sqr(Home home, IntVar x0, IntVar x1, IntConLevel icl) {
00223     using namespace Int;
00224     if (home.failed()) return;
00225     Arithmetic::SqrOps ops;
00226     if (icl == ICL_DOM) {
00227       GECODE_ES_FAIL(Arithmetic::PowDom<Arithmetic::SqrOps>
00228                      ::post(home,x0,x1,ops));
00229     } else {
00230       GECODE_ES_FAIL(Arithmetic::PowBnd<Arithmetic::SqrOps>
00231                      ::post(home,x0,x1,ops));
00232     }
00233   }
00234 
00235   void
00236   sqrt(Home home, IntVar x0, IntVar x1, IntConLevel icl) {
00237     using namespace Int;
00238     if (home.failed()) return;
00239     Arithmetic::SqrOps ops;
00240     if (icl == ICL_DOM) {
00241       GECODE_ES_FAIL(Arithmetic::NrootDom<Arithmetic::SqrOps>
00242                      ::post(home,x0,x1,ops));
00243     } else {
00244       GECODE_ES_FAIL(Arithmetic::NrootBnd<Arithmetic::SqrOps>
00245                      ::post(home,x0,x1,ops));
00246     }
00247   }
00248 
00249   void
00250   pow(Home home, IntVar x0, int n, IntVar x1, IntConLevel icl) {
00251     using namespace Int;
00252     Limits::nonnegative(n,"Int::pow");
00253     if (home.failed()) return;
00254     if (n == 2) {
00255       sqr(home, x0, x1, icl);
00256       return;
00257     }
00258     Arithmetic::PowOps ops(n);
00259     if (icl == ICL_DOM) {
00260       GECODE_ES_FAIL(Arithmetic::PowDom<Arithmetic::PowOps>
00261                      ::post(home,x0,x1,ops));
00262     } else {
00263       GECODE_ES_FAIL(Arithmetic::PowBnd<Arithmetic::PowOps>
00264                      ::post(home,x0,x1,ops));
00265     }
00266   }
00267 
00268   void
00269   nroot(Home home, IntVar x0, int n, IntVar x1, IntConLevel icl) {
00270     using namespace Int;
00271     Limits::positive(n,"Int::nroot");
00272     if (home.failed()) return;
00273     if (n == 2) {
00274       sqrt(home, x0, x1, icl);
00275       return;
00276     }
00277     Arithmetic::PowOps ops(n);
00278     if (icl == ICL_DOM) {
00279       GECODE_ES_FAIL(Arithmetic::NrootDom<Arithmetic::PowOps>
00280                      ::post(home,x0,x1,ops));
00281     } else {
00282       GECODE_ES_FAIL(Arithmetic::NrootBnd<Arithmetic::PowOps>
00283                      ::post(home,x0,x1,ops));
00284     }
00285   }
00286 
00287 }
00288 
00289 // STATISTICS: int-post