/* -*- mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- */ /* * Main author: * Christian Schulte * * Copyright: * Christian Schulte, 2012 * * This file is part of Gecode, the generic constraint * development environment: * http://www.gecode.org * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * */ namespace Gecode { /** * \defgroup TaskBranchViewSel Generic view selection for brancher based on view and value selection * * \ingroup TaskBranchViewVal */ //@{ /// Abstract class for view selection template class ViewSel { public: /// Define the view type typedef View_ View; /// The corresponding variable type typedef typename View::VarType Var; /// \name Initialization //@{ /// Constructor for creation ViewSel(Space& home, const VarBranch& vb); /// Constructor for copying during cloning ViewSel(Space& home, ViewSel& vs); //@} /// \name View selection and tie breaking //@{ /// Select a view from \a x starting from \a s and return its position virtual int select(Space& home, ViewArray& x, int s) = 0; /// Select a view from \a x starting from \a s and return its position virtual int select(Space& home, ViewArray& x, int s, BrancherFilter& f) = 0; /// Select a view from \a x starting from \a s and return its position virtual int select(Space& home, ViewArray& x, int s, BrancherNoFilter& f); /// Select ties from \a x starting from \a s virtual void ties(Space& home, ViewArray& x, int s, int* ties, int& n) = 0; /// Select ties from \a x starting from \a s virtual void ties(Space& home, ViewArray& x, int s, int* ties, int& n, BrancherFilter& f) = 0; /// Select ties from \a x starting from \a s virtual void ties(Space& home, ViewArray& x, int s, int* ties, int& n, BrancherNoFilter& f); /// Break ties in \a x and update to new ties virtual void brk(Space& home, ViewArray& x, int* ties, int& n) = 0; /// Select a view from \a x considering views with positions in \a ties virtual int select(Space& home, ViewArray& x, int* ties, int n) = 0; //@} /// \name Resource management and cloning //@{ /// Create copy during cloning virtual ViewSel* copy(Space& home) = 0; /// Whether dispose must always be called (that is, notice is needed) virtual bool notice(void) const; /// Dispose view selection virtual void dispose(Space& home); /// Unused destructor virtual ~ViewSel(void); //@} /// \name Memory management //@{ /// Allocate memory from space static void* operator new(size_t s, Space& home); /// Return memory to space static void operator delete(void* p, Space& home); /// Needed for exceptions static void operator delete(void* p); //@} }; /// Select the first unassigned view template class ViewSelNone : public ViewSel { protected: typedef typename ViewSel::Var Var; public: /// \name Initialization //@{ /// Constructor for creation ViewSelNone(Space& home, const VarBranch& vb); /// Constructor for copying during cloning ViewSelNone(Space& home, ViewSelNone& vs); //@} /// \name View selection and tie breaking //@{ /// Select a view from \a x starting at \a s and return its position virtual int select(Space& home, ViewArray& x, int s); /// Select a view from \a x starting at \a s and return its position virtual int select(Space& home, ViewArray& x, int s, BrancherFilter& f); /// Select ties from \a x starting at \a s virtual void ties(Space& home, ViewArray& x, int s, int* ties, int& n); /// Select ties from \a x starting at \a s virtual void ties(Space& home, ViewArray& x, int s, int* ties, int& n, BrancherFilter& f); /// Break ties in \a x and update to new ties virtual void brk(Space& home, ViewArray& x, int* ties, int& n); /// Select a view from \a x considering view with positions in \a ties virtual int select(Space& home, ViewArray& x, int* ties, int n); //@} /// \name Resource management and cloning //@{ /// Create copy during cloning virtual ViewSel* copy(Space& home); //@} }; /// Select a view randomly template class ViewSelRnd : public ViewSel { protected: typedef typename ViewSel::Var Var; /// The random number generator used Rnd r; public: /// \name Initialization //@{ /// Constructor for creation ViewSelRnd(Space& home, const VarBranch& vb); /// Constructor for copying during cloning ViewSelRnd(Space& home, ViewSelRnd& vs); //@} /// \name View selection and tie breaking //@{ /// Select a view from \a x starting from \a s and return its position virtual int select(Space& home, ViewArray& x, int s); /// Select a view from \a x starting from \a s and return its position virtual int select(Space& home, ViewArray& x, int s, BrancherFilter& f); /// Select ties from \a x starting from \a s virtual void ties(Space& home, ViewArray& x, int s, int* ties, int& n); /// Select ties from \a x starting from \a s virtual void ties(Space& home, ViewArray& x, int s, int* ties, int& n, BrancherFilter& f); /// Break ties in \a x and update to new ties virtual void brk(Space& home, ViewArray& x, int* ties, int& n); /// Select a view from \a x considering view with positions in \a ties virtual int select(Space& home, ViewArray& x, int* ties, int n); //@} /// \name Resource management and cloning //@{ /// Create copy during cloning virtual ViewSel* copy(Space& home); //@} }; /// Choose views with smaller merit values class ChooseMin { public: /// Return true if \a a is better than \a b template bool operator ()(Val a, Val b) const; }; /// Choose views with larger merit values class ChooseMax { public: /// Return true if \a a is better than \a b template bool operator ()(Val a, Val b) const; }; /// Choose view according to merit template class ViewSelChoose : public ViewSel { protected: typedef typename ViewSel::Var Var; typedef typename ViewSel::View View; /// Type of merit typedef typename Merit::Val Val; /// How to choose Choose c; /// The merit object used Merit m; public: /// \name Initialization //@{ /// Constructor for creation ViewSelChoose(Space& home, const VarBranch& vb); /// Constructor for copying during cloning ViewSelChoose(Space& home, ViewSelChoose& vs); //@} /// \name View selection and tie breaking //@{ /// Select a view from \a x starting from \a s and return its position virtual int select(Space& home, ViewArray& x, int s); /// Select a view from \a x starting from \a s and return its position virtual int select(Space& home, ViewArray& x, int s, BrancherFilter& f); /// Select ties from \a x starting from \a s virtual void ties(Space& home, ViewArray& x, int s, int* ties, int& n); /// Select ties from \a x starting from \a s virtual void ties(Space& home, ViewArray& x, int s, int* ties, int& n, BrancherFilter& f); /// Break ties in \a x and update to new ties virtual void brk(Space& home, ViewArray& x, int* ties, int& n); /// Select a view from \a x considering views with positions in \a ties virtual int select(Space& home, ViewArray& x, int* ties, int n); //@} /// \name Resource management and cloning //@{ /// Whether dispose must always be called (that is, notice is needed) virtual bool notice(void) const; /// Delete view selection virtual void dispose(Space& home); //@} }; /// Choose view according to merit taking tie-break limit into account template class ViewSelChooseTbl : public ViewSelChoose { protected: typedef typename ViewSelChoose::Val Val; typedef typename ViewSelChoose::View View; typedef typename ViewSelChoose::Var Var; using ViewSelChoose::c; using ViewSelChoose::m; /// Tie-break limit function SharedData tbl; public: /// \name Initialization //@{ /// Constructor for initialization ViewSelChooseTbl(Space& home, const VarBranch& vb); /// Constructor for copying during cloning ViewSelChooseTbl(Space& home, ViewSelChooseTbl& vs); //@} /// \name View selection and tie breaking //@{ /// Select ties from \a x starting from \a s virtual void ties(Space& home, ViewArray& x, int s, int* ties, int& n); /// Select ties from \a x starting from \a s virtual void ties(Space& home, ViewArray& x, int s, int* ties, int& n, BrancherFilter& f); /// Break ties in \a x and update to new ties virtual void brk(Space& home, ViewArray& x, int* ties, int& n); //@} /// \name Resource management and cloning //@{ /// Whether dispose must always be called (that is, notice is needed) virtual bool notice(void) const; /// Delete view selection virtual void dispose(Space& home); //@} }; /// Select view with least merit template class ViewSelMin : public ViewSelChoose { typedef typename ViewSelChoose::View View; typedef typename ViewSelChoose::Var Var; public: /// \name Initialization //@{ /// Constructor for initialization ViewSelMin(Space& home, const VarBranch& vb); /// Constructor for copying during cloning ViewSelMin(Space& home, ViewSelMin& vs); //@} /// \name Resource management and cloning //@{ /// Create copy during cloning virtual ViewSel* copy(Space& home); //@} }; /// Select view with least merit taking tie-break limit into account template class ViewSelMinTbl : public ViewSelChooseTbl { typedef typename ViewSelChooseTbl::View View; typedef typename ViewSelChooseTbl::Var Var; public: /// \name Initialization //@{ /// Constructor for initialization ViewSelMinTbl(Space& home, const VarBranch& vb); /// Constructor for copying during cloning ViewSelMinTbl(Space& home, ViewSelMinTbl& vs); //@} /// \name Resource management and cloning //@{ /// Create copy during cloning virtual ViewSel* copy(Space& home); //@} }; /// Select view with largest merit template class ViewSelMax : public ViewSelChoose { typedef typename ViewSelChoose::View View; typedef typename ViewSelChoose::Var Var; public: /// \name Initialization //@{ /// Constructor for initialization ViewSelMax(Space& home, const VarBranch& vb); /// Constructor for copying during cloning ViewSelMax(Space& home, ViewSelMax& vs); //@} /// \name Resource management and cloning //@{ /// Create copy during cloning virtual ViewSel* copy(Space& home); //@} }; /// Select view with largest merit taking tie-break limit into account template class ViewSelMaxTbl : public ViewSelChooseTbl { typedef typename ViewSelChooseTbl::View View; typedef typename ViewSelChooseTbl::Var Var; public: /// \name Initialization //@{ /// Constructor for initialization ViewSelMaxTbl(Space& home, const VarBranch& vb); /// Constructor for copying during cloning ViewSelMaxTbl(Space& home, ViewSelMaxTbl& vs); //@} /// \name Resource management and cloning //@{ /// Create copy during cloning virtual ViewSel* copy(Space& home); //@} }; //@} template forceinline ViewSel::ViewSel(Space&, const VarBranch&) {} template forceinline ViewSel::ViewSel(Space&, ViewSel&) {} template int ViewSel::select(Space&, ViewArray&, int, BrancherNoFilter&) { GECODE_NEVER; return 0; } template void ViewSel::ties(Space&, ViewArray&, int, int*, int&, BrancherNoFilter&) { GECODE_NEVER; } template bool ViewSel::notice(void) const { return false; } template void ViewSel::dispose(Space&) {} template ViewSel::~ViewSel(void) {} template forceinline void ViewSel::operator delete(void*) {} template forceinline void ViewSel::operator delete(void*, Space&) {} template forceinline void* ViewSel::operator new(size_t s, Space& home) { return home.ralloc(s); } template forceinline ViewSelNone::ViewSelNone(Space& home, const VarBranch& vb) : ViewSel(home,vb) {} template forceinline ViewSelNone::ViewSelNone(Space& home, ViewSelNone& vs) : ViewSel(home,vs) {} template int ViewSelNone::select(Space&, ViewArray&, int s) { return s; } template int ViewSelNone::select(Space&, ViewArray&, int s, BrancherFilter&) { return s; } template void ViewSelNone::ties(Space&, ViewArray& x, int s, int* ties, int& n) { int j=0; ties[j++]=s; for (int i=s+1; i 0); } template void ViewSelNone::ties(Space& home, ViewArray& x, int s, int* ties, int& n, BrancherFilter& f) { int j=0; ties[j++]=s; for (int i=s+1; i 0); } template void ViewSelNone::brk(Space&, ViewArray&, int*, int&) { // Nothing needs to be done } template int ViewSelNone::select(Space&, ViewArray&, int* ties, int) { return ties[0]; } template ViewSel* ViewSelNone::copy(Space& home) { return new (home) ViewSelNone(home,*this); } template forceinline ViewSelRnd::ViewSelRnd(Space& home, const VarBranch& vb) : ViewSel(home,vb), r(vb.rnd()) {} template forceinline ViewSelRnd::ViewSelRnd(Space& home, ViewSelRnd& vs) : ViewSel(home,vs), r(vs.r) {} template int ViewSelRnd::select(Space&, ViewArray& x, int s) { unsigned int n=1; int j=s; for (int i=s+1; i int ViewSelRnd::select(Space& home, ViewArray& x, int s, BrancherFilter& f) { unsigned int n=1; int j=s; for (int i=s+1; i void ViewSelRnd::ties(Space& home, ViewArray& x, int s, int* ties, int& n) { n=1; ties[0] = select(home,x,s); } template void ViewSelRnd::ties(Space& home, ViewArray& x, int s, int* ties, int& n, BrancherFilter&) { n=1; ties[0] = select(home,x,s); } template void ViewSelRnd::brk(Space&, ViewArray&, int* ties, int& n) { ties[0] = ties[static_cast(r(static_cast(n)))]; n=1; } template int ViewSelRnd::select(Space&, ViewArray&, int* ties, int n) { return ties[static_cast(r(static_cast(n)))]; } template ViewSel* ViewSelRnd::copy(Space& home) { return new (home) ViewSelRnd(home,*this); } template forceinline bool ChooseMin::operator ()(Val a, Val b) const { return a < b; } template forceinline bool ChooseMax::operator ()(Val a, Val b) const { return a > b; } template forceinline ViewSelChoose::ViewSelChoose(Space& home, const VarBranch& vb) : ViewSel(home,vb), m(home,vb) {} template forceinline ViewSelChoose::ViewSelChoose(Space& home, ViewSelChoose& vs) : ViewSel(home,vs), m(home,vs.m) {} template int ViewSelChoose::select(Space& home, ViewArray& x, int s) { // Consider x[s] as the so-far best view int b_i = s; Val b_m = m(home,x[s],s); // Scan all non-assigned views from s+1 onwards for (int i=s+1; i int ViewSelChoose::select(Space& home, ViewArray& x, int s, BrancherFilter& f) { // Consider x[s] as the so-far best view int b_i = s; Val b_m = m(home,x[s],s); // Scan all non-assigned views from s+1 onwards for (int i=s+1; i void ViewSelChoose::ties(Space& home, ViewArray& x, int s, int* ties, int& n) { // Consider x[s] as the so-far best view and record as tie Val b = m(home,x[s],s); int j=0; ties[j++]=s; for (int i=s+1; i 0); } template void ViewSelChoose::ties(Space& home, ViewArray& x, int s, int* ties, int& n, BrancherFilter& f) { // Consider x[s] as the so-far best view and record as tie Val b = m(home,x[s],s); int j=0; ties[j++]=s; for (int i=s+1; i 0); } template void ViewSelChoose::brk(Space& home, ViewArray& x, int* ties, int& n) { // Keep first tie in place Val b = m(home,x[ties[0]],ties[0]); int j=1; // Scan remaining ties for (int i=1; i 0); } template int ViewSelChoose::select(Space& home, ViewArray& x, int* ties, int n) { int b_i = ties[0]; Val b_m = m(home,x[ties[0]],ties[0]); for (int i=1; i bool ViewSelChoose::notice(void) const { return m.notice(); } template void ViewSelChoose::dispose(Space& home) { m.dispose(home); } template forceinline ViewSelChooseTbl::ViewSelChooseTbl(Space& home, const VarBranch& vb) : ViewSelChoose(home,vb), tbl(vb.tbl()) { if (!tbl()) throw InvalidFunction("ViewSelChooseTbl::ViewSelChooseTbl"); } template forceinline ViewSelChooseTbl::ViewSelChooseTbl (Space& home, ViewSelChooseTbl& vs) : ViewSelChoose(home,vs), tbl(vs.tbl) { } template void ViewSelChooseTbl::ties(Space& home, ViewArray& x, int s, int* ties, int& n) { // Find the worst and best merit value Val w = m(home,x[s],s); Val b = w; for (int i=s+1; i(w),static_cast(b)); // If the limit is not better than the worst merit, everything is a tie if (!c(l,static_cast(w))) { int j=0; for (int i=s; i(b))) l = static_cast(b); // Record all ties that are not worse than the limit merit value int j=0; for (int i=s; i(m(home,x[i],i)))) ties[j++]=i; n=j; } // There will be at least one tie (the best will qualify, of course) assert(n > 0); } template void ViewSelChooseTbl::ties(Space& home, ViewArray& x, int s, int* ties, int& n, BrancherFilter& f) { // Find the worst and best merit value assert(f(home,x[s],s)); Val w = m(home,x[s],s); Val b = w; for (int i=s+1; i(w),static_cast(b)); // If the limit is not better than the worst merit, everything is a tie if (!c(l,static_cast(w))) { int j=0; for (int i=s; i(b))) l = static_cast(b); // Record all ties that are not worse than the limit merit value int j=0; for (int i=s; i(m(home,x[i],i)))) ties[j++]=i; n=j; } // There will be at least one tie (the best will qualify, of course) assert(n > 0); } template void ViewSelChooseTbl::brk(Space& home, ViewArray& x, int* ties, int& n) { // Find the worst and best merit value Val w = m(home,x[ties[0]],ties[0]); Val b = w; for (int i=1; i(w),static_cast(b)); // If the limit is not better than the worst merit, everything is a tie // and no breaking is required if (c(l,static_cast(w))) { // The limit is not allowed to better than the best merit value if (c(l,static_cast(b))) l = static_cast(b); // Keep all ties that are not worse than the limit merit value int j=0; for (int i=0; i(m(home,x[ties[i]],ties[i])))) ties[j++]=ties[i]; n=j; } // There will be at least one tie (the best will qualify) assert(n > 0); } template bool ViewSelChooseTbl::notice(void) const { return true; } template void ViewSelChooseTbl::dispose(Space&) { tbl.~SharedData(); } template forceinline ViewSelMin::ViewSelMin(Space& home, const VarBranch& vb) : ViewSelChoose(home,vb) {} template forceinline ViewSelMin::ViewSelMin(Space& home, ViewSelMin& vs) : ViewSelChoose(home,vs) {} template ViewSel::View>* ViewSelMin::copy(Space& home) { return new (home) ViewSelMin(home,*this); } template forceinline ViewSelMinTbl::ViewSelMinTbl(Space& home, const VarBranch& vb) : ViewSelChooseTbl(home,vb) {} template forceinline ViewSelMinTbl::ViewSelMinTbl(Space& home, ViewSelMinTbl& vs) : ViewSelChooseTbl(home,vs) {} template ViewSel::View>* ViewSelMinTbl::copy(Space& home) { return new (home) ViewSelMinTbl(home,*this); } template forceinline ViewSelMax::ViewSelMax(Space& home, const VarBranch& vb) : ViewSelChoose(home,vb) {} template forceinline ViewSelMax::ViewSelMax(Space& home, ViewSelMax& vs) : ViewSelChoose(home,vs) {} template ViewSel::View>* ViewSelMax::copy(Space& home) { return new (home) ViewSelMax(home,*this); } template forceinline ViewSelMaxTbl::ViewSelMaxTbl(Space& home, const VarBranch& vb) : ViewSelChooseTbl(home,vb) {} template forceinline ViewSelMaxTbl::ViewSelMaxTbl(Space& home, ViewSelMaxTbl& vs) : ViewSelChooseTbl(home,vs) {} template ViewSel::View>* ViewSelMaxTbl::copy(Space& home) { return new (home) ViewSelMaxTbl(home,*this); } } // STATISTICS: kernel-branch