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

ldsb.cpp

Go to the documentation of this file.
00001 /* -*- mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- */
00002 /*
00003  *  Main authors:
00004  *     Christopher Mears <chris.mears@monash.edu>
00005  *
00006  *  Copyright:
00007  *     Christopher Mears, 2012
00008  *
00009  *  Last modified:
00010  *     $Date: 2013-05-15 20:32:39 +0200 (Wed, 15 May 2013) $ by $Author: schulte $
00011  *     $Revision: 13639 $
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 #include <gecode/set/ldsb.hh>
00039 #include <gecode/set/branch.hh>
00040 #include <map>
00041 
00042 namespace Gecode {
00043   using namespace Int::LDSB;
00044   /*
00045    * Implementation of some SymmetryHandle methods.
00046    */
00047   
00048   SymmetryHandle VariableSymmetry(const SetVarArgs& x) {
00049     ArgArray<VarImpBase*> a(x.size());
00050     for (int i = 0 ; i < x.size() ; i++)
00051       a[i] = x[i].varimp();
00052     return SymmetryHandle(new VariableSymmetryObject(a));
00053   }
00054   SymmetryHandle VariableSequenceSymmetry(const SetVarArgs& x, int ss) {
00055     ArgArray<VarImpBase*> a(x.size());
00056     for (int i = 0 ; i < x.size() ; i++)
00057       a[i] = x[i].varimp();
00058     return SymmetryHandle(new VariableSequenceSymmetryObject(a, ss));
00059   }
00060 }
00061 
00062 namespace Gecode { namespace Int { namespace LDSB {
00063   template <>
00064   ModEvent prune<Set::SetView>(Space& home, Set::SetView x, int v) {
00065     return x.exclude(home, v);
00066   }
00067 }}}
00068 
00069 namespace Gecode { namespace Set { namespace LDSB {
00070 
00072   class VariableMap : public std::map<VarImpBase*,int> {};
00073 
00074   /*
00075    * The createSetSym function is an almost exact copy of
00076    * createIntSym/createBoolSym.
00077    */
00078   SymmetryImp<SetView>* createSetSym(Space& home, const SymmetryHandle& s,
00079                                      VariableMap variableMap) {
00080     VariableSymmetryObject* varref    = 
00081       dynamic_cast<VariableSymmetryObject*>(s.ref);
00082     ValueSymmetryObject* valref    = 
00083       dynamic_cast<ValueSymmetryObject*>(s.ref);
00084     VariableSequenceSymmetryObject* varseqref = 
00085       dynamic_cast<VariableSequenceSymmetryObject*>(s.ref);
00086     ValueSequenceSymmetryObject* valseqref = 
00087       dynamic_cast<ValueSequenceSymmetryObject*>(s.ref);
00088     if (varref) {
00089       int n = varref->nxs;
00090       int* indices = home.alloc<int>(n);
00091       for (int i = 0 ; i < n ; i++) {
00092         VariableMap::const_iterator index = variableMap.find(varref->xs[i]);
00093         if (index == variableMap.end())
00094           throw 
00095             Int::LDSBUnbranchedVariable("VariableSymmetryObject::createSet");
00096         indices[i] = index->second;
00097       }
00098       return new (home) VariableSymmetryImp<SetView>(home, indices, n);
00099     }
00100     if (valref) {
00101       int n = valref->values.size();
00102       int *vs = home.alloc<int>(n);
00103       int i = 0;
00104       for (IntSetValues v(valref->values) ; v() ; ++v) {
00105         vs[i] = v.val();
00106         i++;
00107       }
00108       return new (home) ValueSymmetryImp<SetView>(home, vs, n);
00109     }
00110     if (varseqref) {
00111       int n = varseqref->nxs;
00112       int* indices = home.alloc<int>(n);
00113       for (int i = 0 ; i < n ; i++) {
00114         VariableMap::const_iterator index = 
00115           variableMap.find(varseqref->xs[i]);
00116         if (index == variableMap.end())
00117           throw 
00118        Int::LDSBUnbranchedVariable("VariableSequenceSymmetryObject::createSet");
00119         indices[i] = index->second;
00120       }
00121       return new (home) VariableSequenceSymmetryImp<SetView>(home, indices, n, 
00122         varseqref->seq_size);
00123     }
00124     if (valseqref) {
00125       unsigned int n = valseqref->values.size();
00126       int *vs = home.alloc<int>(n);
00127       for (unsigned int i = 0 ; i < n ; i++)
00128         vs[i] = valseqref->values[i];
00129       return new (home) ValueSequenceSymmetryImp<SetView>(home, vs, n, 
00130         valseqref->seq_size);
00131     }
00132     GECODE_NEVER;
00133     return NULL;
00134   }
00135 }}}
00136 
00137 namespace Gecode {
00138 
00139   using namespace Set::LDSB;
00140 
00141   BrancherHandle
00142   branch(Home home, const SetVarArgs& x,
00143          SetVarBranch vars, SetValBranch vals,
00144          const Symmetries& syms,
00145          SetBranchFilter bf, SetVarValPrint vvp) {
00146     using namespace Set;
00147     if (home.failed()) return BrancherHandle();
00148     vars.expand(home,x);
00149     ViewArray<SetView> xv(home,x);
00150     ViewSel<SetView>* vs[1] = { 
00151       Branch::viewsel(home,vars) 
00152     };
00153 
00154     // Construct mapping from each variable in the array to its index
00155     // in the array.
00156     VariableMap variableMap;
00157     for (int i = 0 ; i < x.size() ; i++)
00158       variableMap[x[i].varimp()] = i;
00159     
00160     // Convert the modelling-level Symmetries object into an array of
00161     // SymmetryImp objects.
00162     int n = syms.size();
00163     SymmetryImp<SetView>** array = 
00164       static_cast<Space&>(home).alloc<SymmetryImp<SetView>* >(n);
00165     for (int i = 0 ; i < n ; i++) {
00166       array[i] = createSetSym(home, syms[i], variableMap);
00167     }
00168 
00169     return LDSBSetBrancher<SetView,1,int,2>::post
00170       (home,xv,vs,Branch::valselcommit(home,vals),array,n,bf,vvp);
00171   }
00172 
00173   BrancherHandle
00174   branch(Home home, const SetVarArgs& x,
00175          TieBreak<SetVarBranch> vars, SetValBranch vals,
00176          const Symmetries& syms, 
00177          SetBranchFilter bf, SetVarValPrint vvp) {
00178     using namespace Set;
00179     if (home.failed()) return BrancherHandle();
00180     vars.a.expand(home,x);
00181     if ((vars.a.select() == SetVarBranch::SEL_NONE) ||
00182         (vars.a.select() == SetVarBranch::SEL_RND))
00183       vars.b = SET_VAR_NONE();
00184     vars.b.expand(home,x);
00185     if ((vars.b.select() == SetVarBranch::SEL_NONE) ||
00186         (vars.b.select() == SetVarBranch::SEL_RND))
00187       vars.c = SET_VAR_NONE();
00188     vars.c.expand(home,x);
00189     if ((vars.c.select() == SetVarBranch::SEL_NONE) ||
00190         (vars.c.select() == SetVarBranch::SEL_RND))
00191       vars.d = SET_VAR_NONE();
00192     vars.d.expand(home,x);
00193     if (vars.b.select() == SetVarBranch::SEL_NONE) {
00194       return branch(home,x,vars.a,vals,syms,bf,vvp);
00195     } else {
00196       // Construct mapping from each variable in the array to its index
00197       // in the array.
00198       VariableMap variableMap;
00199       for (int i = 0 ; i < x.size() ; i++)
00200         variableMap[x[i].varimp()] = i;
00201       
00202       // Convert the modelling-level Symmetries object into an array of
00203       // SymmetryImp objects.
00204       int n = syms.size();
00205       SymmetryImp<SetView>** array =
00206         static_cast<Space&>(home).alloc<SymmetryImp<SetView>* >(n);
00207       for (int i = 0 ; i < n ; i++) {
00208         array[i] = Set::LDSB::createSetSym(home, syms[i], variableMap);
00209       }
00210 
00211       ViewArray<SetView> xv(home,x);
00212       ValSelCommitBase<SetView,int>* vsc = Branch::valselcommit(home,vals); 
00213       if (vars.c.select() == SetVarBranch::SEL_NONE) {
00214         ViewSel<SetView>* vs[2] = { 
00215           Branch::viewsel(home,vars.a),Branch::viewsel(home,vars.b)
00216         };
00217         return 
00218           LDSBSetBrancher<SetView,2,int,2>::post(home,xv,vs,vsc,array,n,bf,vvp);
00219       } else if (vars.d.select() == SetVarBranch::SEL_NONE) {
00220         ViewSel<SetView>* vs[3] = { 
00221           Branch::viewsel(home,vars.a),Branch::viewsel(home,vars.b),
00222           Branch::viewsel(home,vars.c)
00223         };
00224         return 
00225           LDSBSetBrancher<SetView,3,int,2>::post(home,xv,vs,vsc,array,n,bf,vvp);
00226       } else {
00227         ViewSel<SetView>* vs[4] = { 
00228           Branch::viewsel(home,vars.a),Branch::viewsel(home,vars.b),
00229           Branch::viewsel(home,vars.c),Branch::viewsel(home,vars.d)
00230         };
00231         return 
00232           LDSBSetBrancher<SetView,4,int,2>::post(home,xv,vs,vsc,array,n,bf,vvp);
00233       }
00234     }
00235   }
00236 
00237 }
00238 
00239 // STATISTICS: set-branch