sl@0: //======================================================================= sl@0: // Copyright 1997, 1998, 1999, 2000 University of Notre Dame. sl@0: // Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek, sl@0: // sl@0: // Distributed under the Boost Software License, Version 1.0. (See sl@0: // accompanying file LICENSE_1_0.txt or copy at sl@0: // http://www.boost.org/LICENSE_1_0.txt) sl@0: //======================================================================= sl@0: #ifndef BOOST_GRAPH_RELAX_HPP sl@0: #define BOOST_GRAPH_RELAX_HPP sl@0: sl@0: #include sl@0: #include // for numeric limits sl@0: #include sl@0: #include sl@0: sl@0: namespace boost { sl@0: sl@0: // The following version of the plus functor prevents sl@0: // problems due to overflow at positive infinity. sl@0: sl@0: template sl@0: struct closed_plus sl@0: { sl@0: // std::abs just isn't portable :( sl@0: template sl@0: inline X my_abs(const X& x) const { return x < 0 ? -x : x; } sl@0: sl@0: T operator()(const T& a, const T& b) const { sl@0: using namespace std; sl@0: T inf = (numeric_limits::max)(); sl@0: if (b > 0 && my_abs(inf - a) < b) sl@0: return inf; sl@0: return a + b; sl@0: } sl@0: }; sl@0: sl@0: template sl@0: bool relax(typename graph_traits::edge_descriptor e, sl@0: const Graph& g, const WeightMap& w, sl@0: PredecessorMap& p, DistanceMap& d, sl@0: const BinaryFunction& combine, const BinaryPredicate& compare) sl@0: { sl@0: typedef typename graph_traits::directed_category DirCat; sl@0: bool is_undirected = is_same::value; sl@0: typedef typename graph_traits::vertex_descriptor Vertex; sl@0: Vertex u = source(e, g), v = target(e, g); sl@0: typedef typename property_traits::value_type D; sl@0: typedef typename property_traits::value_type W; sl@0: D d_u = get(d, u), d_v = get(d, v); sl@0: W w_e = get(w, e); sl@0: sl@0: if ( compare(combine(d_u, w_e), d_v) ) { sl@0: put(d, v, combine(d_u, w_e)); sl@0: put(p, v, u); sl@0: return true; sl@0: } else if (is_undirected && compare(combine(d_v, w_e), d_u)) { sl@0: put(d, u, combine(d_v, w_e)); sl@0: put(p, u, v); sl@0: return true; sl@0: } else sl@0: return false; sl@0: } sl@0: sl@0: template sl@0: bool relax(typename graph_traits::edge_descriptor e, sl@0: const Graph& g, WeightMap w, PredecessorMap p, DistanceMap d) sl@0: { sl@0: typedef typename property_traits::value_type D; sl@0: typedef closed_plus Combine; sl@0: typedef std::less Compare; sl@0: return relax(e, g, w, p, d, Combine(), Compare()); sl@0: } sl@0: sl@0: } // namespace boost sl@0: sl@0: #endif /* BOOST_GRAPH_RELAX_HPP */