00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00027 #include <dag_delta.h>
00028
00029 void dag_delta::help_apply_p(work_node& x, model::walker& _x, model* nm) const
00030 {
00031 model::walker _w;
00032 unsigned int nn;
00033 std::vector<model::walker> __v;
00034
00035 nn = _x->node_num;
00036 while(_x.n_parents() > 0)
00037 {
00038 _w = _x << _x.parent_begin();
00039 if(_w == nm->ground())
00040 return;
00041 nm->remove_edge_and_deattach(_w, _x);
00042 __v.push_back(_w);
00043 }
00044 _w = x.get_model_ptr()->node(nn);
00045 for(std::vector<model::walker>::iterator __m = __v.begin(); __m != __v.end();
00046 ++__m)
00047 x.get_model_ptr()->add_edge_back(*__m, _w);
00048 }
00049
00050 void dag_delta::help_apply_s(work_node& x, model* nm) const
00051 {
00052 model::walker _w, _x(nm->sky());
00053 std::vector<model::walker> __v;
00054
00055 while(_x.n_parents() > 0)
00056 {
00057 _w = _x << _x.parent_begin();
00058 if(_w == nm->ground())
00059 return;
00060 nm->remove_edge_and_deattach(_w, _x);
00061 __v.push_back(_w);
00062 }
00063 for(std::vector<model::walker>::iterator __m = __v.begin(); __m != __v.end();
00064 ++__m)
00065 x.get_model_ptr()->add_edge_back(*__m, x.get_model_ptr()->sky());
00066 }
00067
00068 void dag_delta::help_apply_c(work_node& x, model::walker& _x, model* nm) const
00069 {
00070 model::walker _w;
00071 unsigned int nn;
00072 std::vector<model::walker> __v;
00073
00074 nn = _x->node_num;
00075 while(_x.n_children() > 0)
00076 {
00077 _w = _x << _x.child_begin();
00078 if(_w == nm->sky())
00079 return;
00080 nm->remove_edge_and_deattach(_x, _w);
00081 __v.push_back(_w);
00082 }
00083 _w = x.get_model_ptr()->node(nn);
00084 for(std::vector<model::walker>::iterator __m = __v.begin(); __m != __v.end();
00085 ++__m)
00086 x.get_model_ptr()->add_edge_back(_w, *__m);
00087 }
00088
00089 void dag_delta::help_apply_g(work_node& x, model* nm) const
00090 {
00091 model::walker _w, _x(nm->ground());
00092 std::vector<model::walker> __v;
00093
00094 while(_x.n_children() > 0)
00095 {
00096 if(_w == nm->sky())
00097 return;
00098 _w = _x >> _x.child_begin();
00099 nm->remove_edge_and_deattach(_x, _w);
00100 __v.push_back(_w);
00101 }
00102 for(std::vector<model::walker>::iterator __m = __v.begin(); __m != __v.end();
00103 ++__m)
00104 x.get_model_ptr()->add_edge_back(x.get_model_ptr()->ground(), *__m);
00105 }
00106
00107 bool dag_delta::apply(work_node& x, undelta_base*& u) const
00108 {
00109 model::walker _x;
00110 unsigned int nn;
00111
00112 if(is_full_delta)
00113 {
00114 if(!new_constraints.get() || new_constraints->empty()) return true;
00115
00116 model* nm = new model(*new_constraints);
00117 gptr<model>* old_model = x._m;
00118
00119 x._m = new ptr<model>(nm);
00120 x.make_node_ranges(false);
00121 x.init_cnumbers();
00122 u = (undelta_base*) new dag_undelta(old_model);
00123 return true;
00124 }
00125 else
00126 {
00127 dag_undelta *uu;
00128 model* xm = x.get_model_ptr();
00129 model* nm(NULL);
00130 u = (undelta_base*) (uu = new dag_undelta(false));
00131
00132 if(new_constraints.get() && !new_constraints->empty())
00133 {
00134 nm = new model(xm->gid_data(), *new_constraints);
00135
00136
00137
00138
00139 for(model::ref_iterator __x = nm->ghost_begin();
00140 __x != nm->ghost_end(); ++__x)
00141 {
00142 _x = *__x;
00143
00144 if(!_x->f_bounds.is_entire())
00145 {
00146 uu->bounds_chgd[_x->node_num] = xm->node(_x->node_num)->f_bounds;
00147 xm->node(_x->node_num)->f_bounds.intersect(_x->f_bounds);
00148 }
00149 help_apply_p(x, _x, nm);
00150 help_apply_c(x, _x, nm);
00151 }
00152 help_apply_s(x, nm);
00153 help_apply_g(x, nm);
00154
00155 x.reset_node_ranges();
00156
00157 uu->added_nodes = nm->node_ref;
00158 uu->added_constraints = nm->constraints;
00159 std::sort(uu->added_constraints.begin(), uu->added_constraints.end(),
00160 model::__docompare_nodes());
00161 uu->added_ghosts = nm->ghost_ref;
00162 uu->added_vars = nm->var_ref;
00163
00164
00165 std::vector<model::walker>& nr(xm->node_ref);
00166 nn = nr.size();
00167 nr.insert(nr.end(), nm->node_ref.begin(), nm->node_ref.end());
00168 inplace_merge(nr.begin(), nr.begin()+nn, nr.end(),
00169 model::__docompare_nodes());
00170
00171
00172 std::vector<model::walker>& vr(xm->var_ref);
00173 nn = vr.size();
00174 vr.insert(vr.end(), nm->var_ref.begin(), nm->var_ref.end());
00175 inplace_merge(vr.begin(), vr.begin()+nn, vr.end(),
00176 model::__docompare_variables());
00177
00178
00179 std::vector<model::walker>& gr(xm->ghost_ref);
00180 nn = gr.size();
00181 gr.insert(gr.end(), nm->ghost_ref.begin(), nm->ghost_ref.end());
00182 inplace_merge(gr.begin(), gr.begin()+nn, gr.end(),
00183 model::__docompare_nodes());
00184
00185 xm->constraints.insert(xm->constraints.end(), nm->constraints.begin(),
00186 nm->constraints.end());
00187
00188
00189
00190
00191
00192
00193
00194 }
00195
00196 if(!rm_nodes.empty())
00197 {
00198 model::erased_part me = xm->erase_minimal_subgraph(rm_nodes);
00199 uu->rm_dag = new model(xm->gid_data(), me);
00200 uu->rm_e = me.second;
00201
00202
00203 std::vector<walker> _nn;
00204 std::swap(_nn, xm->node_ref);
00205 std::set_difference(_nn.begin(), _nn.end(), uu->rm_dag->node_ref.begin(),
00206 uu->rm_dag->node_ref.end(),
00207 back_inserter(xm->node_ref),
00208 model::__docompare_nodes());
00209
00210 _nn.erase(_nn.begin(), _nn.end());
00211 std::swap(_nn, xm->var_ref);
00212 std::set_difference(_nn.begin(), _nn.end(), uu->rm_dag->var_ref.begin(),
00213 uu->rm_dag->var_ref.end(), back_inserter(xm->var_ref),
00214 model::__docompare_variables());
00215
00216 _nn.erase(_nn.begin(), _nn.end());
00217 std::swap(_nn, xm->ghost_ref);
00218 std::set_difference(_nn.begin(), _nn.end(), uu->rm_dag->ghost_ref.begin(),
00219 uu->rm_dag->ghost_ref.end(),
00220 back_inserter(xm->ghost_ref),
00221 model::__docompare_nodes());
00222
00223
00224 std::vector<walker>::iterator _i =
00225 std::stable_partition(xm->constraints.begin(), xm->constraints.end(),
00226 __check_nodes(uu->rm_dag->node_ref));
00227 std::copy(_i, xm->constraints.end(), uu->rm_dag->constraints.end());
00228 xm->constraints.erase(_i, xm->constraints.end());
00229
00230
00231
00232
00233
00234
00235
00236
00237 x.reset_node_ranges();
00238 }
00239 else if(nm)
00240 uu->rm_dag = new model(xm->gid_data());
00241
00242 if(nm)
00243 {
00244 uu->rm_dag->objective = xm->objective;
00245 if(!nm->is_empty(nm->objective))
00246 xm->objective = nm->objective;
00247
00248 uu->rm_dag->ocoeff = xm->ocoeff;
00249 if(nm->ocoeff != MAXINT)
00250 xm->ocoeff = nm->ocoeff;
00251 }
00252
00253 x.make_node_ranges(true);
00254 x.init_cnumbers();
00255 return true;
00256 }
00257 }
00258
00259 bool dag_undelta::unapply(work_node& x) const
00260 {
00261 if(is_full_undelta)
00262 {
00263 x._m = old_model;
00264 x.make_node_ranges(false);
00265 x.init_cnumbers();
00266 return true;
00267 }
00268 else
00269 {
00270 model* xm = x.get_model_ptr();
00271
00272
00273 std::vector<model::enhanced_edge>::const_iterator eei, eee(rm_e.end());
00274
00275
00276 for(eei = rm_e.begin(); eei != eee; ++eei)
00277 {
00278 if((*eei).second)
00279 {
00280 if((*eei).first.second.is_root())
00281 xm->remove_edge(xm->ground(), (*eei).first.second);
00282 if((*eei).first.first.is_leaf())
00283 xm->remove_edge((*eei).first.first, xm->sky());
00284 }
00285 xm->add_edge_back((*eei).first.first, (*eei).first.second);
00286 }
00287
00288 if(rm_dag.get() && !rm_dag->empty())
00289 {
00290 model::walker _sg(rm_dag->sky());
00291 for(model::parents_iterator _w = _sg.parent_begin();
00292 _w != _sg.parent_end(); ++_w)
00293 rm_dag->remove_edge_and_deattach(_sg << _w, _sg);
00294 _sg = rm_dag->ground();
00295 for(model::children_iterator _w = _sg.child_begin();
00296 _w != _sg.child_end(); ++_w)
00297 rm_dag->remove_edge_and_deattach(_sg, _sg >> _w);
00298 rm_dag->add_edge_back(rm_dag->ground(), rm_dag->sky());
00299 }
00300
00301
00302 std::vector<model::walker>::const_iterator __x, __e;
00303 for(__x = added_nodes.begin(), __e = added_nodes.end(); __x != __e; ++__x)
00304 xm->gid_data()->mk_globref((*__x)->node_num, xm->empty_reference());
00305 for(__x = added_vars.begin(), __e = added_vars.end(); __x != __e; ++__x)
00306 xm->gid_data()->mk_gvarref((*__x)->params.nn(), xm->empty_reference());
00307 unsigned int const_num;
00308 for(__x = added_constraints.begin(), __e = added_constraints.end();
00309 __x != __e; ++__x)
00310 {
00311 bool ok = xm->gid_data()->get_const_num((*__x)->node_num, const_num);
00312 if(ok)
00313 xm->gid_data()->remove_const_ref(const_num);
00314 }
00315
00316
00317 model::erased_part me = xm->erase_minimal_subgraph(added_nodes);
00318 xm->clear_erased_part(me);
00319
00320 if(!added_nodes.empty())
00321 {
00322
00323 std::vector<walker> _nn;
00324 std::swap(_nn, xm->node_ref);
00325 std::set_difference(_nn.begin(), _nn.end(), added_nodes.begin(),
00326 added_nodes.end(), back_inserter(xm->node_ref),
00327 model::__docompare_nodes());
00328 }
00329
00330 std::vector<model::walker> _nn;
00331 if(!added_vars.empty())
00332 {
00333 _nn.erase(_nn.begin(), _nn.end());
00334 std::swap(_nn, xm->var_ref);
00335 std::set_difference(_nn.begin(), _nn.end(), added_vars.begin(),
00336 added_vars.end(), back_inserter(xm->var_ref),
00337 model::__docompare_variables());
00338 }
00339
00340 if(!added_ghosts.empty())
00341 {
00342 _nn.erase(_nn.begin(), _nn.end());
00343 std::swap(_nn, xm->ghost_ref);
00344 std::set_difference(_nn.begin(), _nn.end(), added_ghosts.begin(),
00345 added_ghosts.end(), back_inserter(xm->ghost_ref),
00346 model::__docompare_nodes());
00347 }
00348
00349 if(!added_constraints.empty())
00350 {
00351
00352 std::vector<walker>::iterator _i =
00353 std::stable_partition(xm->constraints.begin(), xm->constraints.end(),
00354 __check_walkers(added_constraints));
00355 xm->constraints.erase(_i, xm->constraints.end());
00356 }
00357
00358
00359 for(std::map<unsigned int, interval>::const_iterator __b =
00360 bounds_chgd.begin(); __b != bounds_chgd.end(); ++__b)
00361 xm->node(__b->first)->f_bounds = __b->second;
00362
00363 return true;
00364 }
00365 }