/* -*- mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- */ /* * Main author: * Christian Schulte * * Copyright: * Christian Schulte, 2008 * * Last modified: * $Date: 2011-05-11 20:44:17 +1000 (Wed, 11 May 2011) $ by $Author: tack $ * $Revision: 12001 $ * * 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 TaskBranchTieBreak Generic view tie-breaking for brancher based on view and value selection * * \ingroup TaskBranchViewVal */ //@{ /** * \brief View selection class for static tie breaking */ template class ViewSelTieBreakStatic { protected: /// First selection class A a; /// Second selection class B b; public: /// View type typedef typename A::View View; /// View selection choice class Choice { public: /// First choice typename A::Choice a; /// Second choice typename B::Choice b; /// Constructor Choice(const typename A::Choice& a, const typename B::Choice& b); /// Report size occupied size_t size(void) const; /// Archive into \a e void archive(Archive& e) const; }; /// Default constructor ViewSelTieBreakStatic(void); /// Constructor for initialization ViewSelTieBreakStatic(Space& home, A& a, B& b); /// Intialize with view \a x ViewSelStatus init(Space& home, typename A::View x); /// Possibly select better view \a x ViewSelStatus select(Space& home, typename A::View x); /// Return choice Choice choice(Space& home); /// Return choice Choice choice(const Space& home, Archive& e); /// Commit to choice void commit(Space& home, const Choice& c, unsigned int a); /// Updating during cloning void update(Space& home, bool share, ViewSelTieBreakStatic& vs); /// Delete view selection void dispose(Space& home); }; /** * \brief Virtualized choice baseclass */ class ChoiceVirtualBase { public: /// Create copy virtual ChoiceVirtualBase* copy(void) const = 0; /// Report size required virtual size_t size(void) const = 0; /// Destructor GECODE_KERNEL_EXPORT virtual ~ChoiceVirtualBase(void); /// Archive into \a e virtual void archive(Archive& e) const = 0; /// \name Memory management //@{ /// Allocate memory static void* operator new(size_t s); /// Delete memory static void operator delete(void*); //@} }; /** * \brief Virtualized view selection base class */ template class ViewSelVirtualBase { public: /// Intialize with view \a x virtual ViewSelStatus init(Space& home, View x) = 0; /// Possibly select better view \a x virtual ViewSelStatus select(Space& home, View x) = 0; /// Return choice virtual ChoiceVirtualBase* choice(Space& home) = 0; /// Return choice virtual ChoiceVirtualBase* choice(const Space& home, Archive& e) = 0; /// Commit to choice virtual void commit(Space& home, const ChoiceVirtualBase* c, unsigned int a) = 0; /// Create copy virtual ViewSelVirtualBase* copy(Space& home, bool share) = 0; /// Delete view selection and return its size virtual size_t dispose(Space& home) = 0; /// \name Memory management //@{ /// Allocate memory from space static void* operator new(size_t s, Space& home); /// No-op for exceptions static void operator delete(void* p, Space& home); /// Needed for exceptions static void operator delete(void*); //@} }; /** * \brief Virtualized choice */ template class ChoiceVirtual : public ChoiceVirtualBase { public: /// Static choice object Choice choice; /// Constructor for initialization ChoiceVirtual(const Choice& c); /// Create copy virtual ChoiceVirtualBase* copy(void) const; /// Report size required virtual size_t size(void) const; /// Destructor virtual ~ChoiceVirtual(void); /// Archive into \a e virtual void archive(Archive& e) const; }; /** * \brief Virtualized view selection */ template class ViewSelVirtual : public ViewSelVirtualBase { protected: /// Static view selection object ViewSel viewsel; public: /// Constructor for initialization ViewSelVirtual(Space& home, const VarBranchOptions& vbo); /// Constructor for cloning \a vsv ViewSelVirtual(Space& home, bool share, ViewSelVirtual& vsv); /// Intialize with view \a x virtual ViewSelStatus init(Space& home, typename ViewSel::View x); /// Possibly select better view \a x virtual ViewSelStatus select(Space& home, typename ViewSel::View x); /// Return choice virtual ChoiceVirtualBase* choice(Space& home); /// Return choice virtual ChoiceVirtualBase* choice(const Space& home, Archive& e); /// Commit to choice virtual void commit(Space& home, const ChoiceVirtualBase* d, unsigned int a); /// Create copy during cloning virtual ViewSelVirtualBase* copy(Space& home, bool share); /// Delete view selection and returns its size virtual size_t dispose(Space& home); }; /** * \brief View selection class for dynamic tie breaking */ template class ViewSelTieBreakDynamic { protected: /// Number of tie breakers int n; /// Tie breakers ViewSelVirtualBase<_View>** tb; public: /// View type typedef _View View; /// %Choice for tie breakers class Choice { public: /// Number of choices int n; /// Choices ChoiceVirtualBase** c; /// Constructor Choice(Space& home, ViewSelVirtualBase<_View>** tb, int n0); /// Constructor Choice(const Space& home, Archive& e, ViewSelVirtualBase<_View>** tb, int n0); /// Copy constructor Choice(const Choice& ce); /// Assignment operator const Choice& operator =(const Choice& ce); /// Perform commit void commit(Space& home, unsigned int a, ViewSelVirtualBase<_View>** tb) const; /// Report size occupied size_t size(void) const; /// Destructor ~Choice(void); /// Archive into \a e void archive(Archive& e) const; }; /// Default constructor ViewSelTieBreakDynamic(void); /// Constructor for initialization ViewSelTieBreakDynamic(Space& home, ViewSelVirtualBase<_View>** vsv, int n); /// Intialize with view \a x ViewSelStatus init(Space& home, _View x); /// Possibly select better view \a x ViewSelStatus select(Space& home, _View x); /// Return choice Choice choice(Space& home); /// Return choice Choice choice(const Space& home, Archive& e); /// Commit to choice void commit(Space& home, const typename ViewSelTieBreakDynamic<_View>::Choice& c, unsigned int a); /// Updating during cloning void update(Space& home, bool share, ViewSelTieBreakDynamic& vs); /// Delete view selection void dispose(Space& home); }; //@} // Select variable with static tie breaking template forceinline ViewSelTieBreakStatic::Choice::Choice(const typename A::Choice& a0, const typename B::Choice& b0) : a(a0), b(b0) {} template forceinline size_t ViewSelTieBreakStatic::Choice::size(void) const { return a.size() + b.size(); } template forceinline void ViewSelTieBreakStatic::Choice::archive(Archive& e) const { a.archive(e); b.archive(e); } template forceinline ViewSelTieBreakStatic::ViewSelTieBreakStatic(void) {} template forceinline ViewSelTieBreakStatic:: ViewSelTieBreakStatic(Space&, A& a0, B& b0) : a(a0), b(b0) {} template forceinline ViewSelStatus ViewSelTieBreakStatic::init(Space& home, typename A::View x) { ViewSelStatus s = a.init(home,x); return (b.init(home,x) != VSS_BEST) ? VSS_BETTER : s; } template forceinline ViewSelStatus ViewSelTieBreakStatic::select(Space& home, typename A::View x) { switch (a.select(home,x)) { case VSS_BEST: return (b.init(home,x) != VSS_BEST) ? VSS_BETTER : VSS_BEST; case VSS_BETTER: (void) b.init(home,x); return VSS_BETTER; case VSS_WORSE: return VSS_WORSE; case VSS_TIE: switch (b.select(home,x)) { case VSS_BEST: return VSS_BETTER; case VSS_BETTER: return VSS_BETTER; case VSS_TIE: return VSS_TIE; case VSS_WORSE: return VSS_WORSE; default: GECODE_NEVER; } default: GECODE_NEVER; return VSS_WORSE; } } template inline typename ViewSelTieBreakStatic::Choice ViewSelTieBreakStatic::choice(Space& home) { typename ViewSelTieBreakStatic::Choice c(a.choice(home), b.choice(home)); return c; } template inline typename ViewSelTieBreakStatic::Choice ViewSelTieBreakStatic::choice(const Space& home, Archive& e) { typename ViewSelTieBreakStatic::Choice c(a.choice(home,e), b.choice(home,e)); return c; } template forceinline void ViewSelTieBreakStatic::commit(Space& home, const Choice& c, unsigned int al) { a.commit(home, c.a, al); b.commit(home, c.b, al); } template forceinline void ViewSelTieBreakStatic::update(Space& home, bool share, ViewSelTieBreakStatic& vstb) { a.update(home,share,vstb.a); b.update(home,share,vstb.b); } template forceinline void ViewSelTieBreakStatic::dispose(Space& home) { a.dispose(home); b.dispose(home); } // Virtualized view selection template forceinline void ViewSelVirtualBase::operator delete(void*) {} template forceinline void ViewSelVirtualBase::operator delete(void*, Space&) {} template forceinline void* ViewSelVirtualBase::operator new(size_t s, Space& home) { return home.ralloc(s); } // Virtualized choice forceinline void ChoiceVirtualBase::operator delete(void* p) { heap.rfree(p); } forceinline void* ChoiceVirtualBase::operator new(size_t s) { return heap.ralloc(s); } forceinline ChoiceVirtualBase::~ChoiceVirtualBase(void) { } template forceinline ChoiceVirtual::ChoiceVirtual(const Choice& c) : choice(c) {} template forceinline ChoiceVirtualBase* ChoiceVirtual::copy(void) const { return new ChoiceVirtual(choice); } template forceinline size_t ChoiceVirtual::size(void) const { return sizeof(ChoiceVirtual); } template ChoiceVirtual::~ChoiceVirtual(void) {} template void ChoiceVirtual::archive(Archive& e) const { choice.archive(e); } template forceinline ViewSelVirtual::ViewSelVirtual(Space& home, const VarBranchOptions& vbo) : viewsel(home,vbo) {} template forceinline ViewSelVirtual::ViewSelVirtual(Space& home, bool share, ViewSelVirtual& vsv) { viewsel.update(home,share,vsv.viewsel); } template ViewSelStatus ViewSelVirtual::init(Space& home, typename ViewSel::View x) { return viewsel.init(home,x); } template ViewSelStatus ViewSelVirtual::select(Space& home, typename ViewSel::View x) { return viewsel.select(home,x); } template ChoiceVirtualBase* ViewSelVirtual::choice(Space& home) { return new ChoiceVirtual(viewsel.choice(home)); } template ChoiceVirtualBase* ViewSelVirtual::choice(const Space& home, Archive& e) { return new ChoiceVirtual(viewsel.choice(home,e)); } template void ViewSelVirtual::commit(Space& home, const ChoiceVirtualBase* _c, unsigned int a) { const ChoiceVirtual* c = static_cast*>(_c); viewsel.commit(home, c->choice, a); } template ViewSelVirtualBase* ViewSelVirtual::copy(Space& home, bool share) { return new (home) ViewSelVirtual(home,share,*this); } template size_t ViewSelVirtual::dispose(Space& home) { viewsel.dispose(home); return sizeof(ViewSelVirtual); } // Choice for dynamic tie breaking template forceinline ViewSelTieBreakDynamic::Choice::Choice (Space& home, ViewSelVirtualBase** tb, int n0) : n(n0), c(heap.alloc(n)) { for (int i=n; i--; ) c[i] = tb[i]->choice(home); } template forceinline ViewSelTieBreakDynamic::Choice::Choice (const Space& home, Archive& e, ViewSelVirtualBase** tb, int n0) : n(n0), c(heap.alloc(n)) { for (int i=n; i--; ) c[i] = tb[i]->choice(home,e); } template forceinline ViewSelTieBreakDynamic::Choice::Choice(const Choice& ce) : n(ce.n), c(heap.alloc(n)) { for (int i=n; i--; ) c[i] = ce.c[i]->copy(); } template forceinline const typename ViewSelTieBreakDynamic::Choice& ViewSelTieBreakDynamic::Choice::operator =(const Choice& ce) { if (&ce != this) { assert(ce.n == n); for (int i=n; i--; ) { delete c[i]; c[i] = ce.c[i]->copy(); } } return *this; } template forceinline void ViewSelTieBreakDynamic::Choice::commit (Space& home, unsigned int a, ViewSelVirtualBase** tb) const { for (int i=n; i--; ) tb[i]->commit(home, c[i], a); } template forceinline size_t ViewSelTieBreakDynamic::Choice::size(void) const { size_t s = (sizeof(typename ViewSelTieBreakDynamic::Choice) + n * sizeof(ChoiceVirtualBase*)); for (int i=n; i--; ) s += c[i]->size(); return s; } template forceinline ViewSelTieBreakDynamic::Choice::~Choice(void) { for (int i=n; i--; ) delete c[i]; heap.free(c,n); } template forceinline void ViewSelTieBreakDynamic::Choice::archive(Archive& e) const { for (int i=0; iarchive(e); } // Select variable with dynamic tie breaking template forceinline ViewSelTieBreakDynamic::ViewSelTieBreakDynamic(void) {} template forceinline ViewSelTieBreakDynamic:: ViewSelTieBreakDynamic(Space& home, ViewSelVirtualBase** vsv, int n0) : n(n0), tb(home.alloc*>(n)) { for (int i=0; i 0); } template forceinline ViewSelStatus ViewSelTieBreakDynamic::init(Space& home, View x) { ViewSelStatus s = VSS_BEST; for (int i=0; iinit(home,x) != VSS_BEST) s = VSS_BETTER; return s; } template forceinline ViewSelStatus ViewSelTieBreakDynamic::select(Space& home, View x) { switch (tb[0]->select(home,x)) { case VSS_BEST: { ViewSelStatus s = VSS_BEST; for (int i=1; iinit(home,x) != VSS_BEST) s = VSS_BETTER; return s; } case VSS_BETTER: for (int i=1; iinit(home,x); return VSS_BETTER; case VSS_WORSE: return VSS_WORSE; case VSS_TIE: for (int i=1; iselect(home,x)) { case VSS_BEST: case VSS_BETTER: for (int j=i+1; jinit(home,x); return VSS_BETTER; case VSS_TIE: break; case VSS_WORSE: return VSS_WORSE; default: GECODE_NEVER; } return VSS_TIE; default: GECODE_NEVER; return VSS_WORSE; } } template inline typename ViewSelTieBreakDynamic<_View>::Choice ViewSelTieBreakDynamic<_View>::choice(Space& home) { Choice c(home,tb,n); return c; } template inline typename ViewSelTieBreakDynamic<_View>::Choice ViewSelTieBreakDynamic<_View>::choice(const Space& home, Archive& e) { Choice c(home,e,tb,n); return c; } template forceinline void ViewSelTieBreakDynamic<_View>::commit (Space& home, const typename ViewSelTieBreakDynamic<_View>::Choice& c, unsigned int a) { c.commit(home,a,tb); } template forceinline void ViewSelTieBreakDynamic<_View>::update(Space& home, bool share, ViewSelTieBreakDynamic<_View>& vstb) { n = vstb.n; tb = home.alloc*>(n); for (int i=0; icopy(home,share); } template forceinline void ViewSelTieBreakDynamic<_View>::dispose(Space& home) { for (int i=0; idispose(home)); home.free*>(tb,n); } } // STATISTICS: kernel-branch