annotate DEPENDENCIES/generic/include/boost/graph/howard_cycle_ratio.hpp @ 133:4acb5d8d80b6 tip

Don't fail environmental check if README.md exists (but .txt and no-suffix don't)
author Chris Cannam
date Tue, 30 Jul 2019 12:25:44 +0100
parents 2665513ce2d3
children
rev   line source
Chris@16 1 // Copyright (C) 2006-2009 Dmitry Bufistov and Andrey Parfenov
Chris@16 2
Chris@16 3 // Use, modification and distribution is subject to the Boost Software
Chris@16 4 // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
Chris@16 5 // http://www.boost.org/LICENSE_1_0.txt)
Chris@16 6
Chris@16 7 #ifndef BOOST_GRAPH_CYCLE_RATIO_HOWARD_HPP
Chris@16 8 #define BOOST_GRAPH_CYCLE_RATIO_HOWARD_HPP
Chris@16 9
Chris@16 10 #include <vector>
Chris@16 11 #include <list>
Chris@16 12 #include <algorithm>
Chris@16 13 #include <limits>
Chris@16 14
Chris@16 15 #include <boost/bind.hpp>
Chris@16 16 #include <boost/type_traits/is_same.hpp>
Chris@16 17 #include <boost/type_traits/remove_const.hpp>
Chris@16 18 #include <boost/concept_check.hpp>
Chris@16 19 #include <boost/pending/queue.hpp>
Chris@16 20 #include <boost/property_map/property_map.hpp>
Chris@16 21 #include <boost/graph/graph_traits.hpp>
Chris@16 22 #include <boost/graph/graph_concepts.hpp>
Chris@16 23 #include <boost/concept/assert.hpp>
Chris@16 24
Chris@16 25 /** @file howard_cycle_ratio.hpp
Chris@16 26 * @brief The implementation of the maximum/minimum cycle ratio/mean algorithm.
Chris@16 27 * @author Dmitry Bufistov
Chris@16 28 * @author Andrey Parfenov
Chris@16 29 */
Chris@16 30
Chris@16 31 namespace boost {
Chris@16 32
Chris@16 33 /**
Chris@16 34 * The mcr_float is like numeric_limits, but only for floating point types
Chris@16 35 * and only defines infinity() and epsilon(). This class is primarily used
Chris@16 36 * to encapsulate a less-precise epsilon than natively supported by the
Chris@16 37 * floating point type.
Chris@16 38 */
Chris@16 39 template <typename Float = double> struct mcr_float {
Chris@16 40 typedef Float value_type;
Chris@16 41
Chris@16 42 static Float infinity()
Chris@16 43 { return std::numeric_limits<value_type>::infinity(); }
Chris@16 44
Chris@16 45 static Float epsilon()
Chris@16 46 { return Float(-0.005); }
Chris@16 47 };
Chris@16 48
Chris@16 49 namespace detail {
Chris@16 50
Chris@16 51 template <typename FloatTraits> struct
Chris@16 52 min_comparator_props {
Chris@16 53 typedef std::greater<typename FloatTraits::value_type> comparator;
Chris@16 54 static const int multiplier = 1;
Chris@16 55 };
Chris@16 56
Chris@16 57 template <typename FloatTraits> struct
Chris@16 58 max_comparator_props {
Chris@16 59 typedef std::less<typename FloatTraits::value_type> comparator;
Chris@16 60 static const int multiplier = -1;
Chris@16 61 };
Chris@16 62
Chris@16 63 template <typename FloatTraits, typename ComparatorProps>
Chris@16 64 struct float_wrapper {
Chris@16 65 typedef typename FloatTraits::value_type value_type;
Chris@16 66 typedef ComparatorProps comparator_props_t;
Chris@16 67 typedef typename ComparatorProps::comparator comparator;
Chris@16 68
Chris@16 69 static value_type infinity()
Chris@16 70 { return FloatTraits::infinity() * ComparatorProps::multiplier; }
Chris@16 71
Chris@16 72 static value_type epsilon()
Chris@16 73 { return FloatTraits::epsilon() * ComparatorProps::multiplier; }
Chris@16 74
Chris@16 75 };
Chris@16 76
Chris@16 77 /*! @class mcr_howard
Chris@16 78 * @brief Calculates optimum (maximum/minimum) cycle ratio of a directed graph.
Chris@16 79 * Uses Howard's iteration policy algorithm. </br>(It is described in the paper
Chris@16 80 * "Experimental Analysis of the Fastest Optimum Cycle Ratio and Mean Algorithm"
Chris@16 81 * by Ali Dasdan).
Chris@16 82 */
Chris@16 83 template <typename FloatTraits,
Chris@16 84 typename Graph, typename VertexIndexMap,
Chris@16 85 typename EdgeWeight1, typename EdgeWeight2>
Chris@16 86 class mcr_howard
Chris@16 87 {
Chris@16 88 public:
Chris@16 89 typedef typename FloatTraits::value_type float_t;
Chris@16 90 typedef typename FloatTraits::comparator_props_t cmp_props_t;
Chris@16 91 typedef typename FloatTraits::comparator comparator_t;
Chris@16 92 typedef enum{ my_white = 0, my_black } my_color_type;
Chris@16 93 typedef typename graph_traits<Graph>::vertex_descriptor vertex_t;
Chris@16 94 typedef typename graph_traits<Graph>::edge_descriptor edge_t;
Chris@16 95 typedef typename graph_traits<Graph>::vertices_size_type vn_t;
Chris@16 96 typedef std::vector<float_t> vp_t;
Chris@16 97 typedef typename boost::iterator_property_map<
Chris@16 98 typename vp_t::iterator, VertexIndexMap
Chris@16 99 > distance_map_t; //V -> float_t
Chris@16 100
Chris@16 101 typedef typename std::vector<edge_t> ve_t;
Chris@16 102 typedef std::vector<my_color_type> vcol_t;
Chris@16 103 typedef typename ::boost::iterator_property_map<
Chris@16 104 typename ve_t::iterator, VertexIndexMap
Chris@16 105 > policy_t; //Vertex -> Edge
Chris@16 106 typedef typename ::boost::iterator_property_map<
Chris@16 107 typename vcol_t::iterator, VertexIndexMap
Chris@16 108 > color_map_t;
Chris@16 109
Chris@16 110 typedef typename std::list<vertex_t> pinel_t;// The in_edges list of the policy graph
Chris@16 111 typedef typename std::vector<pinel_t> inedges1_t;
Chris@16 112 typedef typename ::boost::iterator_property_map<
Chris@16 113 typename inedges1_t::iterator, VertexIndexMap
Chris@16 114 > inedges_t;
Chris@16 115 typedef typename std::vector<edge_t> critical_cycle_t;
Chris@16 116
Chris@16 117 //Bad vertex flag. If true, then the vertex is "bad".
Chris@16 118 // Vertex is "bad" if its out_degree is equal to zero.
Chris@16 119 typedef typename boost::iterator_property_map<
Chris@16 120 std::vector<int>::iterator, VertexIndexMap
Chris@16 121 > badv_t;
Chris@16 122
Chris@16 123 /*!
Chris@16 124 * Constructor
Chris@16 125 * \param g = (V, E) - a directed multigraph.
Chris@16 126 * \param vim Vertex Index Map. Read property Map: V -> [0, num_vertices(g)).
Chris@16 127 * \param ewm edge weight map. Read property map: E -> R
Chris@16 128 * \param ew2m edge weight map. Read property map: E -> R+
Chris@16 129 * \param infty A big enough value to guaranty that there exist a cycle with
Chris@16 130 * better ratio.
Chris@16 131 * \param cmp The compare operator for float_ts.
Chris@16 132 */
Chris@16 133 mcr_howard(const Graph &g, VertexIndexMap vim,
Chris@16 134 EdgeWeight1 ewm, EdgeWeight2 ew2m) :
Chris@16 135 m_g(g), m_vim(vim), m_ew1m(ewm), m_ew2m(ew2m),
Chris@16 136 m_bound(mcr_bound()),
Chris@16 137 m_cr(m_bound),
Chris@16 138 m_V(num_vertices(m_g)),
Chris@16 139 m_dis(m_V, 0), m_dm(m_dis.begin(), m_vim),
Chris@16 140 m_policyc(m_V), m_policy(m_policyc.begin(), m_vim),
Chris@16 141 m_inelc(m_V), m_inel(m_inelc.begin(), m_vim),
Chris@16 142 m_badvc(m_V, false), m_badv(m_badvc.begin(), m_vim),
Chris@16 143 m_colcv(m_V),
Chris@16 144 m_col_bfs(m_V)
Chris@16 145 { }
Chris@16 146
Chris@16 147 /*!
Chris@16 148 * \return maximum/minimum_{for all cycles C}
Chris@16 149 * [sum_{e in C} w1(e)] / [sum_{e in C} w2(e)],
Chris@16 150 * or FloatTraits::infinity() if graph has no cycles.
Chris@16 151 */
Chris@16 152 float_t ocr_howard()
Chris@16 153 {
Chris@16 154 construct_policy_graph();
Chris@16 155 int k = 0;
Chris@16 156 float_t mcr = 0;
Chris@16 157 do
Chris@16 158 {
Chris@16 159 mcr = policy_mcr();
Chris@16 160 ++k;
Chris@16 161 }
Chris@16 162 while (try_improve_policy(mcr) && k < 100); //To avoid infinite loop
Chris@16 163
Chris@16 164 const float_t eps_ = -0.00000001 * cmp_props_t::multiplier;
Chris@16 165 if (m_cmp(mcr, m_bound + eps_))
Chris@16 166 {
Chris@16 167 return FloatTraits::infinity();
Chris@16 168 }
Chris@16 169 else
Chris@16 170 {
Chris@16 171 return mcr;
Chris@16 172 }
Chris@16 173 }
Chris@16 174 virtual ~mcr_howard() {}
Chris@16 175
Chris@16 176 protected:
Chris@16 177 virtual void store_critical_edge(edge_t, critical_cycle_t &) {}
Chris@16 178 virtual void store_critical_cycle(critical_cycle_t &) {}
Chris@16 179
Chris@16 180 private:
Chris@16 181 /*!
Chris@16 182 * \return lower/upper bound for the maximal/minimal cycle ratio
Chris@16 183 */
Chris@16 184 float_t mcr_bound()
Chris@16 185 {
Chris@16 186 typename graph_traits<Graph>::vertex_iterator vi, vie;
Chris@16 187 typename graph_traits<Graph>::out_edge_iterator oei, oeie;
Chris@16 188 float_t cz = (std::numeric_limits<float_t>::max)(); //Closest to zero value
Chris@16 189 float_t s = 0;
Chris@16 190 const float_t eps_ = std::numeric_limits<float_t>::epsilon();
Chris@16 191 for (boost::tie(vi, vie) = vertices(m_g); vi != vie; ++vi)
Chris@16 192 {
Chris@16 193 for (boost::tie(oei, oeie) = out_edges(*vi, m_g); oei != oeie; ++oei)
Chris@16 194 {
Chris@16 195 s += std::abs(m_ew1m[*oei]);
Chris@16 196 float_t a = std::abs(m_ew2m[*oei]);
Chris@16 197 if ( a > eps_ && a < cz)
Chris@16 198 {
Chris@16 199 cz = a;
Chris@16 200 }
Chris@16 201 }
Chris@16 202 }
Chris@16 203 return cmp_props_t::multiplier * (s / cz);
Chris@16 204 }
Chris@16 205
Chris@16 206
Chris@16 207 /*!
Chris@16 208 * Constructs an arbitrary policy graph.
Chris@16 209 */
Chris@16 210 void construct_policy_graph()
Chris@16 211 {
Chris@16 212 m_sink = graph_traits<Graph>().null_vertex();
Chris@16 213 typename graph_traits<Graph>::vertex_iterator vi, vie;
Chris@16 214 typename graph_traits<Graph>::out_edge_iterator oei, oeie;
Chris@16 215 for ( boost::tie(vi, vie) = vertices(m_g); vi != vie; ++vi )
Chris@16 216 {
Chris@16 217 boost::tie(oei, oeie) = out_edges(*vi, m_g);
Chris@16 218 typename graph_traits<Graph>::out_edge_iterator mei =
Chris@16 219 std::max_element(oei, oeie,
Chris@16 220 boost::bind(m_cmp,
Chris@16 221 boost::bind(&EdgeWeight1::operator[], m_ew1m, _1),
Chris@16 222 boost::bind(&EdgeWeight1::operator[], m_ew1m, _2)
Chris@16 223 )
Chris@16 224 );
Chris@16 225 if (mei == oeie)
Chris@16 226 {
Chris@16 227 if (m_sink == graph_traits<Graph>().null_vertex())
Chris@16 228 {
Chris@16 229 m_sink = *vi;
Chris@16 230 }
Chris@16 231 m_badv[*vi] = true;
Chris@16 232 m_inel[m_sink].push_back(*vi);
Chris@16 233 }
Chris@16 234 else
Chris@16 235 {
Chris@16 236 m_inel[target(*mei, m_g)].push_back(*vi);
Chris@16 237 m_policy[*vi] = *mei;
Chris@16 238 }
Chris@16 239 }
Chris@16 240 }
Chris@16 241 /*! Sets the distance value for all vertices "v" such that there is
Chris@16 242 * a path from "v" to "sv". It does "inverse" breadth first visit of the policy
Chris@16 243 * graph, starting from the vertex "sv".
Chris@16 244 */
Chris@16 245 void mcr_bfv(vertex_t sv, float_t cr, color_map_t c)
Chris@16 246 {
Chris@16 247 boost::queue<vertex_t> Q;
Chris@16 248 c[sv] = my_black;
Chris@16 249 Q.push(sv);
Chris@16 250 while (!Q.empty())
Chris@16 251 {
Chris@16 252 vertex_t v = Q.top(); Q.pop();
Chris@16 253 for (typename pinel_t::const_iterator itr = m_inel[v].begin();
Chris@16 254 itr != m_inel[v].end(); ++itr)
Chris@16 255 //For all in_edges of the policy graph
Chris@16 256 {
Chris@16 257 if (*itr != sv)
Chris@16 258 {
Chris@16 259 if (m_badv[*itr])
Chris@16 260 {
Chris@16 261 m_dm[*itr] = m_dm[v] + m_bound - cr;
Chris@16 262 }
Chris@16 263 else
Chris@16 264 {
Chris@16 265 m_dm[*itr] = m_dm[v] + m_ew1m[m_policy[*itr]] -
Chris@16 266 m_ew2m[m_policy[*itr]] * cr;
Chris@16 267 }
Chris@16 268 c[*itr] = my_black;
Chris@16 269 Q.push(*itr);
Chris@16 270 }
Chris@16 271 }
Chris@16 272 }
Chris@16 273 }
Chris@16 274
Chris@16 275 /*!
Chris@16 276 * \param sv an arbitrary (undiscovered) vertex of the policy graph.
Chris@16 277 * \return a vertex in the policy graph that belongs to a cycle.
Chris@16 278 * Performs a depth first visit until a cycle edge is found.
Chris@16 279 */
Chris@16 280 vertex_t find_cycle_vertex(vertex_t sv)
Chris@16 281 {
Chris@16 282 vertex_t gv = sv;
Chris@16 283 std::fill(m_colcv.begin(), m_colcv.end(), my_white);
Chris@16 284 color_map_t cm(m_colcv.begin(), m_vim);
Chris@16 285 do
Chris@16 286 {
Chris@16 287 cm[gv] = my_black;
Chris@16 288 if (! m_badv[gv])
Chris@16 289 {
Chris@16 290 gv = target(m_policy[gv], m_g);
Chris@16 291 }
Chris@16 292 else
Chris@16 293 {
Chris@16 294 gv = m_sink;
Chris@16 295 }
Chris@16 296 }
Chris@16 297 while (cm[gv] != my_black);
Chris@16 298 return gv;
Chris@16 299 }
Chris@16 300
Chris@16 301 /*!
Chris@16 302 * \param sv - vertex that belongs to a cycle in the policy graph.
Chris@16 303 */
Chris@16 304 float_t cycle_ratio(vertex_t sv)
Chris@16 305 {
Chris@16 306 if (sv == m_sink) return m_bound;
Chris@16 307 std::pair<float_t, float_t> sums_(float_t(0), float_t(0));
Chris@16 308 vertex_t v = sv;
Chris@16 309 critical_cycle_t cc;
Chris@16 310 do
Chris@16 311 {
Chris@16 312 store_critical_edge(m_policy[v], cc);
Chris@16 313 sums_.first += m_ew1m[m_policy[v]];
Chris@16 314 sums_.second += m_ew2m[m_policy[v]];
Chris@16 315 v = target(m_policy[v], m_g);
Chris@16 316 }
Chris@16 317 while (v != sv);
Chris@16 318 float_t cr = sums_.first / sums_.second;
Chris@16 319 if ( m_cmp(m_cr, cr) )
Chris@16 320 {
Chris@16 321 m_cr = cr;
Chris@16 322 store_critical_cycle(cc);
Chris@16 323 }
Chris@16 324 return cr;
Chris@16 325 }
Chris@16 326
Chris@16 327 /*!
Chris@16 328 * Finds the optimal cycle ratio of the policy graph
Chris@16 329 */
Chris@16 330 float_t policy_mcr()
Chris@16 331 {
Chris@16 332 std::fill(m_col_bfs.begin(), m_col_bfs.end(), my_white);
Chris@16 333 color_map_t vcm_ = color_map_t(m_col_bfs.begin(), m_vim);
Chris@16 334 typename graph_traits<Graph>::vertex_iterator uv_itr, vie;
Chris@16 335 boost::tie(uv_itr, vie) = vertices(m_g);
Chris@16 336 float_t mcr = m_bound;
Chris@16 337 while ( (uv_itr = std::find_if(uv_itr, vie,
Chris@16 338 boost::bind(std::equal_to<my_color_type>(),
Chris@16 339 my_white,
Chris@16 340 boost::bind(&color_map_t::operator[], vcm_, _1)
Chris@16 341 )
Chris@16 342 )
Chris@16 343 ) != vie )
Chris@16 344 ///While there are undiscovered vertices
Chris@16 345 {
Chris@16 346 vertex_t gv = find_cycle_vertex(*uv_itr);
Chris@16 347 float_t cr = cycle_ratio(gv) ;
Chris@16 348 mcr_bfv(gv, cr, vcm_);
Chris@16 349 if ( m_cmp(mcr, cr) ) mcr = cr;
Chris@16 350 ++uv_itr;
Chris@16 351 }
Chris@16 352 return mcr;
Chris@16 353 }
Chris@16 354
Chris@16 355 /*!
Chris@16 356 * Changes the edge m_policy[s] to the new_edge.
Chris@16 357 */
Chris@16 358 void improve_policy(vertex_t s, edge_t new_edge)
Chris@16 359 {
Chris@16 360 vertex_t t = target(m_policy[s], m_g);
Chris@16 361 typename property_traits<VertexIndexMap>::value_type ti = m_vim[t];
Chris@16 362 m_inelc[ti].erase( std::find(m_inelc[ti].begin(), m_inelc[ti].end(), s));
Chris@16 363 m_policy[s] = new_edge;
Chris@16 364 t = target(new_edge, m_g);
Chris@16 365 m_inel[t].push_back(s); ///Maintain in_edge list
Chris@16 366 }
Chris@16 367
Chris@16 368 /*!
Chris@16 369 * A negative cycle detector.
Chris@16 370 */
Chris@16 371 bool try_improve_policy(float_t cr)
Chris@16 372 {
Chris@16 373 bool improved = false;
Chris@16 374 typename graph_traits<Graph>::vertex_iterator vi, vie;
Chris@16 375 typename graph_traits<Graph>::out_edge_iterator oei, oeie;
Chris@16 376 const float_t eps_ = FloatTraits::epsilon();
Chris@16 377 for (boost::tie(vi, vie) = vertices(m_g); vi != vie; ++vi)
Chris@16 378 {
Chris@16 379 if (!m_badv[*vi])
Chris@16 380 {
Chris@16 381 for (boost::tie(oei, oeie) = out_edges(*vi, m_g); oei != oeie; ++oei)
Chris@16 382 {
Chris@16 383 vertex_t t = target(*oei, m_g);
Chris@16 384 //Current distance from *vi to some vertex
Chris@16 385 float_t dis_ = m_ew1m[*oei] - m_ew2m[*oei] * cr + m_dm[t];
Chris@16 386 if ( m_cmp(m_dm[*vi] + eps_, dis_) )
Chris@16 387 {
Chris@16 388 improve_policy(*vi, *oei);
Chris@16 389 m_dm[*vi] = dis_;
Chris@16 390 improved = true;
Chris@16 391 }
Chris@16 392 }
Chris@16 393 }
Chris@16 394 else
Chris@16 395 {
Chris@16 396 float_t dis_ = m_bound - cr + m_dm[m_sink];
Chris@16 397 if ( m_cmp(m_dm[*vi] + eps_, dis_) )
Chris@16 398 {
Chris@16 399 m_dm[*vi] = dis_;
Chris@16 400 }
Chris@16 401 }
Chris@16 402 }
Chris@16 403 return improved;
Chris@16 404 }
Chris@16 405 private:
Chris@16 406 const Graph &m_g;
Chris@16 407 VertexIndexMap m_vim;
Chris@16 408 EdgeWeight1 m_ew1m;
Chris@16 409 EdgeWeight2 m_ew2m;
Chris@16 410 comparator_t m_cmp;
Chris@16 411 float_t m_bound; //> The lower/upper bound to the maximal/minimal cycle ratio
Chris@16 412 float_t m_cr; //>The best cycle ratio that has been found so far
Chris@16 413
Chris@16 414 vn_t m_V; //>The number of the vertices in the graph
Chris@16 415 vp_t m_dis; //>Container for the distance map
Chris@16 416 distance_map_t m_dm; //>Distance map
Chris@16 417
Chris@16 418 ve_t m_policyc; //>Container for the policy graph
Chris@16 419 policy_t m_policy; //>The interface for the policy graph
Chris@16 420
Chris@16 421 inedges1_t m_inelc; //>Container fot in edges list
Chris@16 422 inedges_t m_inel; //>Policy graph, input edges list
Chris@16 423
Chris@16 424 std::vector<int> m_badvc;
Chris@16 425 badv_t m_badv; //Marks "bad" vertices
Chris@16 426
Chris@16 427 vcol_t m_colcv, m_col_bfs; //Color maps
Chris@16 428 vertex_t m_sink; //To convert any graph to "good"
Chris@16 429 };
Chris@16 430
Chris@16 431 /*! \class mcr_howard1
Chris@16 432 * \brief Finds optimum cycle raio and a critical cycle
Chris@16 433 */
Chris@16 434 template <typename FloatTraits,
Chris@16 435 typename Graph, typename VertexIndexMap,
Chris@16 436 typename EdgeWeight1, typename EdgeWeight2>
Chris@16 437 class mcr_howard1 : public
Chris@16 438 mcr_howard<FloatTraits, Graph, VertexIndexMap,
Chris@16 439 EdgeWeight1, EdgeWeight2>
Chris@16 440 {
Chris@16 441 public:
Chris@16 442 typedef mcr_howard<FloatTraits, Graph, VertexIndexMap,
Chris@16 443 EdgeWeight1, EdgeWeight2> inhr_t;
Chris@16 444 mcr_howard1(const Graph &g, VertexIndexMap vim,
Chris@16 445 EdgeWeight1 ewm, EdgeWeight2 ew2m) :
Chris@16 446 inhr_t(g, vim, ewm, ew2m)
Chris@16 447 { }
Chris@16 448
Chris@16 449 void get_critical_cycle(typename inhr_t::critical_cycle_t &cc)
Chris@16 450 { return cc.swap(m_cc); }
Chris@16 451
Chris@16 452 protected:
Chris@16 453 void store_critical_edge(typename inhr_t::edge_t ed,
Chris@16 454 typename inhr_t::critical_cycle_t &cc)
Chris@16 455 { cc.push_back(ed); }
Chris@16 456
Chris@16 457 void store_critical_cycle(typename inhr_t::critical_cycle_t &cc)
Chris@16 458 { m_cc.swap(cc); }
Chris@16 459
Chris@16 460 private:
Chris@16 461 typename inhr_t::critical_cycle_t m_cc; //Critical cycle
Chris@16 462 };
Chris@16 463
Chris@16 464 /*!
Chris@16 465 * \param g a directed multigraph.
Chris@16 466 * \param vim Vertex Index Map. A map V->[0, num_vertices(g))
Chris@16 467 * \param ewm Edge weight1 map.
Chris@16 468 * \param ew2m Edge weight2 map.
Chris@16 469 * \param pcc pointer to the critical edges list.
Chris@16 470 * \return Optimum cycle ratio of g or FloatTraits::infinity() if g has no cycles.
Chris@16 471 */
Chris@16 472 template <typename FT,
Chris@16 473 typename TG, typename TVIM,
Chris@16 474 typename TEW1, typename TEW2,
Chris@16 475 typename EV>
Chris@16 476 typename FT::value_type
Chris@16 477 optimum_cycle_ratio(const TG &g, TVIM vim, TEW1 ewm, TEW2 ew2m, EV* pcc)
Chris@16 478 {
Chris@16 479 typedef typename graph_traits<TG>::directed_category DirCat;
Chris@16 480 BOOST_STATIC_ASSERT((is_convertible<DirCat*, directed_tag*>::value == true));
Chris@16 481 BOOST_CONCEPT_ASSERT(( IncidenceGraphConcept<TG> ));
Chris@16 482 BOOST_CONCEPT_ASSERT(( VertexListGraphConcept<TG> ));
Chris@16 483 typedef typename graph_traits<TG>::vertex_descriptor Vertex;
Chris@16 484 BOOST_CONCEPT_ASSERT(( ReadablePropertyMapConcept<TVIM, Vertex> ));
Chris@16 485 typedef typename graph_traits<TG>::edge_descriptor Edge;
Chris@16 486 BOOST_CONCEPT_ASSERT(( ReadablePropertyMapConcept<TEW1, Edge> ));
Chris@16 487 BOOST_CONCEPT_ASSERT(( ReadablePropertyMapConcept<TEW2, Edge> ));
Chris@16 488
Chris@16 489 if(pcc == 0) {
Chris@16 490 return detail::mcr_howard<FT,TG, TVIM, TEW1, TEW2>(
Chris@16 491 g, vim, ewm, ew2m
Chris@16 492 ).ocr_howard();
Chris@16 493 }
Chris@16 494
Chris@16 495 detail::mcr_howard1<FT, TG, TVIM, TEW1, TEW2> obj(g, vim, ewm, ew2m);
Chris@16 496 double ocr = obj.ocr_howard();
Chris@16 497 obj.get_critical_cycle(*pcc);
Chris@16 498 return ocr;
Chris@16 499 }
Chris@16 500 } // namespace detail
Chris@16 501
Chris@16 502 // Algorithms
Chris@16 503 // Maximum Cycle Ratio
Chris@16 504
Chris@16 505 template <
Chris@16 506 typename FloatTraits,
Chris@16 507 typename Graph,
Chris@16 508 typename VertexIndexMap,
Chris@16 509 typename EdgeWeight1Map,
Chris@16 510 typename EdgeWeight2Map>
Chris@16 511 inline typename FloatTraits::value_type
Chris@16 512 maximum_cycle_ratio(const Graph &g, VertexIndexMap vim, EdgeWeight1Map ew1m,
Chris@16 513 EdgeWeight2Map ew2m,
Chris@16 514 std::vector<typename graph_traits<Graph>::edge_descriptor>* pcc = 0,
Chris@16 515 FloatTraits = FloatTraits())
Chris@16 516 {
Chris@16 517 typedef detail::float_wrapper<
Chris@16 518 FloatTraits, detail::max_comparator_props<FloatTraits>
Chris@16 519 > Traits;
Chris@16 520 return detail::optimum_cycle_ratio<Traits>(g, vim, ew1m, ew2m, pcc);
Chris@16 521 }
Chris@16 522
Chris@16 523 template <
Chris@16 524 typename Graph,
Chris@16 525 typename VertexIndexMap,
Chris@16 526 typename EdgeWeight1Map,
Chris@16 527 typename EdgeWeight2Map>
Chris@16 528 inline double
Chris@16 529 maximum_cycle_ratio(const Graph &g, VertexIndexMap vim,
Chris@16 530 EdgeWeight1Map ew1m, EdgeWeight2Map ew2m,
Chris@16 531 std::vector<typename graph_traits<Graph>::edge_descriptor>* pcc = 0)
Chris@16 532 { return maximum_cycle_ratio(g, vim, ew1m, ew2m, pcc, mcr_float<>()); }
Chris@16 533
Chris@16 534 // Minimum Cycle Ratio
Chris@16 535
Chris@16 536 template <
Chris@16 537 typename FloatTraits,
Chris@16 538 typename Graph,
Chris@16 539 typename VertexIndexMap,
Chris@16 540 typename EdgeWeight1Map,
Chris@16 541 typename EdgeWeight2Map>
Chris@16 542 typename FloatTraits::value_type
Chris@16 543 minimum_cycle_ratio(const Graph &g, VertexIndexMap vim,
Chris@16 544 EdgeWeight1Map ew1m, EdgeWeight2Map ew2m,
Chris@16 545 std::vector<typename graph_traits<Graph>::edge_descriptor> *pcc = 0,
Chris@16 546 FloatTraits = FloatTraits())
Chris@16 547 {
Chris@16 548 typedef detail::float_wrapper<
Chris@16 549 FloatTraits, detail::min_comparator_props<FloatTraits>
Chris@16 550 > Traits;
Chris@16 551 return detail::optimum_cycle_ratio<Traits>(g, vim, ew1m, ew2m, pcc);
Chris@16 552 }
Chris@16 553
Chris@16 554 template <
Chris@16 555 typename Graph,
Chris@16 556 typename VertexIndexMap,
Chris@16 557 typename EdgeWeight1Map,
Chris@16 558 typename EdgeWeight2Map>
Chris@16 559 inline double
Chris@16 560 minimum_cycle_ratio(const Graph &g, VertexIndexMap vim,
Chris@16 561 EdgeWeight1Map ew1m, EdgeWeight2Map ew2m,
Chris@16 562 std::vector<typename graph_traits<Graph>::edge_descriptor>* pcc = 0)
Chris@16 563 { return minimum_cycle_ratio(g, vim, ew1m, ew2m, pcc, mcr_float<>()); }
Chris@16 564
Chris@16 565 // Maximum Cycle Mean
Chris@16 566
Chris@16 567 template <
Chris@16 568 typename FloatTraits,
Chris@16 569 typename Graph,
Chris@16 570 typename VertexIndexMap,
Chris@16 571 typename EdgeWeightMap,
Chris@16 572 typename EdgeIndexMap>
Chris@16 573 inline typename FloatTraits::value_type
Chris@16 574 maximum_cycle_mean(const Graph &g, VertexIndexMap vim,
Chris@16 575 EdgeWeightMap ewm, EdgeIndexMap eim,
Chris@16 576 std::vector<typename graph_traits<Graph>::edge_descriptor>* pcc = 0,
Chris@16 577 FloatTraits ft = FloatTraits())
Chris@16 578 {
Chris@16 579 typedef typename remove_const<
Chris@16 580 typename property_traits<EdgeWeightMap>::value_type
Chris@16 581 >::type Weight;
Chris@16 582 typename std::vector<Weight> ed_w2(boost::num_edges(g), 1);
Chris@16 583 return maximum_cycle_ratio(g, vim, ewm,
Chris@16 584 make_iterator_property_map(ed_w2.begin(), eim),
Chris@16 585 pcc, ft);
Chris@16 586 }
Chris@16 587
Chris@16 588 template <
Chris@16 589 typename Graph,
Chris@16 590 typename VertexIndexMap,
Chris@16 591 typename EdgeWeightMap,
Chris@16 592 typename EdgeIndexMap>
Chris@16 593 inline double
Chris@16 594 maximum_cycle_mean(const Graph& g, VertexIndexMap vim,
Chris@16 595 EdgeWeightMap ewm, EdgeIndexMap eim,
Chris@16 596 std::vector<typename graph_traits<Graph>::edge_descriptor>* pcc = 0)
Chris@16 597 { return maximum_cycle_mean(g, vim, ewm, eim, pcc, mcr_float<>()); }
Chris@16 598
Chris@16 599 // Minimum Cycle Mean
Chris@16 600
Chris@16 601 template <
Chris@16 602 typename FloatTraits,
Chris@16 603 typename Graph,
Chris@16 604 typename VertexIndexMap,
Chris@16 605 typename EdgeWeightMap,
Chris@16 606 typename EdgeIndexMap>
Chris@16 607 inline typename FloatTraits::value_type
Chris@16 608 minimum_cycle_mean(const Graph &g, VertexIndexMap vim,
Chris@16 609 EdgeWeightMap ewm, EdgeIndexMap eim,
Chris@16 610 std::vector<typename graph_traits<Graph>::edge_descriptor>* pcc = 0,
Chris@16 611 FloatTraits ft = FloatTraits())
Chris@16 612 {
Chris@16 613 typedef typename remove_const<
Chris@16 614 typename property_traits<EdgeWeightMap>::value_type
Chris@16 615 >::type Weight;
Chris@16 616 typename std::vector<Weight> ed_w2(boost::num_edges(g), 1);
Chris@16 617 return minimum_cycle_ratio(g, vim, ewm,
Chris@16 618 make_iterator_property_map(ed_w2.begin(), eim),
Chris@16 619 pcc, ft);
Chris@16 620 }
Chris@16 621
Chris@16 622 template <
Chris@16 623 typename Graph,
Chris@16 624 typename VertexIndexMap,
Chris@16 625 typename EdgeWeightMap,
Chris@16 626 typename EdgeIndexMap>
Chris@16 627 inline double
Chris@16 628 minimum_cycle_mean(const Graph &g, VertexIndexMap vim,
Chris@16 629 EdgeWeightMap ewm, EdgeIndexMap eim,
Chris@16 630 std::vector<typename graph_traits<Graph>::edge_descriptor>* pcc = 0)
Chris@16 631 { return minimum_cycle_mean(g, vim, ewm, eim, pcc, mcr_float<>()); }
Chris@16 632
Chris@16 633 } //namespace boost
Chris@16 634
Chris@16 635 #endif