heuristics_impl.hpp

Go to the documentation of this file.
00001 // $Id: heuristics_impl.hpp,v 1.5 2004/02/22 18:44:46 gottschling Exp $
00002 
00003 #include <set>
00004 // #include <limits>
00005 #include <limits.h>
00006 #include "angel_exceptions.hpp"
00007 
00008 namespace angel {
00009   using std::vector;
00010 
00011 template <typename Heuristic_t>
00012 int lowest_markowitz_face_complete_t<Heuristic_t>::operator() (const vector<line_graph_t::face_t>& fv1,
00013                                                                const line_graph_t& lg,
00014                                                                vector<line_graph_t::face_t>& fv2) {
00015     fv2.resize(0);
00016     line_graph_t::const_evn_t evn= get(boost::vertex_name, lg);
00017 
00018     // if there are still faces from the vertex with 
00019     // the lowest Markowitz degree chosen at last return these faces
00020     typedef line_graph_t::face_t face_t;
00021     if (lastv != -1) {
00022       for (size_t c= 0; c < fv1.size(); c++) {   
00023         face_t f= fv1[c];
00024         if (lastv == evn[source(f, lg)].second) fv2.push_back (f); }
00025       if (fv2.size() != 0) return fv2.size();
00026     }
00027 
00028     // otherwise search new vertex (vertices)
00029     vector<int> mdegree;
00030     markowitz_on_line_graph (lg, mdegree);
00031     
00032     vector<face_t> fvlm; // faces via vertices with miminal Markowitz
00033     fvlm.push_back (fv1[0]);
00034     int minm= mdegree[evn[source(fv1[0], lg)].second]; // minimal Markowitz
00035     
00036     for (size_t c= 1; c < fv1.size(); c++) {
00037       face_t f= fv1[c];
00038       int m= mdegree[evn[source(f, lg)].second];
00039       if (m < minm) {fvlm.resize (0); minm= m;}
00040       if (m == minm) fvlm.push_back (f); }
00041     
00042     tiebreaker (fvlm, lg, fv2);
00043     THROW_DEBUG_EXCEPT_MACRO (fv2.size() == 0, consistency_exception, "Tiebreaker returned empty vector");
00044     lastv= evn[source(fv2[0], lg)].second;
00045     
00046     // test if all returned faces belong to the same vertex
00047 #ifndef NDEBUG
00048     for (size_t c= 1; c < fv2.size(); c++)
00049       THROW_EXCEPT_MACRO (lastv != evn[source(fv2[c], lg)].second, consistency_exception, 
00050                        "Returned faces does not belong to the same vertex");
00051 #endif
00052 
00053     return fv2.size();
00054 } // end of operator
00055 
00056 
00057 
00058 template <class Vertex_heuristic_t>
00059 int emulated_vertex_heuristic_t<Vertex_heuristic_t>::operator() (const vector<edge_ij_elim_t>& eev1,
00060                                                                  const c_graph_t& cg,
00061                                                                  vector<edge_ij_elim_t>& eev2) {
00062   eev2.resize (0);
00063 
00064   // looking for egde eliminations belonging to last vertex elimination
00065   // and which other vertex eliminations could be performed
00066   std::set<c_graph_t::vertex_t>   vs;
00067   for (size_t c= 0; c < eev1.size(); c++) {
00068     c_graph_t::vertex_t v= eev1[c].front ? eev1[c].j : eev1[c].i;
00069     if (v == last_vertex) eev2.push_back (eev1[c]); 
00070     vs.insert (v);}
00071 
00072   if (eev2.size() > 0) return eev2.size(); // belonging to last vertex elimination
00073 
00074   vector<c_graph_t::vertex_t> vv1 (vs.begin(), vs.end()), vv2;
00075   h (vv1, cg, vv2);
00076   for (size_t c= 0; c < eev1.size(); c++) {
00077     c_graph_t::vertex_t v= eev1[c].front ? eev1[c].j : eev1[c].i;
00078     if (find (vv2.begin(), vv2.end(), v) != vv2.end()) eev2.push_back (eev1[c]); }
00079   return eev2.size();
00080 }
00081 
00082 template <class Object_t, class Ad_graph_t, class Heuristic1_t, class Heuristic2_t, 
00083           class Heuristic3_t, class Heuristic4_t, class Heuristic5_t>
00084 inline int best_heuristic (const Ad_graph_t& adg, vector<Object_t>& el_seq,
00085                            Heuristic1_t h1, Heuristic2_t h2, Heuristic3_t h3, 
00086                            Heuristic4_t h4, Heuristic5_t h5) {
00087   vector<std::pair<int, vector<Object_t> > > results (5);
00088   results[0].first= use_heuristic (adg, results[0].second, h1);
00089   results[1].first= use_heuristic (adg, results[1].second, h2);
00090   results[2].first= use_heuristic (adg, results[2].second, h3);
00091   results[3].first= use_heuristic (adg, results[3].second, h4);
00092   results[4].first= use_heuristic (adg, results[4].second, h5);
00093 
00094   size_t bestIndex = 0;
00095   int bestCost = results[0].first;
00096   for (size_t c = 1; c < 5; c++) {
00097     if (results[c].first < bestCost) {
00098       bestIndex = c;
00099       bestCost = results[c].first;
00100     }
00101   }
00102   el_seq = results[bestIndex].second;
00103   return bestCost;
00104 }
00105 
00106 #ifdef USE_MPI
00107 template <class Heuristic_t, class Comm_t>
00108 template <class Vector_t, class Ad_graph_t>
00109 int par_heuristic_t<Heuristic_t, Comm_t>::operator() (const Vector_t& v1, const Ad_graph_t& adg, 
00110                                                       Vector_t& v2) {
00111 
00112   // best local objects 
00113   typedef typename Heuristic_t::objective_t   objective_t;
00114   h (v1, adg, v2);
00115   objective_t  my_objective= h.objective(), best_objective;
00116 
00117   // find best global objective value
00118   MPI::Datatype     datatype= GMPI::which_mpi_t (my_objective);
00119   MPI::Op           op= h.to_maximize() ? MPI::MAX : MPI::MIN;
00120   comm.Allreduce (&my_objective, &best_objective, 1, datatype, op);
00121 
00122   // if there are better objectives elsewhere --> throw my objects away
00123   if (my_objective != best_objective) v2.resize (0);
00124   return v2.size();
00125 }
00126 
00127 template <class Comm_t>
00128 template <class Vector_t, class Ad_graph_t>
00129 int bcast_best_t<Comm_t>::operator() (const Vector_t& v1, const Ad_graph_t&, Vector_t& v2) {
00130   int my_pe_size[2], sum_pe_size[2];
00131   my_pe_size[1]= v1.size(); my_pe_size[0]= v1.size() == 0 ? 0 : comm.Get_rank(); 
00132   comm.Allreduce (my_pe_size, sum_pe_size, 2, MPI::INT, MPI::SUM);
00133   THROW_EXCEPT_MACRO (sum_pe_size[1] != 1, consistency_exception, "v1 must contain 1 element overall!");
00134   v2= v1;
00135   GMPI::comm_ref_t<int, Vector_t> comm_ref (v2); // reference used in communication
00136   comm.Bcast (comm_ref, sum_pe_size[0]);
00137   return v2.size(); 
00138 }
00139 
00140 #endif // USE_MPI
00141 
00143 template <class Object_t, class Ad_graph_t, class Op_t, class Objective_t>
00144 int standard_heuristic_op (const vector<Object_t>& v1, const Ad_graph_t& adg,
00145                            vector<Object_t>& v2, Op_t op, base_heuristic_t<Objective_t>& h) {
00146   v2.resize (0);
00147   Objective_t best= h.to_maximize() ? std::numeric_limits<Objective_t>::min() : 
00148                                       std::numeric_limits<Objective_t>::max();
00149 
00150   for (size_t c= 0; c < v1.size(); c++) {
00151     Object_t o= v1[c];
00152     Objective_t value= op (o, adg);
00153     if (h.to_maximize()) {
00154       if (value > best) v2.resize (0);
00155       if (value >= best) { v2.push_back (o); best= value; }
00156     } else {
00157       if (value < best) v2.resize (0);
00158       if (value <= best) { v2.push_back (o); best= value;} } }
00159   h.set_objective (best);
00160   return v2.size();
00161 }
00162 
00163 
00164 } // namespace angel

Generated on Wed Mar 11 10:33:11 2009 for angel by  doxygen 1.5.3