On Thu, Oct 9, 2008 at 8:05 AM, Mikael Zayenz Lagerkvist <[EMAIL PROTECTED]> wrote: > I tried it (code below), and it works just as you wanted.
Hi again, Christian pointed out to me that I had a small problem in my posted code - if the member-function called gave a failure, then things could go bad. Thus I've modified the code (see below) so that the member-function returns an ExecStatus that the MemberFunctionBranching can return. Cheers, Mikael <code> /* -*- mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- */ /* * Main authors: * Mikael Lagerkvist <[EMAIL PROTECTED]> * * Copyright: * Mikael Lagerkvist, 2008 * * Last modified: * $Date: 2008-10-09 07:48:15 +0200 (Wed, 09 Oct 2008) $ by $Author: zayenz $ * $Revision: 7912 $ * * 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. * */ #include "examples/support.hh" #include <gecode/minimodel.hh> /** \brief Branching for calling a space member function. */ template <class Model> class MemberFunctionBranch : Branching { public: /// Type of the member-function to call typedef ExecStatus (Model::*MemberFunction)(); private: /// Member function to call MemberFunction mf; /// Call member function just once bool done; /// Minimal branching description storing no information struct Description : public BranchingDesc { /// Initialize description for branching \a b, number of alternatives \a a. Description(const Branching* b, unsigned int a) : BranchingDesc(b,a) {} /// Report size occupied virtual size_t size(void) const { return sizeof(Description); } }; /// Construct branching MemberFunctionBranch(Space* home, MemberFunction mf0) : Branching(home), mf(mf0), done(false) {} /// Copy constructor MemberFunctionBranch(Space* home, bool share, MemberFunctionBranch<Model>& b) : Branching(home, share, b), mf(b.mf), done(b.done) {} public: /// Check status of branching, return true if alternatives left. virtual bool status(const Space*) const { return !done; } /// Return branching description virtual BranchingDesc* description(const Space*) const { assert(!done); return new Description(this, 1); } /// Perform commit virtual ExecStatus commit(Space* home, const BranchingDesc*, unsigned int) { done = true; Model* model = static_cast<Model*>(home); return (model->*mf)(); } /// Copy branching virtual Actor* copy(Space* home, bool share) { return new (home) MemberFunctionBranch(home, share, *this); } /// Reflection name virtual const char* name(void) const { return "MemberFunctionBranch"; } /// Post branching static void post(Space* home, MemberFunction mf) { (void) new (home) MemberFunctionBranch<Model>(home,mf); } }; /** * \brief %Example: n-%Queens puzzle with member function branchings * * \ingroup ExProblem */ class QueensMF : public Example { protected: /// Position of queens on boards IntVarArray q; public: ExecStatus addbranch(void) { branch(this, q, INT_VAR_SIZE_MIN, INT_VAL_MIN); MemberFunctionBranch<QueensMF>::post(this, &QueensMF::addprop); return failed() ? ES_FAILED : ES_OK; } ExecStatus addprop(void) { const int n = q.size(); for (int i = 0; i<n; i++) for (int j = i+1; j<n; j++) { post(this, q[i] != q[j]); post(this, q[i]+i != q[j]+j); post(this, q[i]-i != q[j]-j); } return failed() ? ES_FAILED : ES_OK; } /// The actual problem QueensMF(const SizeOptions& opt) : q(this,opt.size(),0,opt.size()-1) { MemberFunctionBranch<QueensMF>::post(this, &QueensMF::addbranch); } /// Constructor for cloning \a s QueensMF(bool share, QueensMF& s) : Example(share,s) { q.update(this, share, s.q); } /// Perform copying during cloning virtual Space* copy(bool share) { return new QueensMF(share,*this); } /// Print solution virtual void print(std::ostream& os) { os << "\t"; for (int i = 0; i < q.size(); i++) { os << q[i] << ", "; if ((i+1) % 10 == 0) os << std::endl << "\t"; } os << std::endl; } /// Make variables available for visualisation virtual void getVars(Gecode::Reflection::VarMap& vm, bool registerOnly) { vm.putArray(this,q,"q", registerOnly); } }; /** \brief Main-function * \relates QueensMF */ int main(int argc, char* argv[]) { SizeOptions opt("QueensMF"); opt.iterations(500); opt.size(6); opt.parse(argc,argv); Example::run<QueensMF,DFS,SizeOptions>(opt); return 0; } // STATISTICS: example-any </code> -- Mikael Zayenz Lagerkvist, http://www.ict.kth.se/~zayenz/ _______________________________________________ Gecode users mailing list [EMAIL PROTECTED] https://www.gecode.org/mailman/listinfo/gecode-users