00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include <gecode/kernel.hh>
00022
00023 namespace Gecode {
00024
00025 namespace Search {
00026
00027
00028
00029
00030
00031
00032 template<class View, class Val>
00033 void
00034 SymmBreaker<View,Val>::updateCps(Space *home, ViewArray<View> &x, int pos, Val val) {
00035
00036 BoolVarArray new_cps(home,cps.size(),0,1);
00037
00038 for (int i=0; i<cps.size(); i++) {
00039 BoolVar sc = reifySymm(home,symOf[i],x,pos,val);
00040 new_cps[i] = post(home, cps[i] && sc);
00041 }
00042 cps = new_cps;
00043 }
00044
00045 template<class View, class Val>
00046 void
00047 SymmBreaker<View,Val>::postImplications(Space *home, ViewArray<View> &x, int pos, Val val) const {
00048 for (int i=0; i<cps.size(); i++) {
00049 BoolVar sc = reifySymm(home,symOf[i],x,pos,val);
00050
00051
00052 BoolVar negSc(home,0,1);
00053 bool_not( home, sc, negSc);
00054 bool_imp( home, cps[i], negSc, true );
00055 }
00056 }
00057
00058 template<class View, class Val>
00059 void SymmBreaker<View,Val>::tell(Space *home, int a, ViewArray<View> &x, int pos, Val val) {
00060
00061 if (a==0) {
00062 tellSymm(home,0,x,pos,val);
00063 updateCps(home,x,pos,val);
00064 } else {
00065 postImplications(home,x,pos,val);
00066 }
00067 }
00068
00069 template<class View, class Val>
00070 void
00071 SymmBreaker<View,Val>::print(void) const {
00072 std::cout << "Cps: { ";
00073 for (int i = 0; i < cps.size(); i++) {
00074 std::cout << cps[i] << ", ";
00075 if ((i+1) % 15 == 0)
00076 std::cout << std::endl << "\t ";
00077 }
00078 std::cout << "};" << std::endl;
00079 }
00080
00081
00082
00083
00084
00085
00086
00087
00088 template <class View, class Val, class ViewSel, class ValSel, class SymmBreaker>
00089 forceinline
00090 SBViewValBranching<View,Val,ViewSel,ValSel,SymmBreaker>
00091 ::SBViewValBranching(Space* home, ViewArray<View>& x0)
00092 : ViewValBranching<View,Val,ViewSel,ValSel>(home,x0), symmetries(home) {
00093 }
00094
00095 template <class View, class Val, class ViewSel, class ValSel, class SymmBreaker>
00096 forceinline
00097 SBViewValBranching<View,Val,ViewSel,ValSel,SymmBreaker>
00098 ::SBViewValBranching(Space* home, ViewArray<View>& x0, SymmBreaker &sym)
00099 : ViewValBranching<View,Val,ViewSel,ValSel>(home,x0), symmetries(sym) {
00100 }
00101
00102
00103 template <class View, class Val, class ViewSel, class ValSel, class SymmBreaker>
00104 forceinline
00105 SBViewValBranching<View,Val,ViewSel,ValSel,SymmBreaker>
00106 ::SBViewValBranching(Space* home, bool share, SBViewValBranching& b)
00107 : ViewValBranching<View,Val,ViewSel,ValSel>(home,share,b),
00108 symmetries(home,share,b.symmetries)
00109 {
00110
00111 }
00112
00113 template <class View, class Val, class ViewSel, class ValSel, class SymmBreaker>
00114 Actor*
00115 SBViewValBranching<View,Val,ViewSel,ValSel,SymmBreaker>::copy(Space* home, bool share) {
00116 return new (home)
00117 SBViewValBranching<View,Val,ViewSel,ValSel,SymmBreaker>(home,share,*this);
00118 }
00119
00120 template <class View, class Val, class ViewSel, class ValSel, class SymmBreaker>
00121 bool
00122 SBViewValBranching<View,Val,ViewSel,ValSel,SymmBreaker>
00123 ::status(const Space *home) const {
00124
00125 if ( ! symmetries.status(home) ) return false;
00126
00127 return ViewValBranching<View,Val,ViewSel,ValSel>::status(home);
00128 }
00129
00130
00131 template <class View, class Val, class ViewSel, class ValSel, class SymmBreaker>
00132 ExecStatus
00133 SBViewValBranching<View,Val,ViewSel,ValSel,SymmBreaker>
00134 ::commit(Space* home, const BranchingDesc* d, unsigned int a) {
00135 const PosValDesc<Val>* pvd = static_cast<const PosValDesc<Val>*>(d);
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147 symmetries.tell(home,a,ViewValBranching<View,Val,ViewSel,ValSel>::x,pvd->pos(),pvd->val());
00148 return ES_OK;
00149 }
00150
00151
00152
00153
00154 }
00155
00156 }
00157
00158