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

brancher-view.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  *
00006  *  Copyright:
00007  *     Christian Schulte, 2012
00008  *
00009  *  Last modified:
00010  *     $Date: 2013-05-22 16:48:57 +0200 (Wed, 22 May 2013) $ by $Author: schulte $
00011  *     $Revision: 13654 $
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 namespace Gecode {
00039 
00047 
00048   class Pos {
00049   public:
00051     const int pos;
00053     Pos(int p);
00054   };
00055 
00057   class GECODE_VTABLE_EXPORT PosChoice : public Choice {
00058   private:
00060     const Pos _pos;
00061   public:
00063     PosChoice(const Brancher& b, unsigned int a, const Pos& p);
00065     const Pos& pos(void) const;
00067     virtual size_t size(void) const;
00069     virtual void archive(Archive& e) const;
00070   };
00071 
00078   template<class View, int n>
00079   class ViewBrancher : public Brancher {
00080   protected:
00082     typedef typename BranchTraits<typename View::VarType>::Filter BranchFilter;
00084     ViewArray<View> x;
00086     mutable int start;
00088     ViewSel<View>* vs[n];
00090     BranchFilter bf;
00092     Pos pos(Space& home);
00094     View view(const Pos& p) const;
00096     ViewBrancher(Space& home, bool shared, ViewBrancher<View,n>& b);
00098     ViewBrancher(Home home, ViewArray<View>& x,
00099                  ViewSel<View>* vs[n], BranchFilter bf);
00100   public:
00102     virtual bool status(const Space& home) const;
00104     virtual size_t dispose(Space& home);
00105   };
00106 
00108 
00109 
00110   /*
00111    * Position information
00112    *
00113    */
00114   forceinline
00115   Pos::Pos(int p) : pos(p) {}
00116 
00117   /*
00118    * Choice with position
00119    *
00120    */
00121   forceinline
00122   PosChoice::PosChoice(const Brancher& b, unsigned int a, const Pos& p)
00123     : Choice(b,a), _pos(p) {}
00124   forceinline const Pos&
00125   PosChoice::pos(void) const {
00126     return _pos;
00127   }
00128   forceinline size_t
00129   PosChoice::size(void) const {
00130     return sizeof(PosChoice);
00131   }
00132   forceinline void
00133   PosChoice::archive(Archive& e) const {
00134     Choice::archive(e);
00135     e << _pos.pos;
00136   }
00137 
00138   template<class View, int n>
00139   forceinline
00140   ViewBrancher<View,n>::ViewBrancher(Home home, ViewArray<View>& x0,
00141                                      ViewSel<View>* vs0[n], BranchFilter bf0)
00142     : Brancher(home), x(x0), start(0), bf(bf0) {
00143     for (int i=0; i<n; i++)
00144       vs[i] = vs0[i];
00145     for (int i=0; i<n; i++)
00146       if (vs[i]->notice()) {
00147         home.notice(*this,AP_DISPOSE);
00148         break;
00149       }
00150   }
00151 
00152   template<class View, int n>
00153   forceinline
00154   ViewBrancher<View,n>::ViewBrancher(Space& home, bool shared,
00155                                      ViewBrancher<View,n>& vb)
00156     : Brancher(home,shared,vb), start(vb.start), bf(vb.bf) {
00157     x.update(home,shared,vb.x);
00158     for (int i=0; i<n; i++)
00159       vs[i] = vb.vs[i]->copy(home,shared);
00160   }
00161 
00162   template<class View, int n>
00163   bool
00164   ViewBrancher<View,n>::status(const Space& home) const {
00165     if (bf == NULL) {
00166       for (int i=start; i < x.size(); i++)
00167         if (!x[i].assigned()) {
00168           start = i;
00169           return true;
00170         }
00171     } else {
00172       for (int i=start; i < x.size(); i++) {
00173         typename View::VarType y(x[i].varimp());
00174         if (!x[i].assigned() && bf(home,y,i)) {
00175           start = i;
00176           return true;
00177         }
00178       }
00179     }
00180     return false;
00181   }
00182 
00183   template<class View, int n>
00184   inline Pos
00185   ViewBrancher<View,n>::pos(Space& home) {
00186     assert(!x[start].assigned());
00187     int s;
00188     if (bf == NULL) {
00189       if (n == 1) {
00190         s = vs[0]->select(home,x,start);
00191       } else {
00192         Region r(home);
00193         int* ties = r.alloc<int>(x.size()-start+1);
00194         int n_ties;
00195         vs[0]->ties(home,x,start,ties,n_ties);
00196         for (int i=1; (i < n-1) && (n_ties > 1); i++)
00197           vs[i]->brk(home,x,ties,n_ties);
00198         if (n_ties > 1)
00199           s = vs[n-1]->select(home,x,ties,n_ties);
00200         else
00201           s = ties[0];
00202       }
00203     } else {
00204       if (n == 1) {
00205         s = vs[0]->select(home,x,start,bf);
00206       } else {
00207         Region r(home);
00208         int* ties = r.alloc<int>(x.size()-start+1);
00209         int n_ties;
00210         vs[0]->ties(home,x,start,ties,n_ties,bf);
00211         for (int i=1; (i < n-1) && (n_ties > 1); i++)
00212           vs[i]->brk(home,x,ties,n_ties);
00213         if (n_ties > 1)
00214           s = vs[n-1]->select(home,x,ties,n_ties);
00215         else
00216           s = ties[0];
00217       }
00218     }
00219     Pos p(s);
00220     return p;
00221   }
00222 
00223   template<class View, int n>
00224   forceinline View
00225   ViewBrancher<View,n>::view(const Pos& p) const {
00226     return x[p.pos];
00227   }
00228 
00229   template<class View, int n>
00230   forceinline size_t
00231   ViewBrancher<View,n>::dispose(Space& home) {
00232     for (int i=0; i<n; i++)
00233       if (vs[i]->notice()) {
00234         home.ignore(*this,AP_DISPOSE,true);
00235         break;
00236       }
00237     for (int i=0; i<n; i++)
00238       vs[i]->dispose(home);
00239     (void) Brancher::dispose(home);
00240     return sizeof(ViewBrancher<View,n>);
00241   }
00242 
00243 }
00244 
00245 // STATISTICS: kernel-branch