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
00028 #include <coconut_config.h>
00029 #include <dag_delta.h>
00030 #include <api_debug.h>
00031
00032 namespace coco {
00033
00034 void dag_delta::help_apply_p(work_node& x, expression_walker& _x, model* nm) const
00035 {
00036 expression_walker _parent, _nonghost;
00037 unsigned int nn;
00038
00039 nn = _x->node_num;
00040 _nonghost = x.get_model_ptr()->node(nn);
00041 while(_x.n_parents() > 0)
00042 {
00043 _parent = _x << _x.parent_begin();
00044 if(_parent == nm->ground())
00045 return;
00046 if(_nonghost.is_root())
00047 x.get_model_ptr()->remove_edge_and_deattach(x.get_model_ptr()->ground(),
00048 _nonghost);
00049 nm->replace_edge_to_child(_parent, _x, _nonghost);
00050 _nonghost->n_parents++;
00051 }
00052 }
00053
00054 void dag_delta::help_apply_s(work_node& x, model* nm) const
00055 {
00056 expression_walker _w, _x(nm->sky());
00057 std::vector<expression_walker> __v;
00058
00059 while(_x.n_parents() > 0)
00060 {
00061 _w = _x << _x.parent_begin();
00062 if(_w == nm->ground())
00063 break;
00064 nm->remove_edge_and_deattach(_w, _x);
00065 __v.push_back(_w);
00066 }
00067 for(std::vector<expression_walker>::iterator __m = __v.begin(); __m != __v.end();
00068 ++__m)
00069 x.get_model_ptr()->add_edge_back(*__m, x.get_model_ptr()->sky());
00070 }
00071
00072 void dag_delta::help_apply_c(work_node& x, expression_walker& _x, model* nm) const
00073 {
00074 expression_walker _child, _nonghost;
00075 unsigned int nn;
00076
00077 nn = _x->node_num;
00078 _nonghost = x.get_model_ptr()->node(nn);
00079 while(_x.n_children() > 0)
00080 {
00081 _child = _x << _x.child_begin();
00082 if(_child == nm->sky())
00083 return;
00084 if(_nonghost.is_leaf())
00085 x.get_model_ptr()->remove_edge_and_deattach(_nonghost,
00086 x.get_model_ptr()->sky());
00087 nm->replace_edge_to_parent(_x, _nonghost, _child);
00088 _nonghost->n_children++;
00089 }
00090 }
00091
00092 void dag_delta::help_apply_g(work_node& x, model* nm) const
00093 {
00094 expression_walker _w, _x(nm->ground());
00095 std::vector<expression_walker> __v;
00096
00097 while(_x.n_children() > 0)
00098 {
00099 _w = _x >> _x.child_begin();
00100 if(_w == nm->sky())
00101 break;
00102 nm->remove_edge_and_deattach(_x, _w);
00103 __v.push_back(_w);
00104 }
00105 for(std::vector<expression_walker>::iterator __m = __v.begin(); __m != __v.end();
00106 ++__m)
00107 x.get_model_ptr()->add_edge_back(x.get_model_ptr()->ground(), *__m);
00108 }
00109
00110 bool dag_delta::apply(work_node& x, undelta_base*& u, const delta_id& _did) const
00111 {
00112 expression_walker _x;
00113 unsigned int nn;
00114
00115 if(is_full_delta)
00116 {
00117 if(!new_constraints.get() || new_constraints->empty()) return true;
00118
00119 model* nm = new model(*new_constraints);
00120 gptr<model>* old_model = x._m;
00121
00122 x._m = new ptr<model>(nm);
00123 x.make_node_ranges(false);
00124 x.make_node_order();
00125 x.init_cnumbers();
00126 u = (undelta_base*) new dag_undelta(old_model);
00127 return true;
00128 }
00129 else
00130 {
00131 dag_undelta *uu;
00132 model* xm = x.get_model_ptr();
00133 model* nm(NULL);
00134 u = (undelta_base*) (uu = new dag_undelta(false));
00135
00136 if(new_constraints.get() && !new_constraints->empty())
00137 {
00138 std::vector<unsigned int> addnod, addvar, addgh, addcnst;
00139 model::ref_iterator _xic, _xie;
00140
00141 nm = new model(xm->gid_data(), *new_constraints);
00142
00144 addnod.reserve(nm->node_ref.size());
00145 for(_xie = nm->node_ref.end(), _xic = nm->node_ref.begin(); _xic != _xie;
00146 ++_xic)
00147 addnod.push_back((*_xic)->node_num);
00148 addvar.reserve(nm->var_ref.size());
00149 for(_xie = nm->var_ref.end(), _xic = nm->var_ref.begin(); _xic != _xie;
00150 ++_xic)
00151 addvar.push_back((*_xic)->node_num);
00152 addgh.reserve(nm->ghost_ref.size());
00153 for(_xie = nm->ghost_ref.end(), _xic = nm->ghost_ref.begin(); _xic != _xie;
00154 ++_xic)
00155 addgh.push_back((*_xic)->node_num);
00156 addcnst.reserve(nm->constraints.size());
00157 for(_xie = nm->constraints.end(), _xic = nm->constraints.begin(); _xic != _xie;
00158 ++_xic)
00159 addcnst.push_back((*_xic)->node_num);
00160 #if __DEBUG_DAG_DELTA
00161 std::cout << "After model-copy: start" << std::endl;
00162 nm->write();
00163 std::cout << "After model-copy: end" << std::endl;
00164 #endif
00165
00166
00167
00168
00169 for(model::ref_iterator __x = nm->ghost_begin();
00170 __x != nm->ghost_end(); ++__x)
00171 {
00172 _x = *__x;
00173
00174 if(!_x->f_bounds.is_entire())
00175 {
00176 uu->bounds_chgd[_x->node_num] = xm->node(_x->node_num)->f_bounds;
00177 xm->node(_x->node_num)->f_bounds.intersectwith(_x->f_bounds);
00178 }
00179 help_apply_p(x, _x, nm);
00180 help_apply_c(x, _x, nm);
00181 }
00182 #if __DEBUG_DAG_DELTA
00183 std::cout << "Removing GHOSTS!" << std::endl;
00184 #endif
00185
00186 for(model::ref_iterator __x = nm->ghost_begin();
00187 __x != nm->ghost_end(); __x = nm->ghost_begin())
00188 {
00189 #if __DEBUG_DAG_DELTA
00190 std::cout << "Removing GHOST " << (*__x)->node_num;
00191 #endif
00192 nm->remove_node(*__x);
00193 #if __DEBUG_DAG_DELTA
00194 std::cout << " : " << nm->ground().n_children() << std::endl;
00195 #endif
00196 }
00197
00198 help_apply_s(x, nm);
00199 help_apply_g(x, nm);
00200
00201 x.reset_node_ranges();
00202
00203 uu->added_nodes.reserve(addnod.size());
00204 for(std::vector<unsigned int>::iterator _xit = addnod.begin();
00205 _xit != addnod.end(); ++_xit)
00206 uu->added_nodes.push_back(xm->node(*_xit));
00207 uu->added_constraints.reserve(addcnst.size());
00208 for(std::vector<unsigned int>::iterator _xit = addcnst.begin();
00209 _xit != addcnst.end(); ++_xit)
00210 uu->added_constraints.push_back(xm->node(*_xit));
00211 std::sort(uu->added_constraints.begin(), uu->added_constraints.end(),
00212 model::__docompare_nodes());
00213 #if 0
00214 uu->added_ghosts.reserve(addgh.size());
00215 for(std::vector<unsigned int>::iterator _xit = addgh.begin();
00216 _xit != addgh.end(); ++_xit)
00217 uu->added_ghosts.push_back(xm->ghost(*_xit));
00218 #else
00219 uu->added_ghosts.clear();
00220 #endif
00221 uu->added_vars.reserve(addvar.size());
00222 for(std::vector<unsigned int>::iterator _xit = addvar.begin();
00223 _xit != addvar.end(); ++_xit)
00224 uu->added_vars.push_back(xm->node(*_xit));
00225
00226
00227 std::vector<expression_walker>& nr(xm->node_ref);
00228 nn = nr.size();
00229 nr.insert(nr.end(), nm->node_ref.begin(), nm->node_ref.end());
00230 inplace_merge(nr.begin(), nr.begin()+nn, nr.end(),
00231 model::__docompare_nodes());
00232
00233
00234 std::vector<expression_walker>& vr(xm->var_ref);
00235 nn = vr.size();
00236 vr.insert(vr.end(), nm->var_ref.begin(), nm->var_ref.end());
00237 inplace_merge(vr.begin(), vr.begin()+nn, vr.end(),
00238 model::__docompare_variables());
00239
00240
00241 std::vector<expression_walker>& gr(xm->ghost_ref);
00242 nn = gr.size();
00243 gr.insert(gr.end(), nm->ghost_ref.begin(), nm->ghost_ref.end());
00244 inplace_merge(gr.begin(), gr.begin()+nn, gr.end(),
00245 model::__docompare_nodes());
00246
00247 xm->constraints.insert(xm->constraints.end(), nm->constraints.begin(),
00248 nm->constraints.end());
00249
00250
00251
00252
00253
00254
00255
00256 }
00257
00258 if(!rm_nodes.empty())
00259 {
00260 model::erased_part me = xm->erase_minimal_subgraph(rm_nodes);
00261 uu->rm_dag = new model(xm->gid_data(), me);
00262 uu->rm_e = me.second;
00263
00264
00265 std::vector<walker> _nn;
00266 std::swap(_nn, xm->node_ref);
00267 std::set_difference(_nn.begin(), _nn.end(), uu->rm_dag->node_ref.begin(),
00268 uu->rm_dag->node_ref.end(),
00269 back_inserter(xm->node_ref),
00270 model::__docompare_nodes());
00271
00272 _nn.erase(_nn.begin(), _nn.end());
00273 std::swap(_nn, xm->var_ref);
00274 std::set_difference(_nn.begin(), _nn.end(), uu->rm_dag->var_ref.begin(),
00275 uu->rm_dag->var_ref.end(), back_inserter(xm->var_ref),
00276 model::__docompare_variables());
00277
00278 _nn.erase(_nn.begin(), _nn.end());
00279 std::swap(_nn, xm->ghost_ref);
00280 std::set_difference(_nn.begin(), _nn.end(), uu->rm_dag->ghost_ref.begin(),
00281 uu->rm_dag->ghost_ref.end(),
00282 back_inserter(xm->ghost_ref),
00283 model::__docompare_nodes());
00284
00285
00286 std::vector<walker>::iterator _i =
00287 std::stable_partition(xm->constraints.begin(), xm->constraints.end(),
00288 __check_nodes(uu->rm_dag->node_ref));
00289 std::copy(_i, xm->constraints.end(), uu->rm_dag->constraints.end());
00290 xm->constraints.erase(_i, xm->constraints.end());
00291
00292
00293
00294
00295
00296
00297
00298
00299 x.reset_node_ranges();
00300 }
00301 else if(nm)
00302 uu->rm_dag = new model(xm->gid_data());
00303
00304 if(nm)
00305 {
00306 uu->rm_dag->objective = xm->objective;
00307 if(!nm->is_empty(nm->objective))
00308 xm->objective = nm->objective;
00309
00310 uu->rm_dag->ocoeff = xm->ocoeff;
00311 if(nm->ocoeff != MAXINT)
00312 xm->ocoeff = nm->ocoeff;
00313 }
00314
00315 x.make_node_ranges(true);
00316 x.make_node_order();
00317 x.init_cnumbers();
00318 if(nm)
00319 {
00320 nm->add_edge_back(nm->ground(),nm->sky());
00321 delete nm;
00322 }
00323 return true;
00324 }
00325 }
00326
00327 bool dag_undelta::unapply(work_node& x, const delta_id& _did) const
00328 {
00329 if(is_full_undelta)
00330 {
00331 x._m = old_model;
00332 x.make_node_ranges(false);
00333 x.make_node_order();
00334 x.init_cnumbers();
00335 return true;
00336 }
00337 else
00338 {
00339 model* xm = x.get_model_ptr();
00340
00341
00342 std::vector<model::enhanced_edge>::const_iterator eei, eee(rm_e.end());
00343
00344
00345 for(eei = rm_e.begin(); eei != eee; ++eei)
00346 {
00347 if((*eei).second)
00348 {
00349 if((*eei).first.second.is_root())
00350 xm->remove_edge(xm->ground(), (*eei).first.second);
00351 if((*eei).first.first.is_leaf())
00352 xm->remove_edge((*eei).first.first, xm->sky());
00353 }
00354 xm->add_edge_back((*eei).first.first, (*eei).first.second);
00355 }
00356
00357 if(rm_dag.get() && !rm_dag->empty())
00358 {
00359 expression_walker _sg(rm_dag->sky());
00360 for(model::parents_iterator _w = _sg.parent_begin();
00361 _w != _sg.parent_end(); ++_w)
00362 rm_dag->remove_edge_and_deattach(_sg << _w, _sg);
00363 _sg = rm_dag->ground();
00364 for(model::children_iterator _w = _sg.child_begin();
00365 _w != _sg.child_end(); ++_w)
00366 rm_dag->remove_edge_and_deattach(_sg, _sg >> _w);
00367 rm_dag->add_edge_back(rm_dag->ground(), rm_dag->sky());
00368 }
00369
00370
00371 std::vector<expression_walker>::const_iterator __x, __e;
00372 for(__x = added_nodes.begin(), __e = added_nodes.end(); __x != __e; ++__x)
00373 xm->gid_data()->mk_globref((*__x)->node_num, xm->empty_reference());
00374 for(__x = added_vars.begin(), __e = added_vars.end(); __x != __e; ++__x)
00375 xm->gid_data()->mk_gvarref((*__x)->params.nn(), xm->empty_reference());
00376 unsigned int const_num;
00377 for(__x = added_constraints.begin(), __e = added_constraints.end();
00378 __x != __e; ++__x)
00379 {
00380 bool ok = xm->gid_data()->get_const_num((*__x)->node_num, const_num);
00381 if(ok)
00382 xm->gid_data()->remove_const_ref(const_num);
00383 }
00384
00385
00386 model::erased_part me(xm->erase_minimal_subgraph(added_nodes));
00387
00388 if(!added_nodes.empty())
00389 {
00390
00391 std::vector<walker> _nn;
00392 std::swap(_nn, xm->node_ref);
00393 std::set_difference(_nn.begin(), _nn.end(), added_nodes.begin(),
00394 added_nodes.end(), back_inserter(xm->node_ref),
00395 model::__docompare_nodes());
00396 }
00397
00398 std::vector<expression_walker> _nn;
00399 if(!added_vars.empty())
00400 {
00401 _nn.erase(_nn.begin(), _nn.end());
00402 std::swap(_nn, xm->var_ref);
00403 std::set_difference(_nn.begin(), _nn.end(), added_vars.begin(),
00404 added_vars.end(), back_inserter(xm->var_ref),
00405 model::__docompare_variables());
00406 }
00407
00408 if(!added_ghosts.empty())
00409 {
00410 _nn.erase(_nn.begin(), _nn.end());
00411 std::swap(_nn, xm->ghost_ref);
00412 std::set_difference(_nn.begin(), _nn.end(), added_ghosts.begin(),
00413 added_ghosts.end(), back_inserter(xm->ghost_ref),
00414 model::__docompare_nodes());
00415 }
00416
00417 if(!added_constraints.empty())
00418 {
00419
00420 std::vector<walker>::iterator _i =
00421 std::stable_partition(xm->constraints.begin(), xm->constraints.end(),
00422 __check_walkers(added_constraints));
00423 xm->constraints.erase(_i, xm->constraints.end());
00424 }
00425
00426 xm->clear_erased_part(me);
00427
00428
00429 for(std::map<unsigned int, interval>::const_iterator __b =
00430 bounds_chgd.begin(); __b != bounds_chgd.end(); ++__b)
00431 xm->node(__b->first)->f_bounds = __b->second;
00432
00433 x.get_model()->set_counters();
00434 x.make_node_order();
00435
00436 return true;
00437 }
00438 }
00439
00440 }