00001 #ifndef _heuristics_include_
00002 #define _heuristics_include_
00003
00004 #include <vector>
00005
00006 #include "angel_types.hpp"
00007 #include "angel_io.hpp"
00008 #include "eliminations.hpp"
00009
00010 #ifdef USE_MPI
00011 #include "gmpi.hpp"
00012 #include "angel_comm.hpp"
00013 #endif // USE_MPI
00014
00015 #ifdef USEXAIFBOOSTER
00016 #include "reroutings.hpp"
00017 #endif // USEXAIFBOOSTER
00018
00019 namespace angel {
00020
00021 using std::vector;
00022
00023
00024
00025
00026
00027 template <class Objective_t= int>
00028 class base_heuristic_t {
00029 protected:
00030 Objective_t my_objective;
00031 bool is_set;
00032 bool my_maximize;
00033 public:
00034 typedef Objective_t objective_t;
00035 base_heuristic_t (bool _m) : is_set (false), my_maximize (_m) {}
00036 Objective_t objective() const {
00037 THROW_DEBUG_EXCEPT_MACRO (!is_set, consistency_exception, "objective not set"); return my_objective;}
00038 void set_objective (Objective_t o) {
00039 is_set= true; my_objective= o; }
00040 void set_empty_objective () {
00041 is_set= true;
00042 my_objective= my_maximize ? std::numeric_limits<Objective_t>::min()
00043 : std::numeric_limits<Objective_t>::max(); }
00044 bool to_maximize() const {return my_maximize;}
00045 };
00046
00047 template <class Object_t, class Ad_graph_t, class Op_t, class Objective_t>
00048 int standard_heuristic_op (const vector<Object_t>& v1, const Ad_graph_t& adg,
00049 vector<Object_t>& v2, Op_t op, base_heuristic_t<Objective_t>& h);
00050
00051
00052
00053
00054
00064 class forward_mode_vertex_t : public base_heuristic_t<int> {
00065 public:
00066 forward_mode_vertex_t () : base_heuristic_t<int> (false) {}
00067 int operator() (const vector<c_graph_t::vertex_t>& vv1,
00068 const c_graph_t& cg,
00069 vector<c_graph_t::vertex_t>& vv2);
00070 };
00071
00078 extern forward_mode_vertex_t forward_mode_vertex;
00079
00080
00081
00082
00083
00090 class reverse_mode_vertex_t : public base_heuristic_t<int> {
00091 public:
00092 reverse_mode_vertex_t () : base_heuristic_t<int> (true) {}
00093 int operator() (const vector<c_graph_t::vertex_t>& vv1,
00094 const c_graph_t& cg,
00095 vector<c_graph_t::vertex_t>& vv2);
00096 };
00097
00104 extern reverse_mode_vertex_t reverse_mode_vertex;
00105
00106
00107
00108
00109
00116 class lowest_markowitz_vertex_t : public base_heuristic_t<int> {
00117 public:
00118 lowest_markowitz_vertex_t () : base_heuristic_t<int> (false) {}
00119 int operator() (const vector<c_graph_t::vertex_t>& vv1,
00120 const c_graph_t& cg,
00121 vector<c_graph_t::vertex_t>& vv2);
00122 };
00123
00130 extern lowest_markowitz_vertex_t lowest_markowitz_vertex;
00131
00132
00133
00134
00135
00142 class lowest_relative_markowitz_vertex_t : public base_heuristic_t<int> {
00143 public:
00144 lowest_relative_markowitz_vertex_t () : base_heuristic_t<int> (false) {}
00145 int operator() (const vector<c_graph_t::vertex_t>& vv1,
00146 const c_graph_t& cg,
00147 vector<c_graph_t::vertex_t>& vv2);
00148 };
00149
00156 extern lowest_relative_markowitz_vertex_t lowest_relative_markowitz_vertex;
00157
00158
00159
00160
00161
00168 class lowest_fill_in_vertex_t : public base_heuristic_t<int> {
00169 public:
00170 lowest_fill_in_vertex_t () : base_heuristic_t<int> (false) {}
00171 int operator() (const vector<c_graph_t::vertex_t>& vv1,
00172 const c_graph_t& cg,
00173 vector<c_graph_t::vertex_t>& vv2);
00174 };
00175
00182 extern lowest_fill_in_vertex_t lowest_fill_in_vertex;
00183
00184
00185
00186
00187
00194 class lmmd_vertex_t : public base_heuristic_t<int> {
00195 double weight;
00196 public:
00198 lmmd_vertex_t (double w) : base_heuristic_t<int> (false), weight (w) {}
00205 int operator() (const vector<c_graph_t::vertex_t>& vv1,
00206 const c_graph_t& cg,
00207 vector<c_graph_t::vertex_t>& vv2);
00208 };
00209
00210
00216 extern lmmd_vertex_t lmmd_vertex;
00217
00218
00219
00220
00221
00226 class momr_vertex_t : public base_heuristic_t<int> {
00227 public:
00228 momr_vertex_t () : base_heuristic_t<int> (true) {}
00235 int operator() (const vector<c_graph_t::vertex_t>& vv1,
00236 const c_graph_t& cg,
00237 vector<c_graph_t::vertex_t>& vv2);
00238 };
00239
00241 extern momr_vertex_t momr_vertex;
00242
00243
00244
00245
00246
00253 class moplr_vertex_t : public base_heuristic_t<int> {
00254 public:
00255 moplr_vertex_t () : base_heuristic_t<int> (true) {}
00256 int operator() (const vector<c_graph_t::vertex_t>& vv1,
00257 const c_graph_t& cg,
00258 vector<c_graph_t::vertex_t>& vv2);
00259 };
00260
00267 extern moplr_vertex_t moplr_vertex;
00268
00269
00270
00271
00272
00286 int forward_mode_edge_f (const vector<c_graph_t::edge_t>& ev1,
00287 bool front,
00288 const c_graph_t& cg,
00289 vector<c_graph_t::edge_t>& ev2);
00290
00301 inline int forward_mode_edge_front (const vector<c_graph_t::edge_t>& ev1,
00302 const c_graph_t& cg,
00303 vector<c_graph_t::edge_t>& ev2) {
00304 return forward_mode_edge_f (ev1, true, cg, ev2);
00305 }
00306
00316 inline int forward_mode_edge_back (const vector<c_graph_t::edge_t>& ev1,
00317 const c_graph_t& cg,
00318 vector<c_graph_t::edge_t>& ev2) {
00319 return forward_mode_edge_f (ev1, false, cg, ev2);
00320 }
00321
00330 class forward_mode_edge_t : public base_heuristic_t<double> {
00331 public:
00332 forward_mode_edge_t () : base_heuristic_t<double> (false) {}
00333 int operator() (const vector<edge_bool_t>& ev1,
00334 const c_graph_t& cg,
00335 vector<edge_bool_t>& ev2);
00336 };
00337
00349 extern forward_mode_edge_t forward_mode_edge;
00350
00351
00352
00353
00354
00368 int reverse_mode_edge_f (const vector<c_graph_t::edge_t>& ev1,
00369 bool front,
00370 const c_graph_t& cg,
00371 vector<c_graph_t::edge_t>& ev2);
00372
00381 inline int reverse_mode_edge_front (const vector<c_graph_t::edge_t>& ev1,
00382 const c_graph_t& cg,
00383 vector<c_graph_t::edge_t>& ev2) {
00384 return reverse_mode_edge_f (ev1, true, cg, ev2);
00385 }
00386
00395 inline int reverse_mode_edge_back (const vector<c_graph_t::edge_t>& ev1,
00396 const c_graph_t& cg,
00397 vector<c_graph_t::edge_t>& ev2) {
00398 return reverse_mode_edge_f (ev1, false, cg, ev2);
00399 }
00400
00409 class reverse_mode_edge_t : public base_heuristic_t<double> {
00410 public:
00411 reverse_mode_edge_t () : base_heuristic_t<double> (false) {}
00412 int operator() (const vector<edge_bool_t>& ev1,
00413 const c_graph_t& cg,
00414 vector<edge_bool_t>& ev2);
00415 };
00416
00428 extern reverse_mode_edge_t reverse_mode_edge;
00429
00430
00431
00432
00433
00448 int lowest_markowitz_edge_f (const vector<c_graph_t::edge_t>& ev1,
00449 bool front,
00450 const c_graph_t& cg,
00451 vector<c_graph_t::edge_t>& ev2);
00452
00453
00462 inline int lowest_markowitz_edge_front (const vector<c_graph_t::edge_t>& ev1,
00463 const c_graph_t& cg,
00464 vector<c_graph_t::edge_t>& ev2) {
00465 return lowest_markowitz_edge_f (ev1, true, cg, ev2);
00466 }
00467
00468
00477 inline int lowest_markowitz_edge_back (const vector<c_graph_t::edge_t>& ev1,
00478 const c_graph_t& cg,
00479 vector<c_graph_t::edge_t>& ev2) {
00480 return lowest_markowitz_edge_f (ev1, false, cg, ev2);
00481 }
00482
00491 class lowest_markowitz_edge_t : public base_heuristic_t<int> {
00492 public:
00493 lowest_markowitz_edge_t () : base_heuristic_t<int> (false) {}
00494 int operator() (const vector<edge_bool_t>& ev1,
00495 const c_graph_t& cg,
00496 vector<edge_bool_t>& ev2);
00497 };
00498
00505 extern lowest_markowitz_edge_t lowest_markowitz_edge;
00506
00507
00508
00509
00510
00525 int lowest_relative_markowitz_edge_f (const vector<c_graph_t::edge_t>& ev1,
00526 bool front,
00527 const c_graph_t& cg,
00528 vector<c_graph_t::edge_t>& ev2);
00529
00538 inline int lowest_relative_markowitz_edge_front (const vector<c_graph_t::edge_t>& ev1,
00539 const c_graph_t& cg,
00540 vector<c_graph_t::edge_t>& ev2) {
00541 return lowest_relative_markowitz_edge_f (ev1, true, cg, ev2);
00542 }
00543
00552 inline int lowest_relative_markowitz_edge_back (const vector<c_graph_t::edge_t>& ev1,
00553 const c_graph_t& cg,
00554 vector<c_graph_t::edge_t>& ev2) {
00555 return lowest_relative_markowitz_edge_f (ev1, false, cg, ev2);
00556 }
00557
00558
00567 class lowest_relative_markowitz_edge_t : public base_heuristic_t<int> {
00568 public:
00569 lowest_relative_markowitz_edge_t () : base_heuristic_t<int> (false) {}
00570 int operator() (const vector<edge_bool_t>& ev1,
00571 const c_graph_t& cg,
00572 vector<edge_bool_t>& ev2);
00573 };
00574
00581 extern lowest_relative_markowitz_edge_t lowest_relative_markowitz_edge;
00582
00583
00584
00585
00586
00598 int lowest_fill_in_edge_f (const vector<c_graph_t::edge_t>& ev1,
00599 bool front,
00600 const c_graph_t& cg,
00601 vector<c_graph_t::edge_t>& ev2);
00602
00611 inline int lowest_fill_in_edge_front (const vector<c_graph_t::edge_t>& ev1,
00612 const c_graph_t& cg,
00613 vector<c_graph_t::edge_t>& ev2) {
00614 return lowest_fill_in_edge_f (ev1, true, cg, ev2);
00615 }
00616
00625 inline int lowest_fill_in_edge_back (const vector<c_graph_t::edge_t>& ev1,
00626 const c_graph_t& cg,
00627 vector<c_graph_t::edge_t>& ev2) {
00628 return lowest_fill_in_edge_f (ev1, false, cg, ev2);
00629 }
00630
00631
00632
00633
00634
00635
00643 class lmmd_edge_t : public base_heuristic_t<int> {
00644 double weight;
00645 public:
00647 lmmd_edge_t (double w) : base_heuristic_t<int> (false), weight (w) {}
00654 int operator() (const vector<edge_bool_t>& ev1,
00655 const c_graph_t& cg,
00656 vector<edge_bool_t>& ev2);
00657 };
00658
00664 extern lmmd_edge_t lmmd_edge;
00665
00666
00667
00668
00669
00685 int momr_edge_f (const vector<c_graph_t::edge_t>& ev1,
00686 bool front,
00687 const c_graph_t& cg,
00688 vector<c_graph_t::edge_t>& ev2);
00689
00698 inline int momr_edge_front (const vector<c_graph_t::edge_t>& ev1,
00699 const c_graph_t& cg,
00700 vector<c_graph_t::edge_t>& ev2) {
00701 return momr_edge_f (ev1, true, cg, ev2);
00702 }
00703
00712 inline int momr_edge_back (const vector<c_graph_t::edge_t>& ev1,
00713 const c_graph_t& cg,
00714 vector<c_graph_t::edge_t>& ev2) {
00715 return momr_edge_f (ev1, false, cg, ev2);
00716 }
00717
00726 class momr_edge_t : public base_heuristic_t<int> {
00727 public:
00728 momr_edge_t () : base_heuristic_t<int> (true) {}
00729 int operator() (const vector<edge_bool_t>& ev1, const c_graph_t& cg,
00730 vector<edge_bool_t>& ev2);
00731 };
00732
00739 extern momr_edge_t momr_edge;
00740
00741
00742
00743
00744
00749 class minimal_distance_edge_t : public base_heuristic_t<int> {
00750 public:
00751 minimal_distance_edge_t () : base_heuristic_t<int> (false) {}
00752 int operator() (const vector<edge_bool_t>& ev1, const c_graph_t& cg,
00753 vector<edge_bool_t>& ev2);
00754 };
00755
00756
00757
00758
00759
00767 int moplr_edge (const vector<c_graph_t::edge_t>& ev1,
00768 bool front,
00769 const c_graph_t& cg,
00770 vector<c_graph_t::edge_t>& ev2);
00771
00772
00773
00774
00775
00776
00777
00778
00779
00780
00781
00788 class forward_mode_face_t : public base_heuristic_t<double> {
00789 public:
00790 forward_mode_face_t () : base_heuristic_t<double> (false) {}
00791 int operator() (const vector<line_graph_t::face_t>& fv1,
00792 const line_graph_t& lg,
00793 vector<line_graph_t::face_t>& fv2);
00794 };
00795
00809 extern forward_mode_face_t forward_mode_face;
00810
00811
00812
00813
00814
00821 class reverse_mode_face_t : public base_heuristic_t<double> {
00822 public:
00823 reverse_mode_face_t () : base_heuristic_t<double> (true) {}
00824 int operator() (const vector<line_graph_t::face_t>& fv1,
00825 const line_graph_t& lg,
00826 vector<line_graph_t::face_t>& fv2);
00827 };
00828
00842 extern reverse_mode_face_t reverse_mode_face;
00843
00850 class reverse_mode_face_whole_vertex_t : base_heuristic_t<int> {
00851 public:
00852 reverse_mode_face_whole_vertex_t () : base_heuristic_t<int> (false) {}
00853 int operator() (const vector<line_graph_t::face_t>& fv1,
00854 const line_graph_t& lg,
00855 vector<line_graph_t::face_t>& fv2);
00856 };
00857
00868 extern reverse_mode_face_whole_vertex_t reverse_mode_face_whole_vertex;
00869
00870
00871
00872
00873
00874 class lowest_markowitz_face_t : public base_heuristic_t<int> {
00875 public:
00876 lowest_markowitz_face_t () : base_heuristic_t<int> (false) {}
00877 int operator() (const vector<line_graph_t::face_t>& fv1,
00878 const line_graph_t& lg,
00879 vector<line_graph_t::face_t>& fv2);
00880 };
00881
00899 extern lowest_markowitz_face_t lowest_markowitz_face;
00900
00901
00902
00903
00904
00905
00906
00907
00908
00909
00910
00911
00912
00913
00914
00915
00916
00917
00918 void markowitz_on_line_graph (const line_graph_t& lg, vector<int>& mdegree);
00919
00931 template <class Heuristic_t>
00932 class lowest_markowitz_face_complete_t : public base_heuristic_t<int> {
00933 int lastv;
00934 Heuristic_t tiebreaker;
00935 public:
00937 lowest_markowitz_face_complete_t (Heuristic_t t) :
00938 base_heuristic_t<int> (false), lastv (-1), tiebreaker (t) {}
00939
00946 int operator() (const vector<line_graph_t::face_t>& fv1,
00947 const line_graph_t& lg,
00948 vector<line_graph_t::face_t>& fv2);
00949 };
00950
00951
00952
00953
00954
00961 class momr_face_t : public base_heuristic_t<int> {
00962 public:
00963 momr_face_t () : base_heuristic_t<int> (true) {}
00964 int operator() (const vector<line_graph_t::face_t>& fv1,
00965 const line_graph_t& lg,
00966 vector<line_graph_t::face_t>& fv2);
00967 };
00968
00979 extern momr_face_t momr_face;
00980
00981
00982
00983
00984
00996 class minimal_distance_face_t : public base_heuristic_t<int> {
00997 public:
00998 minimal_distance_face_t () : base_heuristic_t<int> (false) {}
00999 int operator() (const vector<line_graph_t::face_t>& fv1, const line_graph_t& lg,
01000 vector<line_graph_t::face_t>& fv2);
01001 };
01002
01003
01004
01005
01006
01008 template <class Edge_heuristic_t>
01009 class edge_ij_elim_heuristic_t {
01010 Edge_heuristic_t h;
01011 public:
01013 edge_ij_elim_heuristic_t (Edge_heuristic_t _h) : h (_h) {}
01014 int operator() (const vector<edge_ij_elim_t>& eev1,
01015 const c_graph_t& cg,
01016 vector<edge_ij_elim_t>& eev2) {
01017 vector<edge_bool_t> ebv1, ebv2;
01018 for (size_t c= 0; c < eev1.size(); c++) {
01019 c_graph_t::edge_t edge; bool found;
01020 tie (edge, found)= angel::edge (eev1[c].i, eev1[c].j, cg);
01021 if (found) ebv1.push_back (std::make_pair (edge, eev1[c].front)); }
01022 h (ebv1, cg, ebv2);
01023 eev2.resize (0);
01024 for (size_t c= 0; c < ebv2.size(); c++) {
01025 edge_ij_elim_t ee (source (ebv2[c].first, cg),
01026 target (ebv2[c].first, cg), ebv2[c].second);
01027 eev2.push_back (ee); }
01028 return eev2.size();
01029 }
01030 };
01031
01032
01033
01034
01035
01036
01041 template <class Face_heuristic_t>
01042 class triplet_heuristic_t {
01043 Face_heuristic_t h;
01044 public:
01046 triplet_heuristic_t (Face_heuristic_t _h) : h (_h) {}
01047 int operator() (const vector<triplet_t>& tv1,
01048 const line_graph_t& lg,
01049 vector<triplet_t>& tv2) {
01050 vector<line_graph_t::face_t> fv1, fv2;
01051 for (size_t c= 0; c < tv1.size(); c++) {
01052 line_graph_t::face_t face; bool found;
01053 tie (face, found)= angel::edge (tv1[c].i, tv1[c].j, lg);
01054 if (found) fv1.push_back (face); }
01055 h (fv1, lg, fv2);
01056 tv2.resize (0);
01057 for (size_t c= 0, tc= 0; c < fv2.size(); c++) {
01058 int s= source (fv2[c], lg), t= target (fv2[c], lg);
01059 for (; s != tv1[tc].i || t != tv1[tc].j; tc++);
01060 tv2.push_back (tv1[tc]); }
01061 return tv2.size();
01062 }
01063 };
01064
01073 template <class Vertex_heuristic_t>
01074 class emulated_vertex_heuristic_t {
01075 Vertex_heuristic_t h;
01076 c_graph_t::vertex_t last_vertex;
01077 public:
01079 emulated_vertex_heuristic_t (Vertex_heuristic_t _h) : h (_h), last_vertex (0) {}
01080 int operator() (const vector<edge_ij_elim_t>& tv1, const c_graph_t& cg,
01081 vector<edge_ij_elim_t>& tv2);
01082 };
01083
01084
01085
01086
01087
01088
01099 template <class Heuristic1_t, class Heuristic2_t>
01100 class heuristic_pair_t {
01101 private:
01102 Heuristic1_t h1;
01103 Heuristic2_t h2;
01104 public:
01106 heuristic_pair_t (Heuristic1_t _h1, Heuristic2_t _h2):
01107 h1 (_h1), h2 (_h2) {}
01109 template <class Vector_t, class Ad_graph_t>
01110 int operator() (const Vector_t& v1, const Ad_graph_t& adg, Vector_t& v2) {
01111 Vector_t vt; h1 (v1, adg, vt); return h2 (vt, adg, v2); }
01112 };
01113
01120 template <class Heuristic1_t, class Heuristic2_t, class Heuristic3_t>
01121 class heuristic_triplet_t {
01122 private:
01123 Heuristic1_t h1;
01124 Heuristic2_t h2;
01125 Heuristic3_t h3;
01126 public:
01127 heuristic_triplet_t (Heuristic1_t _h1, Heuristic2_t _h2, Heuristic3_t _h3):
01128 h1 (_h1), h2 (_h2), h3 (_h3) {}
01129
01130 template <class Vector_t, class Ad_graph_t>
01131 int operator() (const Vector_t& v1, const Ad_graph_t& adg, Vector_t& v2) {
01132 Vector_t vt1, vt2; h1 (v1, adg, vt1); h2 (vt1, adg, vt2);
01133 return h3 (vt2, adg, v2);}
01134 };
01135
01136
01137
01138
01139
01154 template <class Object_t, class Ad_graph_t, class Heuristic_t>
01155 inline int use_heuristic (const Ad_graph_t& adg, vector<Object_t>& el_seq,
01156 Heuristic_t h) {
01157 Ad_graph_t adg_copy (adg);
01158 vector<Object_t> v1;
01159 eliminatable_objects (adg_copy, v1);
01160 int costs= 0;
01161 el_seq.resize (0);
01162
01163 while (!v1.empty()) {
01164 vector<Object_t> v2;
01165 h (v1, adg_copy, v2);
01166 Object_t o= v2[0];
01167 costs+= eliminate (o, adg_copy);
01168 el_seq.push_back (o);
01169 eliminatable_objects (adg_copy, v1);
01170 }
01171 return costs;
01172 }
01173
01186 template <class Object_t, class Ad_graph_t, class Heuristic_t>
01187 inline int use_heuristic_noconst (Ad_graph_t& adg, vector<Object_t>& el_seq,
01188 Heuristic_t h) {
01189 Ad_graph_t& adg_copy (adg);
01190 vector<Object_t> v1;
01191 eliminatable_objects (adg_copy, v1);
01192 int costs= 0;
01193 el_seq.resize (0);
01194
01195 while (!v1.empty()) {
01196 vector<Object_t> v2;
01197 h (v1, adg_copy, v2);
01198 Object_t o= v2[0];
01199 costs+= eliminate (o, adg_copy);
01200 el_seq.push_back (o);
01201 eliminatable_objects (adg_copy, v1);
01202 }
01203 return costs;
01204 }
01205
01216 template <class Object_t, class Ad_graph_t, class Heuristic_t>
01217 inline int use_heuristic_debug (const Ad_graph_t& adg, vector<Object_t>& el_seq,
01218 Heuristic_t h) {
01219
01220 Ad_graph_t adg_copy;
01221 write_graph ("\nuse_heuristic_debug: passed graph", adg);
01222 cout << "edges are ";
01223 typename Ad_graph_t::edge_iterator ei, e_end;
01224 for (tie (ei, e_end)= edges (adg); ei != e_end; ++ei)
01225 cout << '(' << source (*ei, adg) << ", " << target (*ei, adg) << "), ";
01226 cout << "\n";
01227
01228 write_graph ("\nuse_heuristic_debug: copied graph", adg_copy);
01229 adg_copy= adg;
01230 write_graph ("\nuse_heuristic_debug: copied graph", adg_copy);
01231 vector<Object_t> v1;
01232 eliminatable_objects (adg_copy, v1);
01233 int costs= 0;
01234 el_seq.resize (0);
01235
01236 while (!v1.empty()) {
01237 write_vector ("use_heuristic_debug: eliminatable objects", v1);
01238 vector<Object_t> v2;
01239 h (v1, adg_copy, v2);
01240 write_vector ("use_heuristic_debug: selected objects", v2);
01241 Object_t o= v2[0];
01242 costs+= eliminate (o, adg_copy);
01243 write_graph ("use_heuristic_debug: resulting graph", adg_copy);
01244 el_seq.push_back (o);
01245 eliminatable_objects (adg_copy, v1);
01246 }
01247 return costs;
01248 }
01249
01250
01262 template <class Object_t, class Ad_graph_t, class Heuristic_t, class Output_t>
01263 inline int use_heuristic_trace (const Ad_graph_t& adg, vector<Object_t>& el_seq,
01264 Heuristic_t h, Output_t output) {
01265 Ad_graph_t adg_copy (adg);
01266 vector<Object_t> v1;
01267 eliminatable_objects (adg_copy, v1);
01268 int costs= 0;
01269 el_seq.resize (0);
01270
01271 while (!v1.empty()) {
01272 vector<Object_t> v2;
01273 h (v1, adg_copy, v2);
01274 Object_t o= v2[0];
01275 int ocosts= eliminate (o, adg_copy);
01276 costs+= ocosts;
01277 output (cout, o);
01278 cout << " costs " << ocosts << " --> overall " << costs << endl;
01279 el_seq.push_back (o);
01280 eliminatable_objects (adg_copy, v1);
01281 }
01282 return costs;
01283 }
01284
01298 template <class Object_t, class Ad_graph_t, class Heuristic_t, class Output_t>
01299 inline int apply_heuristic (const Ad_graph_t& adg, vector<Object_t>& el_seq,
01300 Heuristic_t h, Output_t output) {
01301 Ad_graph_t adg_copy (adg);
01302 vector<Object_t> v1;
01303 eliminatable_objects (adg_copy, v1);
01304 output.write_graph ("Original graph", adg_copy);
01305 int costs= 0, iteration= 0;
01306 el_seq.resize (0);
01307
01308 while (!v1.empty()) {
01309 vector<Object_t> v2;
01310 h (v1, adg_copy, v2);
01311 Object_t o= v2[0];
01312 int ocosts= eliminate (o, adg_copy);
01313 costs+= ocosts;
01314 output << "Elimination of " << o << " costs " << ocosts << " --> overall " << costs << '\n';
01315 std::ostringstream gtext; gtext << "Graph after " << ++iteration << "iterations\n";
01316 output.write_graph (gtext.str(), adg_copy);
01317 el_seq.push_back (o);
01318 eliminatable_objects (adg_copy, v1);
01319 }
01320 return costs;
01321 }
01322
01324 template <class Object_t, class Ad_graph_t, class Heuristic1_t, class Heuristic2_t,
01325 class Heuristic3_t, class Heuristic4_t, class Heuristic5_t>
01326 inline int best_heuristic (const Ad_graph_t& adg, vector<Object_t>& el_seq,
01327 Heuristic1_t h1, Heuristic2_t h2, Heuristic3_t h3,
01328 Heuristic4_t h4, Heuristic5_t h5);
01329
01330
01331
01332
01333
01335 template <class Object_t, class Ad_graph_t, class Op_t>
01336 int find_best_subset (const vector<Object_t>& v1, const Ad_graph_t& adg,
01337 vector<Object_t>& v2, Op_t op, bool maximize) {
01338 v2.resize (0);
01339
01340 if (v1.size() == 0) return 0;
01341 int best= maximize ? -op (v1[0], adg) : op (v1[0], adg);
01342 v2.push_back (v1[0]);
01343
01344 for (size_t c= 1; c < v1.size(); c++) {
01345 Object_t o= v1[c];
01346 int value= maximize ? -op (o, adg) : op (o, adg);
01347 if (value < best) v2.resize (0);
01348 if (value <= best) {
01349 v2.push_back (o); best= value;}
01350 }
01351 return v2.size();
01352 }
01353
01354 #ifdef USEXAIFBOOSTER
01355
01356
01357
01358
01359
01367 int edge_elim_effect (const edge_bool_t be,
01368 const c_graph_t& angelLCG,
01369 const xaifBoosterCrossCountryInterface::AwarenessLevel::AwarenessLevel_E ourAwarenessLevel);
01370
01378 int edge_elim_effect(const EdgeElim ee,
01379 const c_graph_t& angelLCG,
01380 const xaifBoosterCrossCountryInterface::AwarenessLevel::AwarenessLevel_E ourAwarenessLevel);
01381
01390 bool maintaining_edge_eliminations(const vector<EdgeElim>& bev1,
01391 const c_graph_t& angelLCG,
01392 const xaifBoosterCrossCountryInterface::AwarenessLevel::AwarenessLevel_E ourAwarenessLevel,
01393 vector<EdgeElim>& bev2);
01394
01403 bool reducing_edge_eliminations(const vector<EdgeElim>& bev1,
01404 const c_graph_t& angelLCG,
01405 const xaifBoosterCrossCountryInterface::AwarenessLevel::AwarenessLevel_E ourAwarenessLevel,
01406 vector<EdgeElim>& bev2);
01407
01418 bool refill_avoiding_edge_eliminations(const vector<EdgeElim>& bev1,
01419 c_graph_t& angelLCG,
01420 const refillDependenceMap_t refillDependences,
01421 vector<EdgeElim>& bev2);
01422
01426 bool rerouting_considerate_edge_eliminations(const vector<EdgeElim>& bev,
01427 const c_graph_t& angelLCG,
01428 const std::vector<Transformation>& transformationsPerformedV,
01429 vector<EdgeElim>& reroutingConsiderateEdgeElimsV);
01430
01431 unsigned int lowestMarkowitzEdgeElim(const vector<EdgeElim>& inEEV,
01432 const c_graph_t& angelLCG,
01433 vector<EdgeElim>& outEEV);
01434
01435 bool reverseModeEdgeElim(const vector<EdgeElim>& inEEV,
01436 const c_graph_t& angelLCG,
01437 vector<EdgeElim>& outEEV);
01438
01439
01440
01441
01442
01446 size_t noncyclicReroutings(const vector<Rerouting>& erv,
01447 const std::vector<Transformation>& transformationsPerformedV,
01448 const c_graph_t& angelLCG,
01449 vector<Rerouting>& noncyclicReroutingsV);
01450
01451
01452
01453
01454
01455
01456
01460 bool reducing_reroutings (const vector<Rerouting>& erv,
01461 const c_graph_t& angelLCG,
01462 const xaifBoosterCrossCountryInterface::AwarenessLevel::AwarenessLevel_E ourAwarenessLevel,
01463 vector<Rerouting>& reducingReroutingsV);
01464
01465
01466
01467
01468
01472 int transformation_effect(const Transformation t,
01473 const c_graph_t& angelLCG,
01474 const xaifBoosterCrossCountryInterface::AwarenessLevel::AwarenessLevel_E ourAwarenessLevel);
01475
01479 bool all_viable_transformations(c_graph_t& angelLCG,
01480 const std::vector<Transformation>& transformationsPerformedV,
01481 vector<Transformation>& allViableTransformationsV);
01482
01486 bool maintaining_transformations(const vector<Transformation>& tv,
01487 const c_graph_t& angelLCG,
01488 const xaifBoosterCrossCountryInterface::AwarenessLevel::AwarenessLevel_E ourAwarenessLevel,
01489 vector<Transformation>& maintainingTransformationsV);
01490
01495 bool reducing_transformations(const vector<Transformation>& tv,
01496 const c_graph_t& angelLCG,
01497 const xaifBoosterCrossCountryInterface::AwarenessLevel::AwarenessLevel_E ourAwarenessLevel,
01498 vector<Transformation>& reducingTransformationsV);
01499
01503 bool refill_avoiding_transformations(const vector<Transformation>& tv,
01504 c_graph_t& angelLCG,
01505 const xaifBoosterCrossCountryInterface::AwarenessLevel::AwarenessLevel_E ourAwarenessLevel,
01506 const refillDependenceMap_t& refillDependences,
01507 vector<Transformation>& refillAvoidingTransformationsV);
01508
01512 bool rerouting_considerate_transformations(const vector<Transformation>& tv,
01513 const c_graph_t& angelLCG,
01514 const std::vector<Transformation>& transformationsPerformedV,
01515 vector<Transformation>& reroutingConsiderateTransformationsV);
01516
01520 bool lowest_markowitz_transformations(const vector<Transformation>& tv,
01521 const c_graph_t& angelLCG,
01522 vector<Transformation>& lowestMarkowitzTransformationsV);
01523
01527 bool reverse_mode_transformations (const vector<Transformation>& tv,
01528 const c_graph_t& angelLCG,
01529 vector<Transformation>& reverseModeTransformationsV);
01530
01531 #endif // USEXAIFBOOSTER
01532
01533 #ifdef USE_MPI
01535 template <class Heuristic_t, class Comm_t>
01536 class par_heuristic_t {
01537 Heuristic_t h;
01538 Comm_t comm;
01539 public:
01541 par_heuristic_t (Heuristic_t _h, Comm_t _comm) : h (_h), comm (_comm) {}
01542 template <class Vector_t, class Ad_graph_t>
01543 int operator() (const Vector_t& v1, const Ad_graph_t& adg, Vector_t& v2);
01544 };
01545
01546 template <class Comm_t>
01547 class split_vector_t {
01548 Comm_t comm;
01549 public:
01550 split_vector_t (Comm_t _comm) : comm (_comm) {}
01551 template <class Vector_t, class Ad_graph_t>
01552 int operator() (const Vector_t& v1, const Ad_graph_t&, Vector_t& v2) {
01553 v2.resize (0);
01554 int me= comm.Get_rank(), np= comm.Get_size();
01555 size_t first= block_begin (me, np, v1.size()), last= block_begin (me + 1, np, v1.size()) - 1;
01556 for (; first <= last; first++) v2.push_back (v1[first]);
01557 return v2.size(); }
01558 };
01559
01560 typedef split_vector_t<GMPI::Intracomm> std_split_vector_t;
01561
01562 template <class Comm_t>
01563 class bcast_best_t {
01564 Comm_t comm;
01565 public:
01566 bcast_best_t (Comm_t _comm) : comm (_comm) {}
01567 template <class Vector_t, class Ad_graph_t>
01568 int operator() (const Vector_t& v1, const Ad_graph_t&, Vector_t& v2);
01569 };
01570
01571 typedef bcast_best_t<GMPI::Intracomm> std_bcast_best_t;
01572
01573 template <class Heuristic_t, class Comm_t>
01574 class par_frame_t {
01575 private:
01576 split_vector_t<Comm_t> my_split_vector;
01577 Heuristic_t h;
01578 bcast_best_t<Comm_t> my_bcast_best;
01579 heuristic_triplet_t<split_vector_t<Comm_t>,Heuristic_t,bcast_best_t<Comm_t> > my_triplet;
01580 public:
01581 par_frame_t (Heuristic_t _h, Comm_t _comm) : my_split_vector (_comm), h (_h),
01582 my_bcast_best (_comm), my_triplet (my_split_vector, h, my_bcast_best) {}
01583 template <class Vector_t, class Ad_graph_t>
01584 int operator() (const Vector_t& v1, const Ad_graph_t& adg, Vector_t& v2) {
01585 return my_triplet (v1, adg, v2); }
01586 };
01587
01588 template <class Heuristic1_t, class Heuristic2_t, class Comm_t>
01589 class par_heuristic_pair_t {
01590 private:
01591 typedef par_heuristic_t<Heuristic1_t,Comm_t> ph1_t;
01592 typedef par_heuristic_t<Heuristic2_t,Comm_t> ph2_t;
01593 typedef heuristic_pair_t<ph1_t,ph2_t> pair_t;
01594 typedef par_frame_t<pair_t,Comm_t> par_heuristic_t;
01595 ph1_t ph1;
01596 ph2_t ph2;
01597 pair_t pair;
01598 par_heuristic_t par_heuristic;
01599 public:
01600 par_heuristic_pair_t (Heuristic1_t _h1, Heuristic2_t _h2, Comm_t _comm) :
01601 ph1 (_h1, _comm), ph2 (_h2, _comm), pair (ph1, ph2), par_heuristic (pair, _comm) {}
01602 template <class Vector_t, class Ad_graph_t>
01603 int operator() (const Vector_t& v1, const Ad_graph_t& adg, Vector_t& v2) {
01604 return par_heuristic (v1, adg, v2); }
01605 };
01606
01607 template <class Heuristic1_t, class Heuristic2_t, class Heuristic3_t, class Comm_t>
01608 class par_heuristic_triplet_t {
01609 private:
01610 typedef par_heuristic_t<Heuristic1_t,Comm_t> ph1_t;
01611 typedef par_heuristic_t<Heuristic2_t,Comm_t> ph2_t;
01612 typedef par_heuristic_t<Heuristic3_t,Comm_t> ph3_t;
01613 typedef heuristic_triplet_t<ph1_t,ph2_t,ph3_t> triplet_t;
01614 typedef par_frame_t<triplet_t,Comm_t> par_heuristic_t;
01615 ph1_t ph1;
01616 ph2_t ph2;
01617 ph3_t ph3;
01618 triplet_t triplet;
01619 par_heuristic_t par_heuristic;
01620 public:
01621 par_heuristic_triplet_t (Heuristic1_t _h1, Heuristic2_t _h2, Heuristic3_t _h3, Comm_t _comm) :
01622 ph1 (_h1, _comm), ph2 (_h2, _comm), ph3 (_h3, _comm), triplet (ph1, ph2, ph3),
01623 par_heuristic (triplet, _comm) {}
01624 template <class Vector_t, class Ad_graph_t>
01625 int operator() (const Vector_t& v1, const Ad_graph_t& adg, Vector_t& v2) {
01626 return par_heuristic (v1, adg, v2); }
01627 };
01628
01629 #endif // USE_MPI
01630
01631 }
01632
01633 #include "heuristics_impl.hpp"
01634
01635 #endif // _heuristics_include_
01636