Generated on Mon Jul 6 18:09:15 2009 for Gecode by doxygen 1.5.9

branching.hpp

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, 2004
00009  *     Guido Tack, 2004
00010  *
00011  *  Last modified:
00012  *     $Date: 2009-02-05 11:48:53 +0100 (Thu, 05 Feb 2009) $ by $Author: schulte $
00013  *     $Revision: 8155 $
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 namespace Gecode {
00041 
00050 
00051   enum ViewSelStatus {
00052     VSS_BEST,   
00053     VSS_BETTER, 
00054     VSS_TIE,    
00055     VSS_WORSE   
00056   };
00057 
00059   class Pos {
00060   public:
00062     const int pos;
00064     Pos(int p);
00065   };
00066 
00075   template <class ViewSel>
00076   class ViewBranching : public Branching {
00077   protected:
00079     ViewArray<typename ViewSel::View> x;
00081     mutable int start;
00083     ViewSel viewsel;
00085     Pos pos(Space& home);
00087     typename ViewSel::View view(const Pos& p) const;
00089     ViewBranching(Space& home, bool share, ViewBranching& b);
00090   public:
00092     ViewBranching(Space& home, ViewArray<typename ViewSel::View>& x,
00093                   ViewSel& vi_s);
00095     virtual bool status(const Space& home) const;
00097     virtual size_t dispose(Space& home);
00098   };
00099 
00100 
00110   template <class ViewSel, class ValSel>
00111   class ViewValBranching : public ViewBranching<ViewSel> {
00112   protected:
00113     using ViewBranching<ViewSel>::viewsel;
00114     using ViewBranching<ViewSel>::x;
00116     ValSel valsel;
00118     ViewValBranching(Space& home, bool share, ViewValBranching& b);
00119   public:
00121     ViewValBranching(Space& home, ViewArray<typename ViewSel::View>& x,
00122                      ViewSel& vi_s, ValSel& va_s);
00124     virtual const BranchingDesc* description(Space& home);
00126     virtual ExecStatus commit(Space& home, const BranchingDesc& d,
00127                               unsigned int a);
00129     virtual Actor* copy(Space& home, bool share);
00131     virtual size_t dispose(Space& home);
00132   };
00133 
00134 
00136   template <class ViewSel>
00137   class GECODE_VTABLE_EXPORT PosDesc : public BranchingDesc {
00138   private:
00140     const Pos _pos;
00142     const typename ViewSel::Desc _viewdesc;
00143   public:
00145     PosDesc(const Branching& b, unsigned int a, const Pos& p,
00146             const typename ViewSel::Desc& viewd);
00148     const Pos& pos(void) const;
00150     const typename ViewSel::Desc& viewdesc(void) const;
00152     virtual size_t size(void) const;
00153   };
00154 
00156   template <class ViewSel, class ValSel>
00157   class GECODE_VTABLE_EXPORT PosValDesc : public PosDesc<ViewSel> {
00158   private:
00160     const typename ValSel::Desc _valdesc;
00162     const typename ValSel::Val _val;
00163   public:
00165     PosValDesc(const Branching& b, const Pos& p,
00166                const typename ViewSel::Desc& viewd,
00167                const typename ValSel::Desc& vald,
00168                const typename ValSel::Val& n);
00170     const typename ValSel::Desc& valdesc(void) const;
00172     const typename ValSel::Val& val(void) const;
00174     virtual size_t size(void) const;
00175   };
00177 
00178 
00179 
00180 
00181   /*
00182    * Position information
00183    *
00184    */
00185   forceinline
00186   Pos::Pos(int p) : pos(p) {}
00187 
00188 
00189   /*
00190    * Branching descriptions with position
00191    *
00192    */
00193   template <class ViewSel>
00194   forceinline
00195   PosDesc<ViewSel>::PosDesc(const Branching& b, unsigned int a, const Pos& p,
00196                             const typename ViewSel::Desc& viewd)
00197     : BranchingDesc(b,a), _pos(p), _viewdesc(viewd) {}
00198   template <class ViewSel>
00199   forceinline const Pos&
00200   PosDesc<ViewSel>::pos(void) const {
00201     return _pos;
00202   }
00203   template <class ViewSel>
00204   forceinline const typename ViewSel::Desc&
00205   PosDesc<ViewSel>::viewdesc(void) const {
00206     return _viewdesc;
00207   }
00208   template <class ViewSel>
00209   forceinline size_t
00210   PosDesc<ViewSel>::size(void) const {
00211     return sizeof(PosDesc<ViewSel>) + _viewdesc.size();
00212   }
00213 
00214 
00215   /*
00216    * Branching descriptions with position and value
00217    *
00218    */
00219   template <class ViewSel, class ValSel>
00220   forceinline
00221   PosValDesc<ViewSel,ValSel>::PosValDesc(const Branching& b, const Pos& p,
00222                                          const typename ViewSel::Desc& viewd,
00223                                          const typename ValSel::Desc& vald,
00224                                          const typename ValSel::Val& n)
00225     : PosDesc<ViewSel>(b,ValSel::alternatives,p,viewd),
00226       _valdesc(vald), _val(n) {}
00227 
00228   template <class ViewSel, class ValSel>
00229   forceinline const typename ValSel::Desc&
00230   PosValDesc<ViewSel,ValSel>::valdesc(void) const {
00231     return _valdesc;
00232   }
00233 
00234   template <class ViewSel, class ValSel>
00235   forceinline const typename ValSel::Val&
00236   PosValDesc<ViewSel,ValSel>::val(void) const {
00237     return _val;
00238   }
00239 
00240   template <class ViewSel, class ValSel>
00241   forceinline size_t
00242   PosValDesc<ViewSel, ValSel>::size(void) const {
00243     return sizeof(PosValDesc<ViewSel,ValSel>) + _valdesc.size();
00244   }
00245 
00246 
00247   /*
00248    * Generic branching based on view selection
00249    *
00250    */
00251 
00252   template <class ViewSel>
00253   forceinline
00254   ViewBranching<ViewSel>::ViewBranching(Space& home,
00255                                         ViewArray<typename ViewSel::View>& x0,
00256                                         ViewSel& vi_s)
00257     : Branching(home), x(x0), start(0), viewsel(vi_s) {}
00258 
00259 
00260   template <class ViewSel>
00261   forceinline
00262   ViewBranching<ViewSel>::ViewBranching(Space& home, bool share,
00263                                         ViewBranching& b)
00264     : Branching(home,share,b), start(b.start) {
00265     x.update(home,share,b.x);
00266     viewsel.update(home,share,b.viewsel);
00267   }
00268 
00269   template <class ViewSel>
00270   bool
00271   ViewBranching<ViewSel>::status(const Space&) const {
00272     for (int i=start; i < x.size(); i++)
00273       if (!x[i].assigned()) {
00274         start = i;
00275         return true;
00276       }
00277     return false;
00278   }
00279 
00280   template <class ViewSel>
00281   forceinline Pos
00282   ViewBranching<ViewSel>::pos(Space& home) {
00283     assert(!x[start].assigned());
00284     int i = start;
00285     int b = i++;
00286     if (viewsel.init(home,x[b]) != VSS_BEST)
00287       for (; i < x.size(); i++)
00288         if (!x[i].assigned())
00289           switch (viewsel.select(home,x[i])) {
00290           case VSS_BETTER:              b=i; break;
00291           case VSS_BEST:                b=i; goto create;
00292           case VSS_TIE: case VSS_WORSE: break;
00293           default:                      GECODE_NEVER;
00294           }
00295   create:
00296     Pos p(b);
00297     return p;
00298   }
00299 
00300   template <class ViewSel>
00301   forceinline typename ViewSel::View
00302   ViewBranching<ViewSel>::view(const Pos& p) const {
00303     return x[p.pos];
00304   }
00305 
00306   template <class ViewSel>
00307   forceinline size_t
00308   ViewBranching<ViewSel>::dispose(Space& home) {
00309     viewsel.dispose(home);
00310     (void) Branching::dispose(home);
00311     return sizeof(ViewBranching<ViewSel>);
00312   }
00313 
00314 
00315 
00316   /*
00317    * Generic branching based on variable/value selection
00318    *
00319    */
00320 
00321   template <class ViewSel, class ValSel>
00322   forceinline
00323   ViewValBranching<ViewSel,ValSel>::
00324   ViewValBranching(Space& home, ViewArray<typename ViewSel::View>& x,
00325                    ViewSel& vi_s, ValSel& va_s)
00326     : ViewBranching<ViewSel>(home,x,vi_s), valsel(va_s) {}
00327 
00328   template <class ViewSel, class ValSel>
00329   forceinline
00330   ViewValBranching<ViewSel,ValSel>::
00331   ViewValBranching(Space& home, bool share, ViewValBranching& b)
00332     : ViewBranching<ViewSel>(home,share,b) {
00333     valsel.update(home,share,b.valsel);
00334   }
00335 
00336   template <class ViewSel, class ValSel>
00337   Actor*
00338   ViewValBranching<ViewSel,ValSel>::copy(Space& home, bool share) {
00339     return new (home)
00340       ViewValBranching<ViewSel,ValSel>(home,share,*this);
00341   }
00342 
00343   template <class ViewSel, class ValSel>
00344   const BranchingDesc*
00345   ViewValBranching<ViewSel,ValSel>::description(Space& home) {
00346     Pos p = ViewBranching<ViewSel>::pos(home);
00347     typename ValSel::View v(ViewBranching<ViewSel>::view(p).var());
00348     return new PosValDesc<ViewSel,ValSel>
00349       (*this,p,
00350        viewsel.description(home),
00351        valsel.description(home),valsel.val(home,v));
00352   }
00353 
00354   template <class ViewSel, class ValSel>
00355   ExecStatus
00356   ViewValBranching<ViewSel,ValSel>
00357   ::commit(Space& home, const BranchingDesc& d, unsigned int a) {
00358     const PosValDesc<ViewSel,ValSel>& pvd
00359       = static_cast<const PosValDesc<ViewSel,ValSel>&>(d);
00360     typename ValSel::View
00361       v(ViewBranching<ViewSel>::view(pvd.pos()).var());
00362     viewsel.commit(home, pvd.viewdesc(), a);
00363     valsel.commit(home, pvd.valdesc(), a);
00364     return me_failed(valsel.tell(home,a,v,pvd.val())) ? ES_FAILED : ES_OK;
00365   }
00366 
00367   template <class ViewSel, class ValSel>
00368   forceinline size_t
00369   ViewValBranching<ViewSel,ValSel>::dispose(Space& home) {
00370     valsel.dispose(home);
00371     (void) ViewBranching<ViewSel>::dispose(home);
00372     return sizeof(ViewValBranching<ViewSel,ValSel>);
00373   }
00374 
00375 }
00376 
00377 // STATISTICS: kernel-branch