00001
00002
00003 #include <limits.h>
00004 #include <algorithm>
00005
00006 #include "angel/include/heuristics.hpp"
00007 #include "angel/include/angel_exceptions.hpp"
00008 #include "angel/include/angel_tools.hpp"
00009 #ifdef USEXAIFBOOSTER
00010 #include "angel/include/reroutings.hpp"
00011 using namespace xaifBoosterCrossCountryInterface;
00012 #endif
00013
00014 namespace angel {
00015
00016 using namespace std;
00017 using namespace boost;
00018
00019
00020
00021
00022
00023 int forward_mode_vertex_t::operator() (const vector<c_graph_t::vertex_t>& vv1,
00024 const c_graph_t& cg,
00025 vector<c_graph_t::vertex_t>& vv2) {
00026 vv2.resize (0);
00027 if (vv1.size() == 0) {set_empty_objective (); return 0; }
00028 vv2.push_back (vv1[0]);
00029
00030 for (size_t c= 1; c < vv1.size(); c++)
00031 if (vv1[c] < vv2[0]) vv2[0]= vv1[c];
00032 set_objective (vv2[0]);
00033 return 1;
00034 }
00035
00036 forward_mode_vertex_t forward_mode_vertex;
00037
00038
00039
00040
00041
00042 int reverse_mode_vertex_t::operator() (const vector<c_graph_t::vertex_t>& vv1,
00043 const c_graph_t& cg,
00044 vector<c_graph_t::vertex_t>& vv2) {
00045 vv2.resize (0);
00046 if (vv1.size() == 0) {set_empty_objective (); return 0; }
00047 vv2.push_back (vv1[0]);
00048
00049 for (size_t c= 1; c < vv1.size(); c++)
00050 if (vv1[c] > vv2[0]) vv2[0]= vv1[c];
00051 set_objective (vv2[0]);
00052 return 1;
00053 }
00054
00055 reverse_mode_vertex_t reverse_mode_vertex;
00056
00057
00058
00059
00060
00061
00062 struct lmv_op_t {
00063 int operator() (c_graph_t::vertex_t v, const c_graph_t& cg) {
00064 return in_degree (v, cg) * out_degree (v, cg); }
00065 };
00066
00067 int lowest_markowitz_vertex_t::operator() (const vector<c_graph_t::vertex_t>& vv1,
00068 const c_graph_t& cg,
00069 vector<c_graph_t::vertex_t>& vv2) {
00070 lmv_op_t lmv_op;
00071 return standard_heuristic_op (vv1, cg, vv2, lmv_op, *this);
00072 }
00073
00074 lowest_markowitz_vertex_t lowest_markowitz_vertex;
00075
00076
00077
00078
00079
00080
00081 struct lrm_op_t {
00082 vector<int> indep, dep;
00083 lrm_op_t (const c_graph_t& cg) : indep (num_vertices (cg)), dep (num_vertices (cg)) {
00084 number_independent_vertices (cg, indep); number_dependent_vertices (cg, dep); }
00085 int operator() (bool front, c_graph_t::edge_t edge, const c_graph_t& cg) {
00086 return front ? out_degree (target (edge, cg), cg) - dep[target (edge, cg)]
00087 : in_degree (source (edge, cg), cg) - indep[source (edge, cg)]; }
00088 int operator() (edge_bool_t eb, const c_graph_t& cg) {
00089 return eb.second ? out_degree (target (eb.first, cg), cg) - dep[target (eb.first, cg)]
00090 : in_degree (source (eb.first, cg), cg) - indep[source (eb.first, cg)]; }
00091 int operator() (c_graph_t::vertex_t v, const c_graph_t& cg) {
00092 return in_degree (v, cg) * out_degree (v, cg) - indep[v] * dep[v]; }
00093 };
00094
00095 int lowest_relative_markowitz_vertex_t::operator() (const vector<c_graph_t::vertex_t>& vv1,
00096 const c_graph_t& cg,
00097 vector<c_graph_t::vertex_t>& vv2) {
00098 lrm_op_t lrm_op (cg);
00099 return standard_heuristic_op (vv1, cg, vv2, lrm_op, *this);
00100 }
00101
00102 lowest_relative_markowitz_vertex_t lowest_relative_markowitz_vertex;
00103
00104
00105
00106
00107
00108
00109 int new_in_edges (c_graph_t::edge_t e, const c_graph_t& cg) {
00110
00111 typedef c_graph_t::vertex_t vertex_t;
00112 typedef c_graph_t::iei_t iei_t;
00113
00114 iei_t siei, sie_end, tiei, tie_end;
00115 tie (siei, sie_end)= in_edges (source (e, cg), cg);
00116 tie (tiei, tie_end)= in_edges (target (e, cg), cg);
00117 int new_edges= 0;
00118
00119 vector<vertex_t> nsl;
00120
00121 for (; siei != sie_end; ++siei) {
00122 vertex_t ss= source (*siei, cg);
00123 iei_t i= tiei;
00124 for (; i != tie_end; ++i)
00125 if (source (*i, cg) == ss) break;
00126 if (i == tie_end
00127 && find (nsl.begin(), nsl.end(), ss) == nsl.end()) {
00128 nsl.push_back (ss); new_edges++; }
00129 }
00130
00131 return new_edges;
00132 }
00133
00134
00135 int new_out_edges (c_graph_t::edge_t e, const c_graph_t& cg) {
00136
00137 typedef c_graph_t::vertex_t vertex_t;
00138 typedef c_graph_t::oei_t oei_t;
00139
00140 oei_t soei, soe_end, toei, toe_end;
00141 tie (soei, soe_end)= out_edges (source (e, cg), cg);
00142 tie (toei, toe_end)= out_edges (target (e, cg), cg);
00143 int new_edges= 0;
00144
00145 vector<vertex_t> ntl;
00146
00147 for (; toei != toe_end; ++toei) {
00148 vertex_t tt= target (*toei, cg);
00149 oei_t i= soei;
00150 for (; i != soe_end; ++i)
00151 if (target (*i, cg) == tt) break;
00152 if (i == soe_end
00153 && find (ntl.begin(), ntl.end(), tt) == ntl.end()) {
00154 ntl.push_back (tt); new_edges++; }
00155 }
00156
00157 return new_edges;
00158 }
00159
00160
00161
00162
00163
00164
00165
00166
00167 struct fiv_op_t {
00168 int operator() (c_graph_t::vertex_t v, const c_graph_t& cg) {
00169 int fill_ins= 0;
00170 c_graph_t::iei_t iei, ie_end;
00171 for (tie (iei, ie_end)= in_edges (v, cg); iei != ie_end; ++iei)
00172 fill_ins+= new_out_edges (*iei, cg);
00173 return fill_ins; }
00174 };
00175
00176 int lowest_fill_in_vertex_t::operator() (const vector<c_graph_t::vertex_t>& vv1,
00177 const c_graph_t& cg,
00178 vector<c_graph_t::vertex_t>& vv2) {
00179 fiv_op_t fiv_op;
00180 return standard_heuristic_op (vv1, cg, vv2, fiv_op, *this);
00181 }
00182
00183 lowest_fill_in_vertex_t lowest_fill_in_vertex;
00184
00185
00186
00187
00188
00189
00190
00191 int markowitz_enlargement_front (c_graph_t::edge_t e, const c_graph_t& cg,
00192 bool eliminate_parallel_edges= false) {
00193 int ee= 0;
00194 c_graph_t::vertex_t s= source (e, cg), t= target (e, cg);
00195 if (vertex_type (t, cg) == intermediate){
00196 if (eliminate_parallel_edges) {
00197 c_graph_t::oei_t soei, soe_end;
00198 for (tie (soei, soe_end)= out_edges (s, cg); soei != soe_end; soei++)
00199 ee+= target (*soei, cg) == t;
00200 } else ee= 1;
00201 }
00202 return in_degree (source (e, cg), cg) * (new_out_edges (e, cg) - ee);
00203 }
00204
00205
00206 int markowitz_enlargement_front (c_graph_t::edge_t e, c_graph_t::edge_t e2,
00207 const c_graph_t& cg) {
00208
00209 THROW_DEBUG_EXCEPT_MACRO (target (e, cg) != source (e2, cg), consistency_exception,
00210 "e and e2 does not match");
00211
00212 c_graph_t::vertex_t j= target (e2, cg), se= source (e, cg), te= target (e, cg);
00213
00214
00215
00216
00217
00218
00219 int in_edge_change= in_degree (te, cg) == 1 ? - count_parallel_edges (e2, cg) : 0;
00220
00221
00222 c_graph_t::iei_t iei, ie_end;
00223 for (tie (iei, ie_end)= in_edges (j, cg); iei != ie_end; ++iei)
00224 if (source (*iei, cg) == se) break;
00225 if (iei == ie_end) in_edge_change++;
00226
00227 return in_edge_change * out_degree (j, cg);
00228 }
00229
00230
00231
00232 int markowitz_enlargement_back (c_graph_t::edge_t e, const c_graph_t& cg,
00233 bool eliminate_parallel_edges= false) {
00234
00235 int ee= 0;
00236 if (eliminate_parallel_edges) {
00237 c_graph_t::vertex_t s= source (e, cg), t= target (e, cg);
00238 c_graph_t::iei_t tiei, tie_end;
00239 for (tie (tiei, tie_end)= in_edges (t, cg); tiei != tie_end; ++tiei)
00240 ee+= source (*tiei, cg) == s;
00241 } else ee= 1;
00242
00243 return out_degree (target (e, cg), cg) * (new_in_edges (e, cg) - ee);
00244 }
00245
00246
00247 int markowitz_enlargement_back (c_graph_t::edge_t e, c_graph_t::edge_t e2,
00248 const c_graph_t& cg) {
00249
00250
00251 THROW_DEBUG_EXCEPT_MACRO (source (e, cg) != target (e2, cg), consistency_exception,
00252 "e and e2 does not match");
00253
00254 c_graph_t::vertex_t j= source (e2, cg), se= source (e, cg), te= target (e, cg);
00255
00256
00257 int out_edge_change= out_degree (se, cg) == 1 ? -1 : 0;
00258
00259
00260 c_graph_t::oei_t oei, oe_end;
00261 for (tie (oei, oe_end)= out_edges (j, cg); oei != oe_end; ++oei)
00262 if (target (*oei, cg) == te) break;
00263 if (oei == oe_end) out_edge_change++;
00264
00265 return out_edge_change * in_degree (j, cg);
00266 }
00267
00268
00269
00270 int markowitz_enlargement_all_neighbors (c_graph_t::vertex_t v, const c_graph_t& cg) {
00271
00272 using namespace std;
00273
00274 typedef c_graph_t::vertex_t vertex_t;
00275
00276 int enl= 0;
00277
00278
00279 vector<vertex_t> cv;
00280 cv.reserve (10);
00281
00282 c_graph_t::iei_t iei, ie_end;
00283 tie (iei, ie_end)= in_edges (v, cg);
00284 for (; iei != ie_end; ++iei) {
00285 vertex_t v= source (*iei, cg);
00286 if (find (cv.begin(), cv.end(), v) == cv.end()) {
00287 enl+= markowitz_enlargement_front (*iei, cg, true);
00288 cv.push_back (v); } }
00289
00290 cv.resize (0);
00291 c_graph_t::oei_t oei, oe_end;
00292 tie (oei, oe_end)= out_edges (v, cg);
00293 for (; oei != oe_end; ++oei) {
00294 vertex_t v= target (*oei, cg);
00295 if (find (cv.begin(), cv.end(), v) == cv.end()) {
00296 enl+= markowitz_enlargement_back (*oei, cg, true);
00297 cv.push_back (v); } }
00298 return enl;
00299 }
00300
00301 struct markowitz_enlargement_front_t {
00302 c_graph_t::edge_t _e;
00303 markowitz_enlargement_front_t (c_graph_t::edge_t e) : _e (e) {}
00304 int operator() (c_graph_t::edge_t e2, const c_graph_t& cg) const {
00305 return markowitz_enlargement_front (_e, e2, cg); }
00306 };
00307
00308 struct markowitz_enlargement_back_t {
00309 c_graph_t::edge_t _e;
00310 markowitz_enlargement_back_t (c_graph_t::edge_t e) : _e (e) {}
00311 int operator() (c_graph_t::edge_t e2, const c_graph_t& cg) const {
00312 return markowitz_enlargement_back (_e, e2, cg); }
00313 };
00314
00315
00316
00317
00318
00319
00320
00321 struct lmmdv_op_t {
00322 double w;
00323 lmmdv_op_t (double _w) : w (_w) {}
00324 int operator() (c_graph_t::vertex_t v, const c_graph_t& cg) {
00325 int markowitz= in_degree (v, cg) * out_degree (v, cg),
00326 damage= markowitz_enlargement_all_neighbors (v, cg);
00327 return int (double (markowitz) + w * double (damage)); }
00328 };
00329
00330 int lmmd_vertex_t::operator() (const vector<c_graph_t::vertex_t>& vv1,
00331 const c_graph_t& cg,
00332 vector<c_graph_t::vertex_t>& vv2) {
00333 lmmdv_op_t lmmdv_op (weight);
00334 return standard_heuristic_op (vv1, cg, vv2, lmmdv_op, *this);
00335 }
00336
00337 lmmd_vertex_t lmmd_vertex (1.0);
00338
00339
00340
00341
00342
00343
00344 struct momrv_op_t {
00345 int operator() (c_graph_t::vertex_t v, const c_graph_t& cg) {
00346 int momr= in_degree (v, cg) * out_degree (v, cg)
00347 - markowitz_enlargement_all_neighbors (v, cg);
00348 #ifndef NDEBUG
00349 c_graph_t gtmp (cg); vertex_elimination (v, gtmp);
00350 THROW_DEBUG_EXCEPT_MACRO (overall_markowitz_degree (cg) - overall_markowitz_degree (gtmp) != momr,
00351 consistency_exception, "momr not correct");
00352 #endif
00353 return momr; }
00354 };
00355
00356 int momr_vertex_t::operator() (const vector<c_graph_t::vertex_t>& vv1,
00357 const c_graph_t& cg,
00358 vector<c_graph_t::vertex_t>& vv2) {
00359 momrv_op_t momrv_op;
00360 return standard_heuristic_op (vv1, cg, vv2, momrv_op, *this);
00361 }
00362
00363 momr_vertex_t momr_vertex;
00364
00365
00366
00367
00368
00369
00370 inline int oplr_face (c_graph_t::edge_t e1, c_graph_t::edge_t e2,
00371 const vector<int>& vni, const vector<int>& vli,
00372 const vector<int>& vno, const vector<int>& vlo,
00373 const c_graph_t& cg) {
00374
00375
00376 THROW_DEBUG_EXCEPT_MACRO (target (e1, cg) != source (e2, cg), consistency_exception,
00377 "e1 and e2 does not match");
00378
00379 c_graph_t::vertex_t p= source (e1, cg), s= target (e2, cg);
00380
00381 c_graph_t::edge_t e;
00382 bool found;
00383 boost::tie (e, found)= edge (p, s, cg);
00384
00385 return found ? vno[s] * (vni[p] + vli[p]) + vni[p] * (vno[s] + vlo[s])
00386 : vni[p] * vno[s];
00387 }
00388
00389 int oplr_edge_front (c_graph_t::edge_t e,
00390 const vector<int>& vni, const vector<int>& vli,
00391 const vector<int>& vno, const vector<int>& vlo,
00392 const c_graph_t& cg) {
00393
00394 int oplr= 0;
00395 graph_traits<c_graph_t>::out_edge_iterator oei, oe_end;
00396 tie (oei, oe_end)= out_edges (target (e, cg), cg);
00397
00398 for (; oei != oe_end; ++oei)
00399 oplr+= oplr_face (e, *oei, vni, vli, vno, vlo, cg);
00400
00401 return oplr;
00402 }
00403
00404 int oplr_edge_back (c_graph_t::edge_t e,
00405 const vector<int>& vni, const vector<int>& vli,
00406 const vector<int>& vno, const vector<int>& vlo,
00407 const c_graph_t& cg) {
00408
00409 int oplr= 0;
00410 graph_traits<c_graph_t>::in_edge_iterator iei, ie_end;
00411 tie (iei, ie_end)= in_edges (source (e, cg), cg);
00412
00413 for (; iei != ie_end; ++iei)
00414 oplr+= oplr_face (*iei, e, vni, vli, vno, vlo, cg);
00415
00416 return oplr;
00417 }
00418
00419
00420
00421
00422
00423
00424 struct oplrv_op_t {
00425 vector<int> vni, vli, vno, vlo;
00426 oplrv_op_t (const c_graph_t& cg) {
00427 in_out_path_lengths (cg, vni, vli, vno, vlo); }
00428 int operator () (c_graph_t::vertex_t v, const c_graph_t& cg) {
00429 int oplr= 0;
00430 c_graph_t::iei_t iei, ie_end;
00431 for (tie (iei, ie_end)= in_edges (v, cg); iei != ie_end; ++iei)
00432 oplr+= oplr_edge_front (*iei, vni, vli, vno, vlo, cg);
00433 return oplr; }
00434 };
00435
00436 int moplr_vertex_t::operator() (const vector<c_graph_t::vertex_t>& vv1,
00437 const c_graph_t& cg,
00438 vector<c_graph_t::vertex_t>& vv2) {
00439 oplrv_op_t oplrv_op (cg);
00440 return standard_heuristic_op (vv1, cg, vv2, oplrv_op, *this);
00441 }
00442
00443 moplr_vertex_t moplr_vertex;
00444
00445
00446
00447
00448
00449 int forward_mode_edge_f (const vector<c_graph_t::edge_t>& ev1,
00450 bool front,
00451 const c_graph_t& cg,
00452 vector<c_graph_t::edge_t>& ev2) {
00453 ev2.resize (0);
00454
00455 if (ev1.size() == 0) return 0;
00456 ev2.push_back (ev1[0]);
00457
00458 for (size_t c= 1; c < ev1.size(); c++)
00459 if (front ? inv_lex_less (ev1[c], ev2[0], cg) : lex_less (ev1[c], ev2[0], cg))
00460 ev2[0]= ev1[c];
00461
00462 return 1;
00463 }
00464
00465
00466
00467 inline double fme_obj (edge_bool_t eb, const c_graph_t& cg) {
00468 c_graph_t::edge_t edge= eb.first;
00469
00470 int high, low, notfront;
00471 if (eb.second) high= target (edge, cg), low= source (edge, cg), notfront= 0;
00472 else high= source (edge, cg), low= target (edge, cg), notfront= 1;
00473 return (2 * high + notfront) * double (cg.x()) + low;
00474 }
00475
00476 int forward_mode_edge_t::operator() (const vector<edge_bool_t>& ev1,
00477 const c_graph_t& cg,
00478 vector<edge_bool_t>& ev2) {
00479 ev2.resize (0);
00480 if (ev1.size() == 0) {set_empty_objective (); return 0; }
00481 ev2.push_back (ev1[0]);
00482
00483 for (size_t c= 1; c < ev1.size(); c++) {
00484
00485
00486 if (lex_less (ev1[c], ev2[0], cg)) ev2[0]= ev1[c]; }
00487 set_objective (fme_obj (ev2[0], cg));
00488 return 1;
00489 }
00490
00491 forward_mode_edge_t forward_mode_edge;
00492
00493
00494
00495
00496
00497
00498
00499
00500
00501 int reverse_mode_edge_f (const vector<c_graph_t::edge_t>& ev1,
00502 bool front,
00503 const c_graph_t& cg,
00504 vector<c_graph_t::edge_t>& ev2) {
00505 ev2.resize (0);
00506
00507 if (ev1.size() == 0) return 0;
00508 ev2.push_back (ev1[0]);
00509
00510 for (size_t c= 1; c < ev1.size(); c++)
00511 if (front ? inv_lex_greater (ev1[c], ev2[0], cg) : lex_greater (ev1[c], ev2[0], cg))
00512 ev2[0]= ev1[c];
00513
00514 return 1;
00515 }
00516
00517
00518
00519 inline double rme_obj (edge_bool_t eb, const c_graph_t& cg) {
00520 c_graph_t::edge_t edge= eb.first;
00521
00522 int high, low, front;
00523 if (eb.second) high= target (edge, cg), low= source (edge, cg), front= 1;
00524 else high= source (edge, cg), low= target (edge, cg), front= 0;
00525 return (2 * high + front) * double (cg.x()) + low;
00526 }
00527
00528 int reverse_mode_edge_t::operator() (const vector<edge_bool_t>& ev1,
00529 const c_graph_t& cg,
00530 vector<edge_bool_t>& ev2) {
00531 ev2.resize (0);
00532
00533 if (ev1.size() == 0) {set_empty_objective (); return 0; }
00534 ev2.push_back (ev1[0]);
00535
00536 for (size_t c= 1; c < ev1.size(); c++) {
00537
00538
00539 if (lex_greater (ev1[c], ev2[0], cg)) ev2[0]= ev1[c]; }
00540 set_objective (rme_obj (ev2[0], cg));
00541 return 1;
00542 }
00543
00544 reverse_mode_edge_t reverse_mode_edge;
00545
00546
00547
00548
00549
00550
00551
00552
00553
00554 int lowest_markowitz_edge_f (const vector<c_graph_t::edge_t>& ev1,
00555 bool front,
00556 const c_graph_t& cg,
00557 vector<c_graph_t::edge_t>& ev2) {
00558 ev2.resize (0);
00559
00560 if (ev1.size() == 0) return 0;
00561 int min_degree= front ? out_degree (target (ev1[0], cg), cg)
00562 : in_degree (source (ev1[0], cg), cg);
00563 ev2.push_back (ev1[0]);
00564
00565 for (size_t c= 1; c < ev1.size(); c++) {
00566 c_graph_t::edge_t e= ev1[c];
00567 int degree= front ? out_degree (target (e, cg), cg)
00568 : in_degree (source (e, cg), cg);
00569 if (degree < min_degree) ev2.resize (0);
00570 if (degree <= min_degree) {
00571 ev2.push_back (e); min_degree= degree;}
00572 }
00573 return ev2.size();
00574 }
00575
00576
00577 struct lme_op_t {
00578 int operator() (edge_bool_t eb, const c_graph_t& cg) {
00579 return eb.second ? out_degree (target (eb.first, cg), cg)
00580 : in_degree (source (eb.first, cg), cg); }
00581 };
00582
00583 int lowest_markowitz_edge_t::operator() (const vector<edge_bool_t>& ev1,
00584 const c_graph_t& cg,
00585 vector<edge_bool_t>& ev2) {
00586 lme_op_t lme_op;
00587 return standard_heuristic_op (ev1, cg, ev2, lme_op, *this);
00588 }
00589
00590 lowest_markowitz_edge_t lowest_markowitz_edge;
00591
00592
00593
00594
00595
00596 int lowest_relative_markowitz_edge_f (const vector<c_graph_t::edge_t>& ev1,
00597 bool front,
00598 const c_graph_t& cg,
00599 vector<c_graph_t::edge_t>& ev2) {
00600 ev2.resize (0);
00601 if (ev1.size() == 0) return 0;
00602 lrm_op_t lrm_op (cg);
00603 int min_degree= lrm_op (front, ev1[0], cg);
00604 ev2.push_back (ev1[0]);
00605
00606 for (size_t c= 1; c < ev1.size(); c++) {
00607 int degree= lrm_op (front, ev1[c], cg);
00608 if (degree < min_degree) ev2.resize (0);
00609 if (degree <= min_degree) {
00610 ev2.push_back (ev1[c]); min_degree= degree;} }
00611 return ev2.size();
00612 }
00613
00614 int lowest_relative_markowitz_edge_t::operator() (const vector<edge_bool_t>& ev1,
00615 const c_graph_t& cg,
00616 vector<edge_bool_t>& ev2) {
00617 lrm_op_t lrm_op (cg);
00618 return standard_heuristic_op (ev1, cg, ev2, lrm_op, *this);
00619 }
00620
00621 lowest_relative_markowitz_edge_t lowest_relative_markowitz_edge;
00622
00623
00624
00625
00626
00627 inline int fill_in_front (c_graph_t::edge_t e, const c_graph_t& cg) {
00628 return new_out_edges (e, cg);
00629 }
00630
00631 inline int fill_in_back (c_graph_t::edge_t e, const c_graph_t& cg) {
00632 return new_in_edges (e, cg);
00633 }
00634
00635
00636 int lowest_fill_in_edge_f (const vector<c_graph_t::edge_t>& ev1,
00637 bool front,
00638 const c_graph_t& cg,
00639 vector<c_graph_t::edge_t>& ev2) {
00640 ev2.resize (0);
00641
00642 if (ev1.size() == 0) return 0;
00643 int min_degree= front ? fill_in_front (ev1[0], cg)
00644 : fill_in_back (ev1[0], cg);
00645 ev2.push_back (ev1[0]);
00646
00647 for (size_t c= 1; c < ev1.size(); c++) {
00648 c_graph_t::edge_t e= ev1[c];
00649 int degree= front ? fill_in_front (e, cg)
00650 : fill_in_back (e, cg);
00651 if (degree < min_degree) ev2.resize (0);
00652 if (degree <= min_degree) {
00653 ev2.push_back (e); min_degree= degree;}
00654 }
00655
00656 return ev2.size();
00657 }
00658
00659
00660
00661
00662
00663
00664 lmmd_edge_t lmmd_edge (1.0);
00665
00666 inline int lmmd_edge_front (c_graph_t::edge_t e, double w, const c_graph_t& cg) {
00667 int markowitz= out_degree (target (e, cg), cg);
00668 markowitz_enlargement_front_t me (e);
00669 int damage= markowitz_enlargement_front (e, cg)
00670 + sum_over_all_out_edges (target (e, cg), cg, me);
00671 return int (double (markowitz) + w * double (damage));
00672 }
00673
00674 inline int lmmd_edge_back (c_graph_t::edge_t e, double w, const c_graph_t& cg) {
00675 int markowitz= in_degree (source (e, cg), cg);
00676 markowitz_enlargement_back_t me (e);
00677 int damage= markowitz_enlargement_back (e, cg)
00678 + sum_over_all_in_edges (source (e, cg), cg, me);
00679 return int (double (markowitz) + w * double (damage));
00680 }
00681
00682 struct lmmde_op_t {
00683 double w;
00684 lmmde_op_t (double _w) : w (_w) {}
00685 int operator() (edge_bool_t eb, const c_graph_t& cg) {
00686 return eb.second ? lmmd_edge_front (eb.first, w, cg)
00687 : lmmd_edge_back (eb.first, w, cg); }
00688 };
00689
00690 int lmmd_edge_t::operator() (const vector<edge_bool_t>& ev1,
00691 const c_graph_t& cg,
00692 vector<edge_bool_t>& ev2) {
00693 lmmde_op_t lmmde_op (weight);
00694 return standard_heuristic_op (ev1, cg, ev2, lmmde_op, *this);
00695 }
00696
00697
00698
00699
00700
00701
00702 inline int momr_edge_front (c_graph_t::edge_t e, const c_graph_t& cg) {
00703
00704 markowitz_enlargement_front_t me (e);
00705 int momr= out_degree (target (e, cg), cg) - markowitz_enlargement_front (e, cg)
00706 - sum_over_all_out_edges (target (e, cg), cg, me);
00707
00708 #ifndef NDEBUG
00709 c_graph_t gtmp (cg);
00710
00711
00712 c_graph_t::edge_t etmp;
00713 c_graph_t::ei_t ei, e_end;
00714 c_graph_t::vertex_t s= source (e, cg), t= target (e, cg);
00715 for (boost::tie (ei, e_end)= edges (gtmp); ei != e_end; ++ei)
00716 if (source (*ei, gtmp) == s && target (*ei, gtmp) == t) {
00717 etmp= *ei; break; }
00718
00719 THROW_DEBUG_EXCEPT_MACRO (ei == e_end, consistency_exception, "No matching edge found");
00720
00721 front_edge_elimination (etmp, gtmp);
00722
00723 THROW_DEBUG_EXCEPT_MACRO (overall_markowitz_degree (cg) - overall_markowitz_degree (gtmp) != momr,
00724 consistency_exception, "momr not correct");
00725 #endif
00726 return momr;
00727 }
00728
00729 inline int momr_edge_back (c_graph_t::edge_t e, const c_graph_t& cg) {
00730
00731 int momr= in_degree (source (e, cg), cg);
00732
00733 momr-= markowitz_enlargement_back (e, cg);
00734
00735
00736
00737 c_graph_t::iei_t iei, ie_end;
00738 tie (iei, ie_end)= in_edges (source (e, cg), cg);
00739 for (; iei != ie_end; ++iei)
00740 momr-= markowitz_enlargement_back (e, *iei, cg);
00741 #ifndef NDEBUG
00742 markowitz_enlargement_back_t me (e);
00743 int momr2= in_degree (source (e, cg), cg) - markowitz_enlargement_back (e, cg)
00744 - sum_over_all_in_edges (source (e, cg), cg, me);
00745
00746 THROW_DEBUG_EXCEPT_MACRO (momr2 != momr, consistency_exception, "momr not correct");
00747
00748 c_graph_t gtmp (cg);
00749 c_graph_t::vi_t vi, v_end;
00750 int old_overall_markowitz= 0, new_overall_markowitz= 0;
00751 for (boost::tie (vi, v_end)= vertices (gtmp); vi != v_end; ++vi)
00752 old_overall_markowitz+= in_degree (*vi, gtmp) * out_degree (*vi, gtmp);
00753
00754
00755 c_graph_t::edge_t etmp;
00756 c_graph_t::ei_t ei, e_end;
00757 c_graph_t::vertex_t s= source (e, cg), t= target (e, cg);
00758 for (boost::tie (ei, e_end)= edges (gtmp); ei != e_end; ++ei)
00759 if (source (*ei, gtmp) == s && target (*ei, gtmp) == t) {
00760 etmp= *ei; break; }
00761
00762 THROW_DEBUG_EXCEPT_MACRO (ei == e_end, consistency_exception, "No matching edge found");
00763
00764 back_edge_elimination (etmp, gtmp);
00765 for (boost::tie (vi, v_end)= vertices (gtmp); vi != v_end; ++vi)
00766 new_overall_markowitz+= in_degree (*vi, gtmp) * out_degree (*vi, gtmp);
00767
00768 THROW_DEBUG_EXCEPT_MACRO (old_overall_markowitz-new_overall_markowitz != momr,
00769 consistency_exception, "momr not correct");
00770 #endif
00771 return momr;
00772 }
00773
00774
00775 struct momre_op_t {
00776 int operator() (bool front, c_graph_t::edge_t edge, const c_graph_t& cg) {
00777 return front ? momr_edge_front (edge, cg) : momr_edge_back (edge, cg); }
00778 int operator() (edge_bool_t eb, const c_graph_t& cg) {
00779 return eb.second ? momr_edge_front (eb.first, cg) : momr_edge_back (eb.first, cg); }
00780 };
00781
00782 int momr_edge_f (const vector<c_graph_t::edge_t>& ev1,
00783 bool front,
00784 const c_graph_t& cg,
00785 vector<c_graph_t::edge_t>& ev2) {
00786 ev2.resize (0);
00787 if (ev1.size() == 0) return 0;
00788 momre_op_t momre_op;
00789 int max_momr= momre_op (front, ev1[0], cg);
00790 ev2.push_back (ev1[0]);
00791
00792 for (size_t c= 1; c < ev1.size(); c++) {
00793 int momr= momre_op (front, ev1[c], cg);
00794 if (momr > max_momr) ev2.resize (0);
00795 if (momr >= max_momr) {
00796 ev2.push_back (ev1[c]); max_momr= momr;}
00797 }
00798 return ev2.size();
00799 }
00800
00801 int momr_edge_t::operator() (const vector<edge_bool_t>& ev1, const c_graph_t& cg,
00802 vector<edge_bool_t>& ev2) {
00803 momre_op_t momre_op;
00804 return standard_heuristic_op (ev1, cg, ev2, momre_op, *this);
00805 }
00806
00807 momr_edge_t momr_edge;
00808
00809
00810
00811
00812
00813
00814 struct diste_op_t {
00815 int operator() (edge_bool_t eb, const c_graph_t& cg) {
00816 c_graph_t::vertex_t i= source (eb.first, cg), j= target (eb.first, cg), dist= 0;
00817 vector<c_graph_t::vertex_t> nb;
00818 if (eb.second) {
00819 successor_set (j, cg, nb);
00820 for (size_t c= 0; c < nb.size(); c++)
00821 if (nb[c] - i > dist) dist= nb[c] - i;
00822 } else {
00823 predecessor_set (j, cg, nb);
00824 for (size_t c= 0; c < nb.size(); c++)
00825 if (j - nb[c] > dist) dist= j - nb[c]; }
00826 THROW_DEBUG_EXCEPT_MACRO (dist <= 0, consistency_exception, "Wrong distance in edge elimination");
00827 return dist; }
00828 };
00829
00830 int minimal_distance_edge_t::operator() (const vector<edge_bool_t>& ev1, const c_graph_t& cg,
00831 vector<edge_bool_t>& ev2) {
00832 return standard_heuristic_op (ev1, cg, ev2, diste_op_t(), *this);
00833 }
00834
00835 minimal_distance_edge_t minimal_distance_edge;
00836
00837
00838
00839
00840
00841 int moplr_edge (const vector<c_graph_t::edge_t>& ev1,
00842 bool front,
00843 const c_graph_t& cg,
00844 vector<c_graph_t::edge_t>& ev2) {
00845 ev2.resize (0);
00846 if (ev1.size() == 0) return 0;
00847
00848 vector<int> vni, vli, vno, vlo;
00849 in_out_path_lengths (cg, vni, vli, vno, vlo);
00850
00851 int max_oplr= front ? oplr_edge_front (ev1[0], vni, vli, vno, vlo, cg)
00852 : oplr_edge_back (ev1[0], vni, vli, vno, vlo, cg);
00853 ev2.push_back (ev1[0]);
00854
00855 for (size_t c= 1; c < ev1.size(); c++) {
00856 c_graph_t::edge_t e= ev1[c];
00857 int oplr= front ? oplr_edge_front (e, vni, vli, vno, vlo, cg)
00858 : oplr_edge_back (e, vni, vli, vno, vlo, cg);
00859 if (oplr > max_oplr) ev2.resize (0);
00860 if (oplr >= max_oplr) {
00861 ev2.push_back (e); max_oplr= oplr;}
00862 }
00863
00864 return ev2.size();
00865 }
00866
00867
00868
00869
00870
00871
00872
00873
00874
00875 inline double fmf_obj (line_graph_t::face_t f, const line_graph_t& lg) {
00876 int i, j, k, x= lg.x();
00877 face_vertex_name (f, lg, i, j, k);
00878 return ((double (j) * double (x)) + double (i)) * double (x) + double (k);
00879 }
00880
00881 int forward_mode_face_t::operator() (const vector<line_graph_t::face_t>& fv1,
00882 const line_graph_t& lg,
00883 vector<line_graph_t::face_t>& fv2) {
00884 fv2.resize (0);
00885 if (fv1.size() == 0) {set_empty_objective (); return 0; }
00886 fv2.push_back (fv1[0]);
00887
00888 for (size_t c= 1; c < fv1.size(); c++) {
00889
00890
00891 if (lex_less_face (fv1[c], fv2[0], lg)) fv2[0]= fv1[c]; }
00892 set_objective (fmf_obj (fv2[0], lg));
00893 return 1;
00894 }
00895
00896 forward_mode_face_t forward_mode_face;
00897
00898
00899
00900
00901
00902 int reverse_mode_face_t::operator() (const vector<line_graph_t::face_t>& fv1,
00903 const line_graph_t& lg,
00904 vector<line_graph_t::face_t>& fv2) {
00905 fv2.resize (0);
00906 if (fv1.size() == 0) {set_empty_objective (); return 0; }
00907 fv2.push_back (fv1[0]);
00908
00909 for (size_t c= 1; c < fv1.size(); c++) {
00910
00911
00912 if (!lex_less_face (fv1[c], fv2[0], lg)) fv2[0]= fv1[c]; }
00913 set_objective (fmf_obj (fv2[0], lg));
00914 return 1;
00915 }
00916
00917 reverse_mode_face_t reverse_mode_face;
00918
00919 int reverse_mode_face_whole_vertex_t::operator() (const vector<line_graph_t::face_t>& fv1,
00920 const line_graph_t& lg,
00921 vector<line_graph_t::face_t>& fv2) {
00922 fv2.resize (0);
00923 if (fv1.size() == 0) return 0;
00924 fv2.push_back (fv1[0]);
00925 line_graph_t::const_evn_t evn= get(boost::vertex_name, lg);
00926
00927 int maxv= evn[source(fv1[0], lg)].second;
00928
00929 for (size_t c= 1; c < fv1.size(); c++) {
00930 line_graph_t::face_t f= fv1[c];
00931 int v= evn[source(f, lg)].second;
00932 if (v > maxv) {fv2.resize (0); maxv= v;}
00933 if (v == maxv) fv2.push_back (f); }
00934
00935 return fv2.size();
00936 }
00937
00938 reverse_mode_face_whole_vertex_t reverse_mode_face_whole_vertex;
00939
00940
00941
00942
00943
00944 void markowitz_on_line_graph (const line_graph_t& lg,
00945 vector<int>& mdegree) {
00946
00947 line_graph_t::const_evn_t evn= get(vertex_name, lg);
00948 int max_vertex_cg= 0;
00949 line_graph_t::ei_t ei, e_end;
00950 for (boost::tie (ei, e_end)= vertices (lg); ei != e_end; ++ei)
00951 if (max_vertex_cg < evn[*ei].second) max_vertex_cg= evn[*ei].second;
00952
00953
00954
00955 mdegree.resize (0); mdegree.resize (max_vertex_cg+1);
00956 line_graph_t::fi_t fi, f_end;
00957 for (boost::tie (fi, f_end)= edges (lg); fi != f_end; ++fi) {
00958 line_graph_t::edge_t s= source (*fi, lg), t= target (*fi, lg);
00959 if (evn[s].first != evn[s].second && evn[t].first != evn[t].second)
00960 mdegree[evn[s].second]++; }
00961 }
00962
00963
00964
00965
00966
00967
00968
00969
00970 struct lmf_op_t {
00971 vector<int> mdegree;
00972 lmf_op_t (const line_graph_t& lg) {
00973 markowitz_on_line_graph (lg, mdegree); }
00974 int operator() (line_graph_t::face_t f, const line_graph_t& lg) {
00975 int i, j, k; face_vertex_name (f, lg, i, j, k);
00976 THROW_DEBUG_EXCEPT_MACRO (mdegree[j] == 0, consistency_exception, "Un-eliminatable face in fv1");
00977 return mdegree[j]; }
00978 };
00979
00980 int lowest_markowitz_face_t::operator() (const vector<line_graph_t::face_t>& fv1,
00981 const line_graph_t& lg,
00982 vector<line_graph_t::face_t>& fv2) {
00983 lmf_op_t lmf_op (lg);
00984 return standard_heuristic_op (fv1, lg, fv2, lmf_op, *this);
00985 }
00986
00987
00988
00989
00990
00991
00992
00993
00994 class new_pik_t {
00995 int i, k;
00996 public:
00997 new_pik_t (int _i, int _k) : i (_i), k (_k) {}
00998 int operator() (line_graph_t::face_t pij, const line_graph_t& lg) const {
00999 line_graph_t::edge_t pi= source (pij, lg);
01000
01001 if (vertex_type (pi, lg) == independent) return 0;
01002 line_graph_t::ofi_t ofi, of_end;
01003 for (tie (ofi, of_end)= out_edges (pi, lg); ofi != of_end; ++ofi) {
01004 int v1, v2;
01005 edge_vertex_name (target (*ofi, lg), lg, v1, v2);
01006
01007 THROW_DEBUG_EXCEPT_MACRO (v1 != i, consistency_exception, "Adjacency corrupted in line graph");
01008 if (v2 == k) return 0; }
01009 return 1;
01010 }
01011 };
01012
01013 struct source_not_independent_t {
01014 int operator() (line_graph_t::face_t f, const line_graph_t& lg) const {
01015 return (vertex_type (source (f, lg), lg) != independent); }
01016 };
01017
01018
01019
01020 class new_iks_t {
01021 int i, k;
01022 public:
01023 new_iks_t (int _i, int _k) : i (_i), k (_k) {}
01024 int operator() (line_graph_t::face_t jks, const line_graph_t& lg) const {
01025 line_graph_t::edge_t ks= target (jks, lg);
01026
01027 if (vertex_type (ks, lg) == dependent) return 0;
01028 line_graph_t::ifi_t ifi, if_end;
01029 for (tie (ifi, if_end)= in_edges (ks, lg); ifi != if_end; ++ifi) {
01030 int v1, v2;
01031 edge_vertex_name (source (*ifi, lg), lg, v1, v2);
01032
01033 THROW_DEBUG_EXCEPT_MACRO (v2 != k, consistency_exception, "Adjacency corrupted in line graph");
01034 if (v1 == i) return 0; }
01035 return 1;
01036 }
01037 };
01038
01039 struct target_not_dependent_t {
01040 int operator() (line_graph_t::face_t f, const line_graph_t& lg) const {
01041 return (vertex_type (target (f, lg), lg) != dependent); }
01042 };
01043
01044
01045 struct momrf_op_t {
01046 int operator() (line_graph_t::face_t f, const line_graph_t& lg) {
01047 int momr= 1;
01048 int i, j, k;
01049 face_vertex_name (f, lg, i, j, k);
01050 line_graph_t::edge_t ij= source (f, lg), jk= target (f, lg);
01051
01052 new_pik_t new_pik (i, k);
01053 momr-= sum_over_all_in_edges (ij, lg, new_pik);
01054 if (out_degree (ij, lg) == 1)
01055 momr+= sum_over_all_in_edges (ij, lg, source_not_independent_t());
01056
01057 new_iks_t new_iks (i, k);
01058 momr-= sum_over_all_out_edges (jk, lg, new_iks);
01059 if (in_degree (jk, lg) == 1)
01060 momr+= sum_over_all_out_edges (jk, lg, target_not_dependent_t());
01061 #ifndef NDEBUG
01062 line_graph_t gtmp (lg);
01063
01064
01065 line_graph_t::face_t ftmp;
01066 ftmp= *same_edge (f, lg, gtmp);
01067 face_elimination (ftmp, gtmp);
01068
01069 int old_overall_markowitz= overall_markowitz_degree (lg);
01070 int new_overall_markowitz= overall_markowitz_degree (gtmp);
01071 if (old_overall_markowitz - new_overall_markowitz != momr) {
01072 write_graph ("AD edge before elimination", lg);
01073 line_graph_t::const_evn_t evn= get(vertex_name, lg);
01074 write_vertex_property (cout, "vertices of this edge graph", evn, lg);
01075 cout << "overall_markowitz_degree is " << old_overall_markowitz << "\n";
01076 cout << "elimination of face: ";
01077 write_face_op_t wf (gtmp); wf (cout, ftmp);
01078 cout << endl;
01079 write_graph ("AD edge after elimination", gtmp);
01080 line_graph_t::evn_t evntmp= get(vertex_name, gtmp);
01081 write_vertex_property (cout, "vertices of this edge graph", evntmp, lg);
01082 cout << "overall_markowitz_degree is " << new_overall_markowitz
01083 << " momr is " << momr << "\n";
01084 line_graph_t gtmp2 (lg);
01085 ftmp= *same_edge (f, lg, gtmp2);
01086 face_elimination (ftmp, gtmp2);
01087 }
01088
01089 THROW_DEBUG_EXCEPT_MACRO (overall_markowitz_degree (lg) - overall_markowitz_degree (gtmp) != momr,
01090 consistency_exception, "momr not correct");
01091 #endif
01092 return momr; }
01093 };
01094
01095 int momr_face_t::operator() (const vector<line_graph_t::face_t>& fv1,
01096 const line_graph_t& lg,
01097 vector<line_graph_t::face_t>& fv2) {
01098 momrf_op_t momrf_op;
01099 return standard_heuristic_op (fv1, lg, fv2, momrf_op, *this);
01100 }
01101
01102 momr_face_t momr_face;
01103
01104
01105
01106
01107
01108
01109 struct distf_op_t {
01110 int operator() (line_graph_t::face_t f, const line_graph_t& lg) {
01111 int i, j, k; face_vertex_name (f, lg, i, j, k);
01112 return k - i; }
01113 };
01114
01115 int minimal_distance_face_t::operator() (const vector<line_graph_t::face_t>& fv1,
01116 const line_graph_t& lg, vector<line_graph_t::face_t>& fv2) {
01117 return standard_heuristic_op (fv1, lg, fv2, distf_op_t(), *this);
01118 }
01119
01120 #ifdef USEXAIFBOOSTER
01121
01122
01123
01124
01125 int edge_elim_effect (const edge_bool_t be,
01126 const c_graph_t& angelLCG,
01127 const AwarenessLevel::AwarenessLevel_E ourAwarenessLevel) {
01128
01129 boost::property_map<c_graph_t, EdgeType>::const_type eType = get(EdgeType(), angelLCG);
01130 c_graph_t::oei_t oei, oe_end;
01131 c_graph_t::iei_t iei, ie_end;
01132 c_graph_t::edge_t absorb_e;
01133 bool found_absorb;
01134
01135 c_graph_t::edge_t e = be.first;
01136 bool isFront = be.second;
01137 int nontrivialEdgeChange = 0;
01138
01139
01140 if (ourAwarenessLevel == AwarenessLevel::NO_AWARENESS) nontrivialEdgeChange--;
01141
01142 else if (ourAwarenessLevel == AwarenessLevel::UNIT_AWARENESS && eType[e] != UNIT_EDGE) nontrivialEdgeChange--;
01143
01144 else if (ourAwarenessLevel == AwarenessLevel::CONSTANT_AWARENESS && eType[e] == VARIABLE_EDGE) nontrivialEdgeChange--;
01145
01146 if (isFront) {
01147
01148 if (in_degree (target (e, angelLCG), angelLCG) == 1) {
01149 for (tie (oei, oe_end) = out_edges (target (e, angelLCG), angelLCG); oei != oe_end; ++oei) {
01150
01151 if (ourAwarenessLevel == AwarenessLevel::NO_AWARENESS) nontrivialEdgeChange--;
01152 else if (ourAwarenessLevel == AwarenessLevel::UNIT_AWARENESS && eType[*oei] != UNIT_EDGE) nontrivialEdgeChange--;
01153 else if (ourAwarenessLevel == AwarenessLevel::CONSTANT_AWARENESS && eType[*oei] == VARIABLE_EDGE) nontrivialEdgeChange--;
01154 }
01155 }
01156
01157
01158 for (tie (oei, oe_end) = out_edges (target (e, angelLCG), angelLCG); oei != oe_end; ++oei) {
01159 tie (absorb_e, found_absorb) = edge (source (e, angelLCG), target (*oei, angelLCG), angelLCG);
01160 if (found_absorb) {
01161
01162
01163 if (ourAwarenessLevel == AwarenessLevel::UNIT_AWARENESS && eType[absorb_e] == UNIT_EDGE) nontrivialEdgeChange++;
01164
01165 else if (ourAwarenessLevel == AwarenessLevel::CONSTANT_AWARENESS && eType[absorb_e] != VARIABLE_EDGE)
01166 if (eType[e] == VARIABLE_EDGE || eType[*oei] == VARIABLE_EDGE) nontrivialEdgeChange++;
01167 }
01168 else {
01169 if (ourAwarenessLevel == AwarenessLevel::NO_AWARENESS) nontrivialEdgeChange++;
01170
01171 else if (ourAwarenessLevel == AwarenessLevel::UNIT_AWARENESS && (eType[e] != UNIT_EDGE || eType[*oei] != UNIT_EDGE)) nontrivialEdgeChange++;
01172
01173 else if (ourAwarenessLevel == AwarenessLevel::CONSTANT_AWARENESS && (eType[e] == VARIABLE_EDGE || eType[*oei] == VARIABLE_EDGE)) nontrivialEdgeChange++;
01174 }
01175 }
01176
01177 }
01178 else {
01179
01180
01181 if (out_degree (source (e, angelLCG), angelLCG) == 1 && vertex_type (source (e, angelLCG), angelLCG) != dependent) {
01182 for (tie (iei, ie_end) = in_edges (source (e, angelLCG), angelLCG); iei != ie_end; ++iei) {
01183 if (ourAwarenessLevel == AwarenessLevel::NO_AWARENESS) nontrivialEdgeChange--;
01184 else if (ourAwarenessLevel == AwarenessLevel::UNIT_AWARENESS && eType[*iei] != UNIT_EDGE) nontrivialEdgeChange--;
01185 else if (ourAwarenessLevel == AwarenessLevel::CONSTANT_AWARENESS && eType[*iei] == VARIABLE_EDGE) nontrivialEdgeChange--;
01186 }
01187 }
01188
01189
01190 for (tie (iei, ie_end) = in_edges (source (e, angelLCG), angelLCG); iei != ie_end; ++iei) {
01191 tie (absorb_e, found_absorb) = edge (source (*iei, angelLCG), target (e, angelLCG), angelLCG);
01192 if (found_absorb) {
01193
01194
01195 if (ourAwarenessLevel == AwarenessLevel::UNIT_AWARENESS && eType[absorb_e] == UNIT_EDGE) nontrivialEdgeChange++;
01196
01197 else if (ourAwarenessLevel == AwarenessLevel::CONSTANT_AWARENESS && eType[absorb_e] != VARIABLE_EDGE)
01198 if (eType[e] == VARIABLE_EDGE || eType[*iei] == VARIABLE_EDGE) nontrivialEdgeChange++;
01199 }
01200 else {
01201 if (ourAwarenessLevel == AwarenessLevel::NO_AWARENESS) nontrivialEdgeChange++;
01202
01203 else if (ourAwarenessLevel == AwarenessLevel::UNIT_AWARENESS && (eType[e] != UNIT_EDGE || eType[*iei] != UNIT_EDGE)) nontrivialEdgeChange++;
01204
01205 else if (ourAwarenessLevel == AwarenessLevel::CONSTANT_AWARENESS && (eType[e] == VARIABLE_EDGE || eType[*iei] == VARIABLE_EDGE)) nontrivialEdgeChange++;
01206 }
01207 }
01208 }
01209
01210 return nontrivialEdgeChange;
01211 }
01212
01213 int edge_elim_effect(const EdgeElim ee,
01214 const c_graph_t& angelLCG,
01215 const AwarenessLevel::AwarenessLevel_E ourAwarenessLevel) {
01216 return edge_elim_effect(make_pair(ee.getE(angelLCG), ee.isFront()), angelLCG, ourAwarenessLevel);
01217 }
01218
01219 bool maintaining_edge_eliminations(const vector<EdgeElim>& bev1,
01220 const c_graph_t& angelLCG,
01221 const AwarenessLevel::AwarenessLevel_E ourAwarenessLevel,
01222 vector<EdgeElim>& bev2) {
01223 bev2.clear();
01224 if (bev1.empty()) return 0;
01225
01226 for (size_t c = 0; c < bev1.size(); c++)
01227 if (edge_elim_effect (bev1[c], angelLCG, ourAwarenessLevel) <= 0)
01228 bev2.push_back (bev1[c]);
01229
01230 #ifndef NDEBUG
01231 cout << " Of " << bev1.size() << " edge eliminations passed to maintaining_edge_eliminations(), " << bev2.size() << " maintain the nontrivial edge count" << endl;
01232 #endif
01233
01234 if (bev2.empty()) {
01235 bev2 = bev1;
01236 return false;
01237 }
01238 else return true;
01239 }
01240
01241 bool reducing_edge_eliminations(const vector<EdgeElim>& bev1,
01242 const c_graph_t& angelLCG,
01243 const AwarenessLevel::AwarenessLevel_E ourAwarenessLevel,
01244 vector<EdgeElim>& bev2) {
01245 bev2.clear();
01246 if (bev1.empty()) return 0;
01247
01248 for (size_t c = 0; c < bev1.size(); c++)
01249 if (edge_elim_effect (bev1[c], angelLCG, ourAwarenessLevel) < 0)
01250 bev2.push_back (bev1[c]);
01251
01252 #ifndef NDEBUG
01253 cout << " Of " << bev1.size() << " edge eliminations passed to reducing_edge_eliminations()"
01254 << ", " << bev2.size() << " reduce the nontrivial edge count" << endl;
01255 #endif
01256
01257 if(bev2.empty()) {
01258 bev2 = bev1;
01259 return false;
01260 }
01261 else return true;
01262 }
01263
01264 bool refill_avoiding_edge_eliminations(const vector<EdgeElim>& bev1,
01265 c_graph_t& angelLCG,
01266 const refillDependenceMap_t refillDependences,
01267 vector<EdgeElim>& bev2) {
01268 bev2.clear();
01269 if (bev1.empty())
01270 return 0;
01271
01272 c_graph_t::iei_t iei, ie_end;
01273 c_graph_t::oei_t oei, oe_end;
01274 refillDependenceMap_t::const_iterator depMap_i;
01275 vertex_set_t::const_iterator vDepSet_i;
01276 property_map<pure_c_graph_t, VertexVisited>::type visited = get(VertexVisited(), angelLCG);
01277 c_graph_t::vi_t cleari, clear_end;
01278
01279 for (size_t c = 0; c < bev1.size(); c++) {
01280 c_graph_t::edge_t e = bev1[c].getE(angelLCG);
01281
01282 depMap_i = refillDependences.find(make_pair(source (e, angelLCG), target(e, angelLCG)));
01283 if (depMap_i != refillDependences.end()) {
01284 #ifndef NDEBUG
01285 cout << "edge " << e << " has some refill dependences. Checking them..." << endl;
01286 #endif
01287 vertex_set_t vDepSet = depMap_i->second;
01288
01289
01290
01291 for (vDepSet_i = vDepSet.begin(); vDepSet_i != vDepSet.end(); vDepSet_i++) {
01292
01293 for (tie(cleari, clear_end) = vertices(angelLCG); cleari != clear_end; ++cleari) visited[*cleari] = false;
01294 if (reachable (source (e, angelLCG), *vDepSet_i, angelLCG)) {
01295
01296 for (tie(cleari, clear_end) = vertices(angelLCG); cleari != clear_end; ++cleari) visited[*cleari] = false;
01297 if (reachable (*vDepSet_i, target (e, angelLCG), angelLCG)) {
01298 #ifndef NDEBUG
01299 cout << "edge " << e << " has an unmet refill dependence on vertex " << *vDepSet_i << endl;
01300 #endif
01301 break;
01302 }
01303 }
01304 }
01305
01306
01307 if (vDepSet_i == vDepSet.end())
01308 bev2.push_back(bev1[c]);
01309 }
01310 else bev2.push_back(bev1[c]);
01311
01312 }
01313
01314 #ifndef NDEBUG
01315 cout << " Of " << bev1.size() << " edge eliminations passed to refill_avoiding_edge_eliminations(), " << bev2.size() << " don't violate refill dependences" << endl;
01316 #endif
01317
01318 if (bev2.empty()) {
01319 bev2 = bev1;
01320 return false;
01321 }
01322 else return true;
01323 }
01324
01325 bool rerouting_considerate_edge_eliminations(const vector<EdgeElim>& bev,
01326 const c_graph_t& angelLCG,
01327 const std::vector<Transformation>& transformationsPerformedV,
01328 vector<EdgeElim>& reroutingConsiderateEdgeElimsV) {
01329 reroutingConsiderateEdgeElimsV.clear();
01330 if (bev.empty())
01331 return false;
01332
01333
01334 for (size_t i = 0; i < bev.size(); i++) {
01335 size_t j;
01336
01337 if (bev[i].isFront()) {
01338
01339 for (j = 0; j < transformationsPerformedV.size(); j++) {
01340 if (transformationsPerformedV[j].isRerouting()
01341 && transformationsPerformedV[j].getRerouting().isPre()
01342 && source(transformationsPerformedV[j].getRerouting().getE(angelLCG), angelLCG) == bev[i].getSource()
01343 && source(transformationsPerformedV[j].getRerouting().getPivotE(angelLCG), angelLCG) == bev[i].getTarget())
01344 break;
01345 }
01346 }
01347
01348 else {
01349 for (j = 0; j < transformationsPerformedV.size(); j++) {
01350 if (transformationsPerformedV[j].isRerouting()
01351 && !transformationsPerformedV[j].getRerouting().isPre()
01352 && target(transformationsPerformedV[j].getRerouting().getE(angelLCG), angelLCG) == bev[i].getTarget()
01353 && target(transformationsPerformedV[j].getRerouting().getPivotE(angelLCG), angelLCG) == bev[i].getSource())
01354 break;
01355 }
01356 }
01357
01358 if (j == transformationsPerformedV.size())
01359 reroutingConsiderateEdgeElimsV.push_back(bev[i]);
01360 }
01361
01362 #ifndef NDEBUG
01363 cout << " Of " << bev.size() << " edge eliminations passed to rerouting_considerate_edge_eliminations(), " << reroutingConsiderateEdgeElimsV.size() << " don't undo a rerouting" << endl;
01364 #endif
01365
01366 if (reroutingConsiderateEdgeElimsV.empty()) {
01367 reroutingConsiderateEdgeElimsV = bev;
01368 return false;
01369 }
01370 else return true;
01371 }
01372
01373 unsigned int lowestMarkowitzEdgeElim(const vector<EdgeElim>& inEEV,
01374 const c_graph_t& angelLCG,
01375 vector<EdgeElim>& outEEV) {
01376 outEEV.clear();
01377 if (inEEV.empty())
01378 return 0;
01379
01380 vector<edge_bool_t> inBEV, outBEV;
01381
01382 for (size_t i = 0; i < inEEV.size(); i++)
01383 inBEV.push_back(inEEV[i].getBool(angelLCG));
01384
01385 lowest_markowitz_edge(inBEV, angelLCG, outBEV);
01386
01387 for (size_t i = 0; i < outBEV.size(); i++)
01388 outEEV.push_back(EdgeElim (outBEV[i], angelLCG));
01389
01390 return outEEV.size();
01391 }
01392
01393 bool reverseModeEdgeElim(const vector<EdgeElim>& inEEV,
01394 const c_graph_t& angelLCG,
01395 vector<EdgeElim>& outEEV) {
01396 outEEV.clear();
01397 if (inEEV.empty())
01398 return false;
01399
01400 vector<edge_bool_t> inBEV, outBEV;
01401
01402 for (size_t i = 0; i < inEEV.size(); i++)
01403 inBEV.push_back(inEEV[i].getBool(angelLCG));
01404
01405 reverse_mode_edge(inBEV, angelLCG, outBEV);
01406
01407 for (size_t i = 0; i < outBEV.size(); i++)
01408 outEEV.push_back(EdgeElim (outBEV[i], angelLCG));
01409
01410 return true;
01411 }
01412
01413
01414
01415
01416
01417 size_t noncyclicReroutings (const vector<Rerouting>& erv,
01418 const std::vector<Transformation>& transformationsPerformedV,
01419 const c_graph_t& angelLCG,
01420 vector<Rerouting>& noncyclicReroutingsV) {
01421 noncyclicReroutingsV.clear();
01422 if (erv.empty())
01423 return 0;
01424 size_t j;
01425
01426 for (size_t i = 0; i < erv.size(); i++) {
01427
01428 for (j = 0; j < transformationsPerformedV.size(); j++)
01429 if (transformationsPerformedV[j].isRerouting()
01430 && transformationsPerformedV[j].getRerouting() == erv[i]);
01431 break;
01432 if (j == transformationsPerformedV.size())
01433 noncyclicReroutingsV.push_back(erv[i]);
01434 }
01435 return noncyclicReroutingsV.size();
01436 }
01437
01438
01439
01440
01441
01442
01443
01444
01445
01446
01447
01448
01449
01450
01451
01452
01453
01454
01455
01456
01457
01458
01459
01460
01461
01462
01463
01464
01465
01466
01467
01468
01469
01470
01471
01472
01473
01474
01475
01476
01477
01478
01479
01480
01481
01482
01483
01484
01485
01486
01487
01488
01489
01490
01491
01492 bool reducing_reroutings (const vector<Rerouting>& erv,
01493 const c_graph_t& angelLCG,
01494 const AwarenessLevel::AwarenessLevel_E ourAwarenessLevel,
01495 vector<Rerouting>& reducingReroutingsV) {
01496 reducingReroutingsV.clear();
01497 if (erv.empty())
01498 return 0;
01499
01500 boost::property_map<c_graph_t, EdgeType>::const_type eType = get(EdgeType(), angelLCG);
01501 c_graph_t::iei_t iei, ie_end;
01502 c_graph_t::oei_t oei, oe_end;
01503 c_graph_t::edge_t absorb_e, increment_absorb_e, decrement_absorb_e;
01504 bool found_absorb_e;
01505
01506 for (size_t i = 0; i < erv.size(); i++) {
01507 edge_reroute_t er = erv[i].getER(angelLCG);
01508
01509 bool incrementIsTrivial;
01510 int nontrivialEdgeChange_rerouting = reroute_effect (er, angelLCG, ourAwarenessLevel, incrementIsTrivial);
01511
01512 c_graph_t::edge_t e = er.e;
01513 c_graph_t::edge_t pe = er.pivot_e;
01514 er.pivot_eliminatable = false;
01515 er.increment_eliminatable = false;
01516 er.type3EdgeElimVector.clear();
01517
01518 int nontrivialEdgeChange_elimIncrement = 0;
01519 int nontrivialEdgeChange_elimPivot = 0;
01520
01521 if (er.isPre) {
01522
01523
01524
01525
01526
01527 if (in_degree (source (e, angelLCG), angelLCG) > 0) {
01528
01529 if (!incrementIsTrivial) nontrivialEdgeChange_elimIncrement--;
01530
01531
01532 for (tie(iei, ie_end) = in_edges(source(e, angelLCG), angelLCG); iei != ie_end; ++iei) {
01533 tie(absorb_e, found_absorb_e) = edge(source(*iei, angelLCG), source(pe, angelLCG), angelLCG);
01534 if (found_absorb_e) {
01535 if (ourAwarenessLevel == AwarenessLevel::UNIT_AWARENESS && eType[absorb_e] == UNIT_EDGE) nontrivialEdgeChange_elimIncrement++;
01536 else if (ourAwarenessLevel == AwarenessLevel::CONSTANT_AWARENESS && eType[absorb_e] != VARIABLE_EDGE)
01537 if (eType[*iei] == VARIABLE_EDGE || !incrementIsTrivial) nontrivialEdgeChange_elimIncrement++;
01538 }
01539 else {
01540 if (ourAwarenessLevel == AwarenessLevel::NO_AWARENESS) nontrivialEdgeChange_elimIncrement++;
01541 else if (ourAwarenessLevel == AwarenessLevel::UNIT_AWARENESS && (eType[*iei] != UNIT_EDGE || !incrementIsTrivial)) nontrivialEdgeChange_elimIncrement++;
01542 else if (ourAwarenessLevel == AwarenessLevel::CONSTANT_AWARENESS && (eType[*iei] == VARIABLE_EDGE || !incrementIsTrivial)) nontrivialEdgeChange_elimIncrement++;
01543 }
01544 }
01545 if (nontrivialEdgeChange_rerouting + nontrivialEdgeChange_elimIncrement < 0) er.increment_eliminatable = true;
01546 }
01547
01548
01549
01550
01551
01552
01553 if (in_degree(target(pe, angelLCG), angelLCG) == 2 && vertex_type(target(pe, angelLCG), angelLCG) != dependent) {
01554
01555
01556 if (ourAwarenessLevel == AwarenessLevel::NO_AWARENESS) nontrivialEdgeChange_elimPivot--;
01557 else if (ourAwarenessLevel == AwarenessLevel::UNIT_AWARENESS && eType[pe] != UNIT_EDGE) nontrivialEdgeChange_elimPivot--;
01558 else if (ourAwarenessLevel == AwarenessLevel::CONSTANT_AWARENESS && eType[pe] == VARIABLE_EDGE) nontrivialEdgeChange_elimPivot--;
01559
01560
01561 for (tie (oei, oe_end) = out_edges(target(pe, angelLCG), angelLCG); oei != oe_end; ++oei) {
01562
01563 if (ourAwarenessLevel == AwarenessLevel::NO_AWARENESS) nontrivialEdgeChange_elimPivot--;
01564 else if (ourAwarenessLevel == AwarenessLevel::UNIT_AWARENESS && eType[*oei] != UNIT_EDGE) nontrivialEdgeChange_elimPivot--;
01565 else if (ourAwarenessLevel == AwarenessLevel::CONSTANT_AWARENESS && eType[*oei] == VARIABLE_EDGE) nontrivialEdgeChange_elimPivot--;
01566
01567 tie (absorb_e, found_absorb_e) = edge (source(pe, angelLCG), target(*oei, angelLCG), angelLCG);
01568 if (found_absorb_e) {
01569 if (ourAwarenessLevel == AwarenessLevel::UNIT_AWARENESS && eType[absorb_e] == UNIT_EDGE) nontrivialEdgeChange_elimPivot++;
01570 else if (ourAwarenessLevel == AwarenessLevel::CONSTANT_AWARENESS && eType[absorb_e] != VARIABLE_EDGE)
01571 if (eType[pe] == VARIABLE_EDGE || eType[*oei] == VARIABLE_EDGE) nontrivialEdgeChange_elimPivot++;
01572 }
01573 else {
01574 if (ourAwarenessLevel == AwarenessLevel::NO_AWARENESS) nontrivialEdgeChange_elimPivot++;
01575 else if (ourAwarenessLevel == AwarenessLevel::UNIT_AWARENESS && (eType[pe] != UNIT_EDGE || eType[*oei] != UNIT_EDGE)) nontrivialEdgeChange_elimPivot++;
01576 else if (ourAwarenessLevel == AwarenessLevel::CONSTANT_AWARENESS && (eType[pe] == VARIABLE_EDGE || eType[*oei] == VARIABLE_EDGE)) nontrivialEdgeChange_elimPivot++;
01577 }
01578
01579 }
01580 if (nontrivialEdgeChange_rerouting + nontrivialEdgeChange_elimPivot < 0) er.pivot_eliminatable = true;
01581 }
01582
01583
01584
01585
01586
01587
01588 for (tie(oei, oe_end) = out_edges(target(e, angelLCG), angelLCG); oei != oe_end; ++oei) {
01589 int nontrivialEdgeChange_backElimination = 0;
01590
01591
01592 if (ourAwarenessLevel == AwarenessLevel::NO_AWARENESS
01593 || (ourAwarenessLevel == AwarenessLevel::UNIT_AWARENESS && eType[*oei] != UNIT_EDGE)
01594 || (ourAwarenessLevel == AwarenessLevel::CONSTANT_AWARENESS && eType[*oei] == VARIABLE_EDGE)) nontrivialEdgeChange_backElimination--;
01595
01596
01597 for (tie(iei, ie_end) = in_edges(target(e, angelLCG), angelLCG); iei != ie_end; ++iei) {
01598 if (*iei == e) continue;
01599 tie(absorb_e, found_absorb_e) = edge(source(*iei, angelLCG), target(*oei, angelLCG), angelLCG);
01600 if (found_absorb_e) {
01601 if (ourAwarenessLevel == AwarenessLevel::UNIT_AWARENESS && eType[absorb_e] == UNIT_EDGE) nontrivialEdgeChange_backElimination++;
01602 else if (ourAwarenessLevel == AwarenessLevel::CONSTANT_AWARENESS && eType[absorb_e] != VARIABLE_EDGE)
01603 if (eType[*oei] == VARIABLE_EDGE || eType[*iei] == VARIABLE_EDGE) nontrivialEdgeChange_backElimination++;
01604 }
01605 else {
01606 if (ourAwarenessLevel == AwarenessLevel::NO_AWARENESS) nontrivialEdgeChange_backElimination++;
01607 else if (ourAwarenessLevel == AwarenessLevel::UNIT_AWARENESS && (eType[*oei] != UNIT_EDGE || eType[*iei] != UNIT_EDGE)) nontrivialEdgeChange_backElimination++;
01608 else if (ourAwarenessLevel == AwarenessLevel::CONSTANT_AWARENESS && (eType[*oei] == VARIABLE_EDGE || eType[*iei] == VARIABLE_EDGE)) nontrivialEdgeChange_backElimination++;
01609 }
01610 }
01611 if (nontrivialEdgeChange_rerouting + nontrivialEdgeChange_backElimination < 0) er.type3EdgeElimVector.push_back(target(*oei, angelLCG));
01612 }
01613
01614 }
01615 else {
01616
01617
01618
01619
01620
01621
01622 if (vertex_type(target(e, angelLCG), angelLCG) != dependent) {
01623
01624 if (!incrementIsTrivial) nontrivialEdgeChange_elimIncrement--;
01625
01626
01627 for (tie (oei, oe_end) = out_edges(target(e, angelLCG), angelLCG); oei != oe_end; ++oei) {
01628 tie (absorb_e, found_absorb_e) = edge(target(pe, angelLCG), target(*oei, angelLCG), angelLCG);
01629 if (found_absorb_e) {
01630 if (ourAwarenessLevel == AwarenessLevel::UNIT_AWARENESS && eType[absorb_e] == UNIT_EDGE) nontrivialEdgeChange_elimIncrement++;
01631 else if (ourAwarenessLevel == AwarenessLevel::CONSTANT_AWARENESS && eType[absorb_e] != VARIABLE_EDGE)
01632 if (eType[*oei] == VARIABLE_EDGE || !incrementIsTrivial) nontrivialEdgeChange_elimIncrement++;
01633 }
01634 else {
01635 if (ourAwarenessLevel == AwarenessLevel::NO_AWARENESS) nontrivialEdgeChange_elimIncrement++;
01636 else if (ourAwarenessLevel == AwarenessLevel::UNIT_AWARENESS && (eType[*oei] != UNIT_EDGE || !incrementIsTrivial)) nontrivialEdgeChange_elimIncrement++;
01637 else if (ourAwarenessLevel == AwarenessLevel::CONSTANT_AWARENESS && (eType[*oei] == VARIABLE_EDGE || !incrementIsTrivial)) nontrivialEdgeChange_elimIncrement++;
01638 }
01639 }
01640 if (nontrivialEdgeChange_rerouting + nontrivialEdgeChange_elimIncrement < 0) er.increment_eliminatable = true;
01641 }
01642
01643
01644
01645
01646
01647
01648 if (out_degree (source(pe, angelLCG), angelLCG) == 2 && in_degree (source(pe, angelLCG), angelLCG) > 0) {
01649
01650
01651 if (ourAwarenessLevel == AwarenessLevel::NO_AWARENESS) nontrivialEdgeChange_elimPivot--;
01652 else if (ourAwarenessLevel == AwarenessLevel::UNIT_AWARENESS && eType[pe] != UNIT_EDGE) nontrivialEdgeChange_elimPivot--;
01653 else if (ourAwarenessLevel == AwarenessLevel::CONSTANT_AWARENESS && eType[pe] == VARIABLE_EDGE) nontrivialEdgeChange_elimPivot--;
01654
01655
01656
01657 for (tie (iei, ie_end) = in_edges(source(pe, angelLCG), angelLCG); iei != ie_end; ++iei) {
01658
01659 if (ourAwarenessLevel == AwarenessLevel::NO_AWARENESS) nontrivialEdgeChange_elimPivot--;
01660 else if (ourAwarenessLevel == AwarenessLevel::UNIT_AWARENESS && eType[*iei] != UNIT_EDGE) nontrivialEdgeChange_elimPivot--;
01661 else if (ourAwarenessLevel == AwarenessLevel::CONSTANT_AWARENESS && eType[*iei] == VARIABLE_EDGE) nontrivialEdgeChange_elimPivot--;
01662
01663 tie (absorb_e, found_absorb_e) = edge (source(*iei, angelLCG), target(pe, angelLCG), angelLCG);
01664 if (found_absorb_e) {
01665 if (ourAwarenessLevel == AwarenessLevel::UNIT_AWARENESS && eType[absorb_e] == UNIT_EDGE) nontrivialEdgeChange_elimPivot++;
01666 else if (ourAwarenessLevel == AwarenessLevel::CONSTANT_AWARENESS && eType[absorb_e] != VARIABLE_EDGE)
01667 if (eType[pe] == VARIABLE_EDGE || eType[*iei] == VARIABLE_EDGE) nontrivialEdgeChange_elimPivot++;
01668 }
01669 else {
01670 if (ourAwarenessLevel == AwarenessLevel::NO_AWARENESS) nontrivialEdgeChange_elimPivot++;
01671 else if (ourAwarenessLevel == AwarenessLevel::UNIT_AWARENESS && (eType[pe] != UNIT_EDGE || eType[*iei] != UNIT_EDGE)) nontrivialEdgeChange_elimPivot++;
01672 else if (ourAwarenessLevel == AwarenessLevel::CONSTANT_AWARENESS && (eType[pe] == VARIABLE_EDGE || eType[*iei] == VARIABLE_EDGE)) nontrivialEdgeChange_elimPivot++;
01673 }
01674
01675 }
01676 if (nontrivialEdgeChange_rerouting + nontrivialEdgeChange_elimPivot < 0) er.pivot_eliminatable = true;
01677 }
01678
01679
01680
01681
01682
01683
01684 if (vertex_type(source(e, angelLCG), angelLCG) != dependent) {
01685 for (tie(iei, ie_end) = in_edges(source(e, angelLCG), angelLCG); iei != ie_end; ++iei) {
01686 int nontrivialEdgeChange_frontElimination = 0;
01687
01688
01689 if (ourAwarenessLevel == AwarenessLevel::NO_AWARENESS
01690 || (ourAwarenessLevel == AwarenessLevel::UNIT_AWARENESS && eType[*iei] != UNIT_EDGE)
01691 || (ourAwarenessLevel == AwarenessLevel::CONSTANT_AWARENESS && eType[*iei] == VARIABLE_EDGE)) nontrivialEdgeChange_frontElimination--;
01692
01693
01694 for (tie(oei, oe_end) = out_edges(source(e, angelLCG), angelLCG); oei != oe_end; ++oei) {
01695 if (*oei == e) continue;
01696 tie(absorb_e, found_absorb_e) = edge(source(*iei, angelLCG), target(*oei, angelLCG), angelLCG);
01697 if (found_absorb_e) {
01698 if (ourAwarenessLevel == AwarenessLevel::UNIT_AWARENESS && eType[absorb_e] == UNIT_EDGE) nontrivialEdgeChange_frontElimination++;
01699 else if (ourAwarenessLevel == AwarenessLevel::CONSTANT_AWARENESS && eType[absorb_e] != VARIABLE_EDGE)
01700 if (eType[*oei] == VARIABLE_EDGE || eType[*iei] == VARIABLE_EDGE) nontrivialEdgeChange_frontElimination++;
01701 }
01702 else {
01703 if (ourAwarenessLevel == AwarenessLevel::NO_AWARENESS) nontrivialEdgeChange_frontElimination++;
01704 else if (ourAwarenessLevel == AwarenessLevel::UNIT_AWARENESS && (eType[*oei] != UNIT_EDGE || eType[*iei] != UNIT_EDGE)) nontrivialEdgeChange_frontElimination++;
01705 else if (ourAwarenessLevel == AwarenessLevel::CONSTANT_AWARENESS && (eType[*oei] == VARIABLE_EDGE || eType[*iei] == VARIABLE_EDGE)) nontrivialEdgeChange_frontElimination++;
01706 }
01707 }
01708 if (nontrivialEdgeChange_rerouting + nontrivialEdgeChange_frontElimination < 0) er.type3EdgeElimVector.push_back(source(*iei, angelLCG));
01709 }
01710 }
01711 }
01712
01713 if (er.pivot_eliminatable || er.increment_eliminatable || !er.type3EdgeElimVector.empty())
01714 reducingReroutingsV.push_back(Rerouting (er, angelLCG));
01715
01716 }
01717
01718 #ifndef NDEBUG
01719 cout << " Of " << erv.size() << " reroutings passed to reducing_reroutings(), " << reducingReroutingsV.size() << " reduce the nontrivial edge count when followed by elimination" << endl;
01720 #endif
01721
01722 return !reducingReroutingsV.empty();
01723 }
01724
01725
01726
01727
01728
01729 int transformation_effect(const Transformation t,
01730 const c_graph_t& angelLCG,
01731 const AwarenessLevel::AwarenessLevel_E ourAwarenessLevel) {
01732 int effect;
01733 if (t.isRerouting()) {
01734 bool dummy_incrementIsTrivial;
01735 effect = reroute_effect(t.getRerouting().getER(angelLCG), angelLCG, ourAwarenessLevel, dummy_incrementIsTrivial);
01736 }
01737 else
01738 effect = edge_elim_effect(t.getEdgeElim(), angelLCG, ourAwarenessLevel);
01739 return effect;
01740 }
01741
01742 bool all_viable_transformations (c_graph_t& angelLCG,
01743 const std::vector<Transformation>& transformationsPerformedV,
01744 vector<Transformation>& allViableTransformationsV) {
01745 allViableTransformationsV.clear();
01746
01747 vector<EdgeElim> allEdgeElimsV;
01748 eliminatable_edges(angelLCG, allEdgeElimsV);
01749 for (size_t i = 0; i < allEdgeElimsV.size(); i++)
01750 allViableTransformationsV.push_back(Transformation (allEdgeElimsV[i]));
01751
01752 vector<Rerouting> allReroutingsV, noncyclicReroutingsV;
01753 reroutable_edges (angelLCG, allReroutingsV);
01754 noncyclicReroutings (allReroutingsV, transformationsPerformedV, angelLCG, noncyclicReroutingsV);
01755 for (size_t i = 0; i < noncyclicReroutingsV.size(); i++)
01756 allViableTransformationsV.push_back(Transformation (noncyclicReroutingsV[i]));
01757 #ifndef NDEBUG
01758 cout << "\tThere are " << allEdgeElimsV.size() << " viable Edge eliminations in G" << endl;
01759 cout << "\tOf " << allReroutingsV.size() << " possible reroutings, " << noncyclicReroutingsV.size() << " are noncyclic" << endl;
01760 cout << "\t\tThere are " << allViableTransformationsV.size() << " viable transformations in G" << endl;
01761 #endif
01762 return !allViableTransformationsV.empty();
01763 }
01764
01765 bool maintaining_transformations(const vector<Transformation>& tv,
01766 const c_graph_t& angelLCG,
01767 const AwarenessLevel::AwarenessLevel_E ourAwarenessLevel,
01768 vector<Transformation>& maintainingTransformationsV) {
01769 maintainingTransformationsV.clear();
01770 if (tv.empty())
01771 return false;
01772
01773 vector<Rerouting> tempReroutingsV;
01774 vector<EdgeElim> tempEdgeElimsV, tempMaintainingEdgeElimsV;
01775
01776
01777 for (size_t i = 0; i < tv.size(); i++)
01778 tv[i].isRerouting() ? tempReroutingsV.push_back(tv[i].getRerouting())
01779 : tempEdgeElimsV.push_back(tv[i].getEdgeElim());
01780
01781
01782 if (maintaining_edge_eliminations(tempEdgeElimsV, angelLCG, ourAwarenessLevel, tempMaintainingEdgeElimsV))
01783 for (size_t i = 0; i < tempMaintainingEdgeElimsV.size(); i++)
01784 maintainingTransformationsV.push_back(Transformation (tempMaintainingEdgeElimsV[i]));
01785
01786
01787 for (size_t i = 0; i < tempReroutingsV.size(); i++)
01788 maintainingTransformationsV.push_back(Transformation (tempReroutingsV[i]));
01789
01790 #ifndef NDEBUG
01791 cout << "Of " << tv.size() << " transformations passed to maintaining_transformations()"
01792 << ", " << maintainingTransformationsV.size() << " maintain the nontrivial edge count" << endl;
01793 #endif
01794
01795
01796 if (maintainingTransformationsV.empty()) {
01797 maintainingTransformationsV = tv;
01798 return false;
01799 }
01800 else return true;
01801 }
01802
01803 bool reducing_transformations(const vector<Transformation>& tv,
01804 const c_graph_t& angelLCG,
01805 const AwarenessLevel::AwarenessLevel_E ourAwarenessLevel,
01806 vector<Transformation>& reducingTransformationsV) {
01807 reducingTransformationsV.clear();
01808 if (tv.empty())
01809 return 0;
01810
01811 vector<Rerouting> tempReroutingsV, tempReducingReroutingsV;
01812 vector<EdgeElim> tempEdgeElimsV, tempReducingEdgeElimsV;
01813
01814
01815 for (size_t i = 0; i < tv.size(); i++)
01816 tv[i].isRerouting() ? tempReroutingsV.push_back(tv[i].getRerouting())
01817 : tempEdgeElimsV.push_back(tv[i].getEdgeElim());
01818
01819
01820 if (reducing_edge_eliminations(tempEdgeElimsV, angelLCG, ourAwarenessLevel, tempReducingEdgeElimsV))
01821 for (size_t i = 0; i < tempReducingEdgeElimsV.size(); i++)
01822 reducingTransformationsV.push_back(Transformation (tempReducingEdgeElimsV[i]));
01823
01824
01825 if (reducing_reroutings(tempReroutingsV, angelLCG, ourAwarenessLevel, tempReducingReroutingsV))
01826 for (size_t i = 0; i < tempReducingReroutingsV.size(); i++)
01827 reducingTransformationsV.push_back(Transformation (tempReducingReroutingsV[i]));
01828
01829 #ifndef NDEBUG
01830 cout << "Of " << tv.size() << " transformations passed to reducing_transformations(), " << reducingTransformationsV.size() << " reduce the nontrivial edge count" << endl;
01831 #endif
01832
01833
01834 if (reducingTransformationsV.empty()) {
01835 for (size_t i = 0; i < tempEdgeElimsV.size(); i++)
01836 reducingTransformationsV.push_back(Transformation (tempEdgeElimsV[i]));
01837
01838 if (reducingTransformationsV.empty()) {
01839 vector<EdgeElim> allEdgeElimsV;
01840 eliminatable_edges(angelLCG, allEdgeElimsV);
01841 for (size_t j = 0; j < allEdgeElimsV.size(); j++)
01842 reducingTransformationsV.push_back(Transformation (allEdgeElimsV[j]));
01843 }
01844 return false;
01845 }
01846
01847
01848
01849
01850
01851
01852 else return true;
01853
01854 }
01855
01856 bool refill_avoiding_transformations(const vector<Transformation>& tv,
01857 c_graph_t& angelLCG,
01858 const AwarenessLevel::AwarenessLevel_E ourAwarenessLevel,
01859 const refillDependenceMap_t& refillDependences,
01860 vector<Transformation>& refillAvoidingTransformationsV) {
01861 refillAvoidingTransformationsV.clear();
01862 if (tv.empty())
01863 return false;
01864
01865 vector<Rerouting> tempReroutingsV;
01866 vector<EdgeElim> tempEdgeElimsV, tempRefillAvoidingEdgeElimsV;
01867
01868
01869 for (size_t i = 0; i < tv.size(); i++)
01870 tv[i].isRerouting() ? tempReroutingsV.push_back(tv[i].getRerouting())
01871 : tempEdgeElimsV.push_back(tv[i].getEdgeElim());
01872
01873
01874 if (refill_avoiding_edge_eliminations(tempEdgeElimsV, angelLCG, refillDependences, tempRefillAvoidingEdgeElimsV)) {
01875
01876 for (size_t i = 0; i < tempRefillAvoidingEdgeElimsV.size(); i++)
01877 refillAvoidingTransformationsV.push_back(Transformation (tempRefillAvoidingEdgeElimsV[i]));
01878
01879 for (size_t i = 0; i < tempReroutingsV.size(); i++)
01880 refillAvoidingTransformationsV.push_back(Transformation (tempReroutingsV[i]));
01881 return true;
01882 }
01883
01884 else {
01885 refillAvoidingTransformationsV = tv;
01886 return false;
01887 }
01888 }
01889
01890 bool rerouting_considerate_transformations(const vector<Transformation>& tv,
01891 const c_graph_t& angelLCG,
01892 const std::vector<Transformation>& transformationsPerformedV,
01893 vector<Transformation>& reroutingConsiderateTransformationsV) {
01894 reroutingConsiderateTransformationsV.clear();
01895 if (tv.empty())
01896 return false;
01897
01898 vector<Transformation> tempReroutingsV;
01899 vector<EdgeElim> tempEdgeElimsV, tempReroutingConsiderateEdgeElimsV;
01900
01901
01902 for (size_t i = 0; i < tv.size(); i++)
01903 tv[i].isRerouting() ? tempReroutingsV.push_back(tv[i].getRerouting())
01904 : tempEdgeElimsV.push_back(tv[i].getEdgeElim());
01905
01906
01907 if (rerouting_considerate_edge_eliminations(tempEdgeElimsV, angelLCG, transformationsPerformedV, tempReroutingConsiderateEdgeElimsV)) {
01908
01909 for (size_t i = 0; i < tempReroutingConsiderateEdgeElimsV.size(); i++)
01910 reroutingConsiderateTransformationsV.push_back(Transformation (tempReroutingConsiderateEdgeElimsV[i]));
01911
01912 for (size_t i = 0; i < tempReroutingsV.size(); i++)
01913 reroutingConsiderateTransformationsV.push_back(Transformation (tempReroutingsV[i]));
01914 return true;
01915 }
01916
01917 else {
01918 reroutingConsiderateTransformationsV = tv;
01919 return false;
01920 }
01921 }
01922
01923 bool lowest_markowitz_transformations(const vector<Transformation>& tv,
01924 const c_graph_t& angelLCG,
01925 vector<Transformation>& lowestMarkowitzTransformationsV) {
01926 lowestMarkowitzTransformationsV.clear();
01927 if (tv.empty())
01928 return false;
01929
01930 vector<EdgeElim> tempEdgeElimsV, tempLowestMarkowitzEdgeElimsV;
01931 for (size_t i = 0; i < tv.size(); i++)
01932 if (!tv[i].isRerouting())
01933 tempEdgeElimsV.push_back(tv[i].getEdgeElim());
01934
01935 if (tempEdgeElimsV.empty()) {
01936 lowestMarkowitzTransformationsV = tv;
01937 return false;
01938 }
01939 lowestMarkowitzEdgeElim(tempEdgeElimsV, angelLCG, tempLowestMarkowitzEdgeElimsV);
01940
01941 for (size_t i = 0; i < tempLowestMarkowitzEdgeElimsV.size(); i++)
01942 lowestMarkowitzTransformationsV.push_back(Transformation (tempLowestMarkowitzEdgeElimsV[i]));
01943 return true;
01944 }
01945
01946 bool reverse_mode_transformations(const vector<Transformation>& tv,
01947 const c_graph_t& angelLCG,
01948 vector<Transformation>& reverseModeTransformationsV) {
01949 reverseModeTransformationsV.clear();
01950 if (tv.empty())
01951 return false;
01952
01953 vector<EdgeElim> tempEdgeElimsV, tempReverseModeEdgeElimsV;
01954 for (size_t i = 0; i < tv.size(); i++)
01955 if (!tv[i].isRerouting())
01956 tempEdgeElimsV.push_back(tv[i].getEdgeElim());
01957
01958 if (tempEdgeElimsV.empty()) {
01959 reverseModeTransformationsV = tv;
01960 return false;
01961 }
01962 reverseModeEdgeElim(tempEdgeElimsV, angelLCG, tempReverseModeEdgeElimsV);
01963
01964 for (size_t i = 0; i < tempReverseModeEdgeElimsV.size(); i++)
01965 reverseModeTransformationsV.push_back(Transformation (tempReverseModeEdgeElimsV[i]));
01966 return true;
01967 }
01968
01969 #endif // USEXAIFBOOSTER
01970
01971 }
01972
01973