00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034 #ifdef GECODE_HAS_CBS
00035
00036 namespace Gecode { namespace Int { namespace Branch {
00037
00038 template<class View>
00039 forceinline void
00040 CBSBrancher<View>::VarIdToPos::init() {
00041 assert(object() == nullptr);
00042 object(new VarIdToPosO());
00043 }
00044
00045 template<class View>
00046 forceinline bool
00047 CBSBrancher<View>::VarIdToPos::isIn(unsigned int var_id) const {
00048 auto *hm = &static_cast<VarIdToPosO*>(object())->_varIdToPos;
00049 return hm->find(var_id) != hm->end();
00050 }
00051
00052 template<class View>
00053 forceinline int
00054 CBSBrancher<View>::VarIdToPos::operator[](unsigned int i) const {
00055 return static_cast<VarIdToPosO*>(object())->_varIdToPos.at(i);
00056 }
00057
00058 template<class View>
00059 forceinline void
00060 CBSBrancher<View>::VarIdToPos::insert(unsigned int var_id,
00061 unsigned int pos) {
00062 static_cast<VarIdToPosO*>(object())
00063 ->_varIdToPos.insert(std::make_pair(var_id, pos));
00064 }
00065
00066 template<class View>
00067 CBSBrancher<View>::CBSBrancher(Home home, ViewArray<View>& x0)
00068 : Brancher(home), x(x0),
00069 logProp(typename decltype(logProp)::size_type(),
00070 typename decltype(logProp)::hasher(),
00071 typename decltype(logProp)::key_equal(),
00072 typename decltype(logProp)::allocator_type(home)) {
00073 home.notice(*this, AP_DISPOSE);
00074 varIdToPos.init();
00075 for (int i=0; i<x.size(); i++)
00076 varIdToPos.insert(x[i].id(), i);
00077 }
00078
00079 template<class View>
00080 forceinline void
00081 CBSBrancher<View>::post(Home home, ViewArray<View>& x) {
00082 (void) new (home) CBSBrancher(home,x);
00083 }
00084
00085 template<class View>
00086 Actor* CBSBrancher<View>::copy(Space& home) {
00087 return new (home) CBSBrancher(home,*this);
00088 }
00089
00090 template<class View>
00091 forceinline size_t
00092 CBSBrancher<View>::dispose(Space& home) {
00093 home.ignore(*this, AP_DISPOSE);
00094 varIdToPos.~VarIdToPos();
00095 (void) Brancher::dispose(home);
00096 return sizeof(*this);
00097 }
00098
00099 template<class View>
00100 CBSBrancher<View>::CBSBrancher(Space& home, CBSBrancher& b)
00101 : Brancher(home,b),
00102 varIdToPos(b.varIdToPos),
00103 logProp(b.logProp.begin(), b.logProp.end(),
00104 typename decltype(logProp)::size_type(),
00105 typename decltype(logProp)::hasher(),
00106 typename decltype(logProp)::key_equal(),
00107 typename decltype(logProp)::allocator_type(home)) {
00108 x.update(home,b.x);
00109 }
00110
00111 template<class View>
00112 bool CBSBrancher<View>::status(const Space& home) const {
00113 for (Propagators p(home, PropagatorGroup::all); p(); ++p) {
00114
00115 unsigned int domsum;
00116
00117 unsigned int domsum_b;
00118
00119
00120
00121 p.propagator().domainsizesum([this](unsigned int var_id)
00122 { return inbrancher(var_id); },
00123 domsum, domsum_b);
00124
00125 if (domsum_b > 0)
00126 return true;
00127 }
00128
00129 return false;
00130 }
00131
00132 template<class View>
00133 forceinline bool
00134 CBSBrancher<View>::inbrancher(unsigned int varId) const {
00135 return varIdToPos.isIn(varId);
00136 }
00137
00138 template<class View>
00139 const Choice* CBSBrancher<View>::choice(Space& home) {
00140
00141 struct {
00142 unsigned int var_id;
00143 int val;
00144 double dens;
00145 } maxSD{0, 0, -1};
00146
00147
00148 auto SendMarginal = [this](unsigned int prop_id, unsigned int var_id,
00149 int val, double dens) {
00150 if (logProp[prop_id].dens < dens) {
00151 logProp[prop_id].var_id = var_id;
00152 logProp[prop_id].val = val;
00153 logProp[prop_id].dens = dens;
00154 }
00155 };
00156
00157 for (auto& kv : logProp)
00158 kv.second.visited = false;
00159
00160 for (Propagators p(home, PropagatorGroup::all); p(); ++p) {
00161 unsigned int prop_id = p.propagator().id();
00162 unsigned int domsum;
00163 unsigned int domsum_b;
00164
00165 p.propagator().domainsizesum([this](unsigned int var_id)
00166 { return inbrancher(var_id); },
00167 domsum, domsum_b);
00168
00169
00170
00171 if (domsum_b == 0)
00172 continue;
00173
00174
00175
00176 if (logProp.find(prop_id) == logProp.end())
00177 logProp.insert(std::make_pair(prop_id, PropInfo{0, 0, 0, -1, true}));
00178 else
00179 logProp[prop_id].visited = true;
00180
00181
00182
00183
00184 if (logProp[prop_id].domsum != domsum) {
00185 logProp[prop_id].dens = -1;
00186
00187 p.propagator().solndistrib(home, SendMarginal);
00188 logProp[prop_id].domsum = domsum;
00189 }
00190 }
00191
00192
00193
00194 for (const auto& kv : logProp) {
00195 unsigned int prop_id = kv.first;
00196 const PropInfo& info = kv.second;
00197 if (!info.visited)
00198 logProp.erase(prop_id);
00199 else if (info.dens > maxSD.dens)
00200 maxSD = {info.var_id, info.val, info.dens};
00201 }
00202
00203 assert(maxSD.dens != -1);
00204 assert(!x[varIdToPos[maxSD.var_id]].assigned());
00205 return new PosValChoice<int>(*this, 2, varIdToPos[maxSD.var_id], maxSD.val);
00206 }
00207
00208 template<class View>
00209 forceinline const Choice*
00210 CBSBrancher<View>::choice(const Space&, Archive& e) {
00211 int pos, val;
00212 e >> pos >> val;
00213 return new PosValChoice<int>(*this, 2, pos, val);
00214 }
00215
00216 template<class View>
00217 forceinline ExecStatus
00218 CBSBrancher<View>::commit(Space& home, const Choice& c, unsigned int a) {
00219 const auto& pvc = static_cast<const PosValChoice<int>&>(c);
00220 int pos = pvc.pos().pos;
00221 int val = pvc.val();
00222 if (a == 0)
00223 return me_failed(x[pos].eq(home, val)) ? ES_FAILED : ES_OK;
00224 else
00225 return me_failed(x[pos].nq(home, val)) ? ES_FAILED : ES_OK;
00226 }
00227
00228 template<class View>
00229 forceinline void
00230 CBSBrancher<View>::print(const Space&, const Choice& c, unsigned int a,
00231 std::ostream& o) const {
00232 const auto& pvc = static_cast<const PosValChoice<int>&>(c);
00233 int pos=pvc.pos().pos, val=pvc.val();
00234 if (a == 0)
00235 o << "x[" << pos << "] = " << val;
00236 else
00237 o << "x[" << pos << "] != " << val;
00238 }
00239
00240 }}}
00241
00242 #endif
00243
00244