2
0
mirror of https://github.com/boostorg/graph.git synced 2026-01-19 04:12:11 +00:00

This commit was manufactured by cvs2svn to create tag 'boost++graph'.

[SVN r24506]
This commit is contained in:
nobody
2004-08-16 14:12:15 +00:00
parent d711937ec8
commit 51eb40aaa3
86 changed files with 39 additions and 25386 deletions

View File

@@ -332,26 +332,6 @@ Automata, Languages and Programming, 376-386, 1986
<EM>A Transitive Closure Algorithm</EM><br>
BIT, 10, 1970, pp. 76-94.
<p></p><dt><a name="brandes01">54</a>
<dd>Ulrik Brandes<br>
<em><a href="http://ella.slis.indiana.edu/~katy/L579/brandes.pdf">A
Faster Algorithm for Betweenness Centrality</a></em><br>
Journal of Mathematical Sociology 25 (2):163-177, 2001.
<p></p><dt><a name="freeman77">55</a>
<dd>Lindon C. Freeman<br>
<em>A Set of Measures of Centrality Based on Betweenness</em><br>
Sociometry 40, pp. 35-41, 1977.
<p></p><dt><a name="anthonisse71">56</a>
<dd>J.M. Anthonisse<br>
<em>The rush in a directed graph.</em><br>
Technical Report BN9/71, Stichting Mahtematisch Centrum, Amsterdam, 1971.
<p></p><dt><a name="kamada89">57</a>
<dd>T. Kamada and S. Kawai<br>
<em>An algorithm for drawing general undirected graphs.</em><br>
Information Processing Letters, 31, pp. 7-15, 1989.
</DL>
<br>

View File

@@ -132,21 +132,21 @@
</OL>
<LI>Graph Algorithms
<OL>
<LI>Shortest Paths Algorithms
<LI>Shortest Paths Algorithms
<OL>
<LI><A href="./dijkstra_shortest_paths.html"><tt>dijkstra_shortest_paths</tt></A>
<LI><A href="./bellman_ford_shortest.html"><tt>bellman_ford_shortest_paths</tt></A>
<LI><A href="./dag_shortest_paths.html"><tt>dag_shortest_paths</tt></A>
<LI><A
href="./johnson_all_pairs_shortest.html"><tt>johnson_all_pairs_shortest_paths</tt></A>
<LI><A href="./dijkstra_shortest_paths.html"><tt>dijkstra_shortest_paths</tt></A>
<LI><A href="./bellman_ford_shortest.html"><tt>bellman_ford_shortest_paths</tt></A>
<LI><A href="./dag_shortest_paths.html"><tt>dag_shortest_paths</tt></A>
<LI><A
href="./johnson_all_pairs_shortest.html"><tt>johnson_all_pairs_shortest_paths</tt></A>
</OL>
<LI>Minimum Spanning Tree Algorithms
<OL>
<LI><A
href="./kruskal_min_spanning_tree.html"><tt>kruskal_minimum_spanning_tree</tt></A>
<LI><A
href="./prim_minimum_spanning_tree.html"><tt>prim_minimum_spanning_tree</tt></A>
</OL>
<OL>
<LI><A
href="./kruskal_min_spanning_tree.html"><tt>kruskal_minimum_spanning_tree</tt></A>
<LI><A
href="./prim_minimum_spanning_tree.html"><tt>prim_minimum_spanning_tree</tt></A>
</OL>
<LI><A href="./connected_components.html"><tt>connected_components</tt></A>
<LI><A href="./strong_components.html"><tt>strong_components</tt></A>
@@ -175,29 +175,17 @@
<LI><A
href="../../../boost/graph/sequential_vertex_coloring.hpp"><tt>sequential_vertex_coloring</tt></A><a
href="#*">*</a>
<LI><a href="./minimum_degree_ordering.html"><tt>minimum_degree_ordering</tt></a>
<LI><a href="./minimum_degree_ordering.html"><tt>minimum_degree_ordering</tt></a>
<li><a href="./sloan_ordering.htm"><tt>sloan_ordering</tt></a></li>
<LI><A href="./wavefront.htm"><tt>ith_wavefront</tt>, <tt>max_wavefront</tt>, <tt>aver_wavefront</tt>, and <tt>rms_wavefront</tt></A></LI>
<LI><A href="brandes_betweenness_centrality.html"><tt>brandes_betweenness_centrality</tt></A></LI>
<li>Layout algorithms
<ol>
<li><a href="circle_layout.html"><tt>circle_layout</tt></a></li>
<li><a href="kamada_kawai_spring_layout.html"><tt>kamada_kawai_spring_layout</tt></a></li>
</ol>
</li>
<li>Clustering algorithms
<ol>
<li><a href="betweenness_centrality_clustering.html"><tt>betweenness_centrality_clustering</tt></li>
</ol>
</li>
</OL>
</OL>
<LI>AT&amp;T Graphviz Read/Write Utilities
<OL>
<LI><a href="./write-graphviz.html">write_graphviz</a>
<LI><a href="./read-graphviz.html">read_graphviz</a>
</OL>
<LI><a href="./write-graphviz.html">write_graphviz</a>
<LI><a href="./read-graphviz.html">read_graphviz</a>
</OL>
<LI>Auxiliary Concepts, Classes, and Functions
<OL>
@@ -207,8 +195,8 @@
<LI><a href="./BasicMatrix.html">BasicMatrix</a>
<LI><a href="./incident.html"><tt>incident</tt></a>
<LI><a href="./opposite.html"><tt>opposite</tt></a>
<LI><a href="./bandwidth.html#sec:bandwidth"><tt>bandwidth</tt></a>
<LI><a href="./bandwidth.html#sec:ith-bandwidth"><tt>ith_bandwidth</tt></a>
<LI><a href="./bandwidth.html#sec:bandwidth"><tt>bandwidth</tt></a>
<LI><a href="./bandwidth.html#sec:ith-bandwidth"><tt>ith_bandwidth</tt></a>
<LI><a href="./random.html">Tools for random graphs</a>
<OL>
<LI><a href="./random.html#random_vertex">random_vertex</a>

View File

@@ -1,116 +0,0 @@
//=======================================================================
// Copyright 2002 Indiana University.
// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek
//
// This file is part of the Boost Graph Library
//
// You should have received a copy of the License Agreement for the
// Boost Graph Library along with the software; see the file LICENSE.
//
// Permission to modify the code and to distribute modified code is
// granted, provided the text of this NOTICE is retained, a notice that
// the code was modified is included with the above COPYRIGHT NOTICE and
// with the COPYRIGHT NOTICE in the LICENSE file, and that the LICENSE
// file is distributed with the modified code.
//
// LICENSOR MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED.
// By way of example, but not limitation, Licensor MAKES NO
// REPRESENTATIONS OR WARRANTIES OF MERCHANTABILITY OR FITNESS FOR ANY
// PARTICULAR PURPOSE OR THAT THE USE OF THE LICENSED SOFTWARE COMPONENTS
// OR DOCUMENTATION WILL NOT INFRINGE ANY PATENTS, COPYRIGHTS, TRADEMARKS
// OR OTHER RIGHTS.
//=======================================================================
#ifndef BOOST_ADJACENCY_ITERATOR_HPP
#define BOOST_ADJACENCY_ITERATOR_HPP
#include <boost/iterator/iterator_adaptor.hpp>
#include <boost/graph/graph_traits.hpp>
namespace boost
{
template <class Graph, class Vertex, class OutEdgeIter, class Difference>
struct adjacency_iterator
: iterator_adaptor<
adjacency_iterator<Graph,Vertex,OutEdgeIter,Difference>
, OutEdgeIter
, Vertex
, use_default
, Vertex
, Difference
>
{
typedef iterator_adaptor<
adjacency_iterator<Graph,Vertex,OutEdgeIter,Difference>
, OutEdgeIter
, Vertex
, use_default
, Vertex
, Difference
> super_t;
inline adjacency_iterator() {}
inline adjacency_iterator(OutEdgeIter const& i, const Graph* g) : super_t(i), m_g(g) { }
inline Vertex
dereference() const
{ return target(*this->base(), *m_g); }
const Graph* m_g;
};
template <class Graph,
class Vertex = typename graph_traits<Graph>::vertex_descriptor,
class OutEdgeIter=typename graph_traits<Graph>::out_edge_iterator>
class adjacency_iterator_generator
{
typedef typename boost::detail::iterator_traits<OutEdgeIter>
::difference_type difference_type;
public:
typedef adjacency_iterator<Graph,Vertex,OutEdgeIter,difference_type> type;
};
template <class Graph, class Vertex, class InEdgeIter, class Difference>
struct inv_adjacency_iterator
: iterator_adaptor<
inv_adjacency_iterator<Graph,Vertex,InEdgeIter,Difference>
, InEdgeIter
, Vertex
, use_default
, Vertex
, Difference
>
{
typedef iterator_adaptor<
inv_adjacency_iterator<Graph,Vertex,InEdgeIter,Difference>
, InEdgeIter
, Vertex
, use_default
, Vertex
, Difference
> super_t;
inline inv_adjacency_iterator() { }
inline inv_adjacency_iterator(InEdgeIter const& i, const Graph* g) : super_t(i), m_g(g) { }
inline Vertex
dereference() const
{ return source(*this->base(), *m_g); }
const Graph* m_g;
};
template <class Graph,
class Vertex = typename graph_traits<Graph>::vertex_descriptor,
class InEdgeIter = typename graph_traits<Graph>::in_edge_iterator>
class inv_adjacency_iterator_generator {
typedef typename boost::detail::iterator_traits<InEdgeIter>
::difference_type difference_type;
public:
typedef inv_adjacency_iterator<Graph, Vertex, InEdgeIter, difference_type> type;
};
} // namespace boost
#endif // BOOST_DETAIL_ADJACENCY_ITERATOR_HPP

View File

@@ -1,548 +0,0 @@
//=======================================================================
// Copyright 1997, 1998, 1999, 2000 University of Notre Dame.
// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek
//
// This file is part of the Boost Graph Library
//
// You should have received a copy of the License Agreement for the
// Boost Graph Library along with the software; see the file LICENSE.
// If not, contact Office of Research, University of Notre Dame, Notre
// Dame, IN 46556.
//
// Permission to modify the code and to distribute modified code is
// granted, provided the text of this NOTICE is retained, a notice that
// the code was modified is included with the above COPYRIGHT NOTICE and
// with the COPYRIGHT NOTICE in the LICENSE file, and that the LICENSE
// file is distributed with the modified code.
//
// LICENSOR MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED.
// By way of example, but not limitation, Licensor MAKES NO
// REPRESENTATIONS OR WARRANTIES OF MERCHANTABILITY OR FITNESS FOR ANY
// PARTICULAR PURPOSE OR THAT THE USE OF THE LICENSED SOFTWARE COMPONENTS
// OR DOCUMENTATION WILL NOT INFRINGE ANY PATENTS, COPYRIGHTS, TRADEMARKS
// OR OTHER RIGHTS.
//=======================================================================
#ifndef BOOST_GRAPH_ADJACENCY_LIST_HPP
#define BOOST_GRAPH_ADJACENCY_LIST_HPP
#include <boost/config.hpp>
#include <vector>
#include <list>
#include <set>
#if !defined BOOST_NO_HASH
#include <hash_set>
#endif
#if !defined BOOST_NO_SLIST
#include <slist>
#endif
#include <boost/graph/graph_traits.hpp>
#include <boost/graph/graph_selectors.hpp>
#include <boost/property_map.hpp>
#include <boost/pending/ct_if.hpp>
#include <boost/graph/detail/edge.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/detail/workaround.hpp>
#include <boost/graph/properties.hpp>
namespace boost {
//===========================================================================
// Selectors for the VertexList and EdgeList template parameters of
// adjacency_list, and the container_gen traits class which is used
// to map the selectors to the container type used to implement the
// graph.
//
// The main container_gen traits class uses partial specialization,
// so we also include a workaround.
#if !defined BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
#if !defined BOOST_NO_SLIST
struct slistS {};
#endif
struct vecS { };
struct listS { };
struct setS { };
struct multisetS { };
struct mapS { };
#if !defined BOOST_NO_HASH
struct hash_mapS { };
struct hash_setS { };
#endif
template <class Selector, class ValueType>
struct container_gen { };
template <class ValueType>
struct container_gen<listS, ValueType> {
typedef std::list<ValueType> type;
};
#if !defined BOOST_NO_SLIST
template <class ValueType>
struct container_gen<slistS, ValueType> {
typedef BOOST_STD_EXTENSION_NAMESPACE::slist<ValueType> type;
};
#endif
template <class ValueType>
struct container_gen<vecS, ValueType> {
typedef std::vector<ValueType> type;
};
template <class ValueType>
struct container_gen<mapS, ValueType> {
typedef std::set<ValueType> type;
};
template <class ValueType>
struct container_gen<setS, ValueType> {
typedef std::set<ValueType> type;
};
template <class ValueType>
struct container_gen<multisetS, ValueType> {
typedef std::multiset<ValueType> type;
};
#if !defined BOOST_NO_HASH
template <class ValueType>
struct container_gen<hash_mapS, ValueType> {
typedef BOOST_STD_EXTENSION_NAMESPACE::hash_set<ValueType> type;
};
template <class ValueType>
struct container_gen<hash_setS, ValueType> {
typedef BOOST_STD_EXTENSION_NAMESPACE::hash_set<ValueType> type;
};
#endif
#else // !defined BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
#if !defined BOOST_NO_SLIST
struct slistS {
template <class T>
struct bind_ { typedef std::slist<T> type; };
};
#endif
struct vecS {
template <class T>
struct bind_ { typedef std::vector<T> type; };
};
struct listS {
template <class T>
struct bind_ { typedef std::list<T> type; };
};
struct setS {
template <class T>
struct bind_ { typedef std::set<T, std::less<T> > type; };
};
struct multisetS {
template <class T>
struct bind_ { typedef std::multiset<T, std::less<T> > type; };
};
#if !defined BOOST_NO_HASH
struct hash_setS {
template <class T>
struct bind_ { typedef BOOST_STD_EXTENSION_NAMESPACE::hash_set<T, std::less<T> > type; };
};
#endif
struct mapS {
template <class T>
struct bind_ { typedef std::set<T, std::less<T> > type; };
};
#if !defined BOOST_NO_HASH
struct hash_mapS {
template <class T>
struct bind_ { typedef BOOST_STD_EXTENSION_NAMESPACE::hash_set<T, std::less<T> > type; };
};
#endif
template <class Selector> struct container_selector {
typedef vecS type;
};
#define BOOST_CONTAINER_SELECTOR(NAME) \
template <> struct container_selector<NAME> { \
typedef NAME type; \
}
BOOST_CONTAINER_SELECTOR(vecS);
BOOST_CONTAINER_SELECTOR(listS);
BOOST_CONTAINER_SELECTOR(mapS);
BOOST_CONTAINER_SELECTOR(setS);
BOOST_CONTAINER_SELECTOR(multisetS);
#if !defined BOOST_NO_HASH
BOOST_CONTAINER_SELECTOR(hash_mapS);
#endif
#if !defined BOOST_NO_SLIST
BOOST_CONTAINER_SELECTOR(slistS);
#endif
template <class Selector, class ValueType>
struct container_gen {
typedef typename container_selector<Selector>::type Select;
typedef typename Select:: template bind_<ValueType>::type type;
};
#endif // !defined BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
template <class StorageSelector>
struct parallel_edge_traits { };
template <>
struct parallel_edge_traits<vecS> {
typedef allow_parallel_edge_tag type; };
template <>
struct parallel_edge_traits<listS> {
typedef allow_parallel_edge_tag type; };
#if !defined BOOST_NO_SLIST
template <>
struct parallel_edge_traits<slistS> {
typedef allow_parallel_edge_tag type; };
#endif
template <>
struct parallel_edge_traits<setS> {
typedef disallow_parallel_edge_tag type; };
template <>
struct parallel_edge_traits<multisetS> {
typedef allow_parallel_edge_tag type; };
#if !defined BOOST_NO_HASH
template <>
struct parallel_edge_traits<hash_setS> {
typedef disallow_parallel_edge_tag type;
};
#endif
// mapS is obsolete, replaced with setS
template <>
struct parallel_edge_traits<mapS> {
typedef disallow_parallel_edge_tag type; };
#if !defined BOOST_NO_HASH
template <>
struct parallel_edge_traits<hash_mapS> {
typedef disallow_parallel_edge_tag type;
};
#endif
namespace detail {
template <class Directed> struct is_random_access {
enum { value = false};
typedef false_type type;
};
template <>
struct is_random_access<vecS> {
enum { value = true };
typedef true_type type;
};
} // namespace detail
//===========================================================================
// The adjacency_list_traits class, which provides a way to access
// some of the associated types of an adjacency_list type without
// having to first create the adjacency_list type. This is useful
// when trying to create interior vertex or edge properties who's
// value type is a vertex or edge descriptor.
template <class OutEdgeListS = vecS,
class VertexListS = vecS,
class DirectedS = directedS>
struct adjacency_list_traits
{
typedef typename detail::is_random_access<VertexListS>::type
is_rand_access;
typedef typename DirectedS::is_bidir_t is_bidir;
typedef typename DirectedS::is_directed_t is_directed;
typedef typename boost::ct_if_t<is_bidir,
bidirectional_tag,
typename boost::ct_if_t<is_directed,
directed_tag, undirected_tag
>::type
>::type directed_category;
typedef typename parallel_edge_traits<OutEdgeListS>::type
edge_parallel_category;
typedef void* vertex_ptr;
typedef typename boost::ct_if_t<is_rand_access,
std::size_t, vertex_ptr>::type vertex_descriptor;
typedef detail::edge_desc_impl<directed_category, vertex_descriptor>
edge_descriptor;
};
} // namespace boost
#include <boost/graph/detail/adjacency_list.hpp>
namespace boost {
//===========================================================================
// The adjacency_list class.
//
template <class OutEdgeListS = vecS, // a Sequence or an AssociativeContainer
class VertexListS = vecS, // a Sequence or a RandomAccessContainer
class DirectedS = directedS,
class VertexProperty = no_property,
class EdgeProperty = no_property,
class GraphProperty = no_property,
class EdgeListS = listS>
class adjacency_list
: public detail::adj_list_gen<
adjacency_list<OutEdgeListS,VertexListS,DirectedS,
VertexProperty,EdgeProperty,GraphProperty,EdgeListS>,
VertexListS, OutEdgeListS, DirectedS,
#if !defined(BOOST_GRAPH_NO_BUNDLED_PROPERTIES)
typename detail::retag_property_list<vertex_bundle_t,
VertexProperty>::type,
typename detail::retag_property_list<edge_bundle_t, EdgeProperty>::type,
#else
VertexProperty, EdgeProperty,
#endif
GraphProperty, EdgeListS>::type
{
#if !defined(BOOST_GRAPH_NO_BUNDLED_PROPERTIES)
typedef typename detail::retag_property_list<vertex_bundle_t,
VertexProperty>::retagged
maybe_vertex_bundled;
typedef typename detail::retag_property_list<edge_bundle_t,
EdgeProperty>::retagged
maybe_edge_bundled;
#endif
struct no_vertex_bundle {};
struct no_edge_bundle {};
public:
#if !defined(BOOST_GRAPH_NO_BUNDLED_PROPERTIES)
typedef typename detail::retag_property_list<vertex_bundle_t,
VertexProperty>::type
vertex_property_type;
typedef typename detail::retag_property_list<edge_bundle_t,
EdgeProperty>::type
edge_property_type;
// The types that are actually bundled
typedef typename ct_if<(is_same<maybe_vertex_bundled, no_property>::value),
no_vertex_bundle,
maybe_vertex_bundled>::type vertex_bundled;
typedef typename ct_if<(is_same<maybe_edge_bundled, no_property>::value),
no_edge_bundle,
maybe_edge_bundled>::type edge_bundled;
#else
typedef VertexProperty vertex_property_type;
typedef EdgeProperty edge_property_type;
typedef no_vertex_bundle vertex_bundled;
typedef no_edge_bundle edge_bundled;
#endif
private:
typedef adjacency_list self;
typedef typename detail::adj_list_gen<
self, VertexListS, OutEdgeListS, DirectedS,
vertex_property_type, edge_property_type, GraphProperty, EdgeListS
>::type Base;
public:
typedef typename Base::stored_vertex stored_vertex;
typedef typename Base::vertices_size_type vertices_size_type;
typedef typename Base::edges_size_type edges_size_type;
typedef typename Base::degree_size_type degree_size_type;
typedef typename Base::vertex_descriptor vertex_descriptor;
typedef typename Base::edge_descriptor edge_descriptor;
typedef GraphProperty graph_property_type;
inline adjacency_list(const GraphProperty& p = GraphProperty())
: m_property(p) { }
inline adjacency_list(const adjacency_list& x)
: Base(x), m_property(x.m_property) { }
inline adjacency_list& operator=(const adjacency_list& x) {
Base::operator=(x);
m_property = x.m_property;
return *this;
}
// Required by Mutable Graph
inline adjacency_list(vertices_size_type num_vertices,
const GraphProperty& p = GraphProperty())
: Base(num_vertices), m_property(p) { }
#if !defined(BOOST_MSVC) || BOOST_MSVC > 1300
// Required by Iterator Constructible Graph
template <class EdgeIterator>
inline adjacency_list(EdgeIterator first, EdgeIterator last,
vertices_size_type n,
edges_size_type m = 0,
const GraphProperty& p = GraphProperty())
: Base(n, first, last), m_property(p) { }
template <class EdgeIterator, class EdgePropertyIterator>
inline adjacency_list(EdgeIterator first, EdgeIterator last,
EdgePropertyIterator ep_iter,
vertices_size_type n,
edges_size_type m = 0,
const GraphProperty& p = GraphProperty())
: Base(n, first, last, ep_iter), m_property(p) { }
#endif
void swap(adjacency_list& x) {
// Is there a more efficient way to do this?
adjacency_list tmp(x);
x = *this;
*this = tmp;
}
#ifndef BOOST_GRAPH_NO_BUNDLED_PROPERTIES
// Directly access a vertex or edge bundle
vertex_bundled& operator[](vertex_descriptor v)
{ return get(vertex_bundle, *this)[v]; }
const vertex_bundled& operator[](vertex_descriptor v) const
{ return get(vertex_bundle, *this)[v]; }
edge_bundled& operator[](edge_descriptor e)
{ return get(edge_bundle, *this)[e]; }
const edge_bundled& operator[](edge_descriptor e) const
{ return get(edge_bundle, *this)[e]; }
#endif
// protected: (would be protected if friends were more portable)
GraphProperty m_property;
};
template <class OEL, class VL, class DS, class VP,class EP, class GP,
class EL, class Tag, class Value>
inline void
set_property(adjacency_list<OEL,VL,DS,VP,EP,GP,EL>& g, Tag,
const Value& value) {
get_property_value(g.m_property, Tag()) = value;;
}
template <class OEL, class VL, class DS, class VP, class EP, class GP,
class Tag, class EL>
inline
typename graph_property<adjacency_list<OEL,VL,DS,VP,EP,GP,EL>, Tag>::type&
get_property(adjacency_list<OEL,VL,DS,VP,EP,GP,EL>& g, Tag) {
return get_property_value(g.m_property, Tag());
}
template <class OEL, class VL, class DS, class VP, class EP, class GP,
class Tag, class EL>
inline
const
typename graph_property<adjacency_list<OEL,VL,DS,VP,EP,GP,EL>, Tag>::type&
get_property(const adjacency_list<OEL,VL,DS,VP,EP,GP,EL>& g, Tag) {
return get_property_value(g.m_property, Tag());
}
// dwa 09/25/00 - needed to be more explicit so reverse_graph would work.
template <class Directed, class Vertex,
class OutEdgeListS,
class VertexListS,
class DirectedS,
class VertexProperty,
class EdgeProperty,
class GraphProperty, class EdgeListS>
inline Vertex
source(const detail::edge_base<Directed,Vertex>& e,
const adjacency_list<OutEdgeListS, VertexListS, DirectedS,
VertexProperty, EdgeProperty, GraphProperty, EdgeListS>&)
{
return e.m_source;
}
template <class Directed, class Vertex, class OutEdgeListS,
class VertexListS, class DirectedS, class VertexProperty,
class EdgeProperty, class GraphProperty, class EdgeListS>
inline Vertex
target(const detail::edge_base<Directed,Vertex>& e,
const adjacency_list<OutEdgeListS, VertexListS, DirectedS,
VertexProperty, EdgeProperty, GraphProperty, EdgeListS>&)
{
return e.m_target;
}
// Support for bundled properties
#ifndef BOOST_GRAPH_NO_BUNDLED_PROPERTIES
template<typename OutEdgeListS, typename VertexListS, typename DirectedS, typename VertexProperty,
typename EdgeProperty, typename GraphProperty, typename EdgeListS, typename T, typename Bundle>
inline
typename property_map<adjacency_list<OutEdgeListS, VertexListS, DirectedS, VertexProperty, EdgeProperty,
GraphProperty, EdgeListS>, T Bundle::*>::type
get(T Bundle::* p, adjacency_list<OutEdgeListS, VertexListS, DirectedS, VertexProperty, EdgeProperty,
GraphProperty, EdgeListS>& g)
{
typedef typename property_map<adjacency_list<OutEdgeListS, VertexListS, DirectedS, VertexProperty,
EdgeProperty, GraphProperty, EdgeListS>, T Bundle::*>::type
result_type;
return result_type(&g, p);
}
template<typename OutEdgeListS, typename VertexListS, typename DirectedS, typename VertexProperty,
typename EdgeProperty, typename GraphProperty, typename EdgeListS, typename T, typename Bundle>
inline
typename property_map<adjacency_list<OutEdgeListS, VertexListS, DirectedS, VertexProperty, EdgeProperty,
GraphProperty, EdgeListS>, T Bundle::*>::const_type
get(T Bundle::* p, adjacency_list<OutEdgeListS, VertexListS, DirectedS, VertexProperty, EdgeProperty,
GraphProperty, EdgeListS> const & g)
{
typedef typename property_map<adjacency_list<OutEdgeListS, VertexListS, DirectedS, VertexProperty,
EdgeProperty, GraphProperty, EdgeListS>, T Bundle::*>::const_type
result_type;
return result_type(&g, p);
}
template<typename OutEdgeListS, typename VertexListS, typename DirectedS, typename VertexProperty,
typename EdgeProperty, typename GraphProperty, typename EdgeListS, typename T, typename Bundle,
typename Key>
inline T
get(T Bundle::* p, adjacency_list<OutEdgeListS, VertexListS, DirectedS, VertexProperty, EdgeProperty,
GraphProperty, EdgeListS> const & g, const Key& key)
{
return get(get(p, g), key);
}
template<typename OutEdgeListS, typename VertexListS, typename DirectedS, typename VertexProperty,
typename EdgeProperty, typename GraphProperty, typename EdgeListS, typename T, typename Bundle,
typename Key>
inline void
put(T Bundle::* p, adjacency_list<OutEdgeListS, VertexListS, DirectedS, VertexProperty, EdgeProperty,
GraphProperty, EdgeListS>& g, const Key& key, const T& value)
{
put(get(p, g), key, value);
}
#endif
} // namespace boost
#endif // BOOST_GRAPH_ADJACENCY_LIST_HPP

View File

@@ -1,375 +0,0 @@
//=======================================================================
// Copyright 2001 Universite Joseph Fourier, Grenoble.
// Author: François Faure
//
// This file is part of the Boost Graph Library
//
// You should have received a copy of the License Agreement for the
// Boost Graph Library along with the software; see the file LICENSE.
// If not, contact Office of Research, University of Notre Dame, Notre
// Dame, IN 46556.
//
// Permission to modify the code and to distribute modified code is
// granted, provided the text of this NOTICE is retained, a notice that
// the code was modified is included with the above COPYRIGHT NOTICE and
// with the COPYRIGHT NOTICE in the LICENSE file, and that the LICENSE
// file is distributed with the modified code.
//
// LICENSOR MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED.
// By way of example, but not limitation, Licensor MAKES NO
// REPRESENTATIONS OR WARRANTIES OF MERCHANTABILITY OR FITNESS FOR ANY
// PARTICULAR PURPOSE OR THAT THE USE OF THE LICENSED SOFTWARE COMPONENTS
// OR DOCUMENTATION WILL NOT INFRINGE ANY PATENTS, COPYRIGHTS, TRADEMARKS
// OR OTHER RIGHTS.
//=======================================================================
#ifndef ______adj_list_io_______
#define ______adj_list_io_______
#include <iostream>
#include <vector>
#include <boost/graph/adjacency_list.hpp>
#include <cctype>
// Method read to parse an adjacency list from an input stream. Examples:
// cin >> read( G );
// cin >> read( G, NodePropertySubset(), EdgepropertySubset() );
//
// Method write to print an adjacency list to an output stream. Examples:
// cout << write( G );
// cout << write( G, NodePropertySubset(), EdgepropertySubset() );
namespace boost {
/* outline
- basic property input
- get property subset
- graph parser
- property printer
- graph printer
- user methods
*/
//===========================================================================
// basic property input
template<class Tag, class Value, class Next>
std::istream& operator >> ( std::istream& in, property<Tag,Value,Next>& p )
{
in >> p.m_value >> *(static_cast<Next*>(&p)); // houpla !!
return in;
}
template<class Tag, class Value>
std::istream& operator >> ( std::istream& in, property<Tag,Value,no_property>& p )
{
in >> p.m_value;
return in;
}
inline std::istream& operator >> ( std::istream& in, no_property& )
{
return in;
}
// basic property input
//===========================================================================
// get property subsets
// get a single property tagged Stag
template<class Tag, class Value, class Next, class V, class Stag>
void get
( property<Tag,Value,Next>& p, const V& v, Stag s )
{
get( *(static_cast<Next*>(&p)),v,s );
}
template<class Value, class Next, class V, class Stag>
void get
( property<Stag,Value,Next>& p, const V& v, Stag )
{
p.m_value = v;
}
// get a subset of properties tagged Stag
template<class Tag, class Value, class Next,
class Stag, class Svalue, class Snext>
void getSubset
( property<Tag,Value,Next>& p, const property<Stag,Svalue,Snext>& s )
{
get( p, s.m_value, Stag() );
getSubset( p, Snext(s) );
}
template<class Tag, class Value, class Next,
class Stag, class Svalue>
void getSubset
( property<Tag,Value,Next>& p, const property<Stag,Svalue,no_property>& s )
{
get( p, s.m_value, Stag() );
}
inline void getSubset
( no_property& p, const no_property& s )
{
}
// get property subset
//===========================================================================
// graph parser
template<class Graph_t, class VertexProperty, class EdgeProperty, class VertexPropertySubset,
class EdgePropertySubset>
struct GraphParser
{
typedef Graph_t Graph;
GraphParser( Graph* g ): graph(g)
{}
GraphParser& operator () ( std::istream& in )
{
typedef typename graph_traits<Graph>::vertex_descriptor Vertex;
std::vector<Vertex> nodes;
typedef enum{ PARSE_NUM_NODES, PARSE_VERTEX, PARSE_EDGE } State;
State state = PARSE_VERTEX;
unsigned int numLine = 1;
char c;
while ( in.get(c) )
{
if( c== '#' ) skip(in);
else if( c== 'n' ) state = PARSE_NUM_NODES;
else if( c== 'v' ) state = PARSE_VERTEX;
else if( c== 'e' ) state = PARSE_EDGE;
else if( c== '\n' ) numLine++;
else if( !std::isspace(c) ){
in.putback(c);
if( state == PARSE_VERTEX ){
VertexPropertySubset readProp;
if( in >> readProp )
{
VertexProperty vp;
getSubset( vp, readProp );
nodes.push_back( add_vertex(vp, *graph) );
}
else
std::cerr<<"read vertex, parse error at line"<<numLine<<std::endl;
}
else if( state == PARSE_EDGE ) {
int source, target;
EdgePropertySubset readProp;
in >> source >> target;
if( in >> readProp )
{
EdgeProperty ep;
getSubset( ep, readProp );
add_edge(nodes[source], nodes[target], ep, *graph);
}
else
std::cerr<<"read edge, parse error at line"<<numLine<<std::endl;
}
else { // state == PARSE_NUM_NODES
int n;
if( in >> n ){
for( int i=0; i<n; ++i )
nodes.push_back( add_vertex( *graph ));
}
else
std::cerr<<"read num_nodes, parse error at line "<< numLine << std::endl;
}
}
}
return (*this);
}
protected:
Graph* graph;
void skip( std::istream& in )
{
char c = 0;
while( c!='\n' && !in.eof() )
in.get(c);
in.putback(c);
}
};
// parser
//=======================================================================
// property printer
template<class Graph, class Property>
struct PropertyPrinter
{
typedef typename Property::value_type Value;
typedef typename Property::tag_type Tag;
typedef typename Property::next_type Next;
PropertyPrinter( Graph& g ):graph(&g){}
template<class Iterator>
PropertyPrinter& operator () ( std::ostream& out, Iterator it )
{
typename property_map<Graph,Tag>::type ps = get(Tag(), *graph);
out << ps[ *it ] <<" ";
PropertyPrinter<Graph,Next> print(*graph);
print(out, it);
return (*this);
}
private:
Graph* graph;
};
template<class Graph>
struct PropertyPrinter<Graph, no_property>
{
PropertyPrinter( Graph& ){}
template<class Iterator>
PropertyPrinter& operator () ( std::ostream&, Iterator it ){ return *this; }
};
// property printer
//=========================================================================
// graph printer
template<class Graph_t, class EdgeProperty>
struct EdgePrinter
{
typedef Graph_t Graph;
typedef typename graph_traits<Graph>::vertex_descriptor Vertex;
EdgePrinter( Graph& g )
: graph(g)
{}
const EdgePrinter& operator () ( std::ostream& out ) const
{
// assign indices to vertices
std::map<Vertex,int> indices;
int num = 0;
typename graph_traits<Graph>::vertex_iterator vi;
for (vi = vertices(graph).first; vi != vertices(graph).second; ++vi){
indices[*vi] = num++;
}
// write edges
PropertyPrinter<Graph, EdgeProperty> print_Edge(graph);
out << "e" << std::endl;
typename graph_traits<Graph>::edge_iterator ei;
for (ei = edges(graph).first; ei != edges(graph).second; ++ei){
out << indices[source(*ei,graph)] << " " << indices[target(*ei,graph)] << " ";
print_Edge(out,ei);
out << std::endl;
}
out << std::endl;
return (*this);
}
protected:
Graph& graph;
};
template<class Graph, class V, class E>
struct GraphPrinter: public EdgePrinter<Graph,E>
{
GraphPrinter( Graph& g )
: EdgePrinter<Graph,E>(g)
{}
const GraphPrinter& operator () ( std::ostream& out ) const
{
PropertyPrinter<Graph, V> printNode(this->graph);
out << "v"<<std::endl;
typename graph_traits<Graph>::vertex_iterator vi;
for (vi = vertices(this->graph).first; vi != vertices(this->graph).second; ++vi){
printNode(out,vi);
out << std::endl;
}
EdgePrinter<Graph,E>::operator ()( out );
return (*this);
}
};
template<class Graph, class E>
struct GraphPrinter<Graph,no_property,E>
: public EdgePrinter<Graph,E>
{
GraphPrinter( Graph& g )
: EdgePrinter<Graph,E>(g)
{}
const GraphPrinter& operator () ( std::ostream& out ) const
{
out << "n "<< num_vertices(this->graph) << std::endl;
EdgePrinter<Graph,E>::operator ()( out );
return (*this);
}
};
// graph printer
//=========================================================================
// user methods
/// input stream for reading a graph
template<class Graph, class VP, class EP, class VPS, class EPS>
std::istream& operator >> ( std::istream& in, GraphParser<Graph,VP,EP,VPS,EPS> gp )
{
gp(in);
return in;
}
/// graph parser for given subsets of internal vertex and edge properties
template<class EL, class VL, class D, class VP, class EP, class GP, class VPS, class EPS>
GraphParser<adjacency_list<EL,VL,D,VP,EP,GP>,VP,EP,VPS,EPS>
read( adjacency_list<EL,VL,D,VP,EP,GP>& g, VPS vps, EPS eps )
{
return GraphParser<adjacency_list<EL,VL,D,VP,EP,GP>,VP,EP,VPS,EPS>(&g);
}
/// graph parser for all internal vertex and edge properties
template<class EL, class VL, class D, class VP, class EP, class GP>
GraphParser<adjacency_list<EL,VL,D,VP,EP,GP>,VP,EP,VP,EP>
read( adjacency_list<EL,VL,D,VP,EP,GP>& g )
{
return GraphParser<adjacency_list<EL,VL,D,VP,EP,GP>,VP,EP,VP,EP>(&g);
}
/// output stream for writing a graph
template<class Graph, class VP, class EP>
std::ostream& operator << ( std::ostream& out, const GraphPrinter<Graph,VP,EP>& gp )
{
gp(out);
return out;
}
/// write the graph with given property subsets
template<class EL, class VL, class D, class VP, class EP, class GP, class VPS, class EPS>
GraphPrinter<adjacency_list<EL,VL,D,VP,EP,GP>,VPS,EPS>
write( adjacency_list<EL,VL,D,VP,EP,GP>& g, VPS, EPS )
{
return GraphPrinter<adjacency_list<EL,VL,D,VP,EP,GP>,VPS,EPS>(g);
}
/// write the graph with all internal vertex and edge properties
template<class EL, class VL, class D, class VP, class EP, class GP>
GraphPrinter<adjacency_list<EL,VL,D,VP,EP,GP>,VP,EP>
write( adjacency_list<EL,VL,D,VP,EP,GP>& g )
{
return GraphPrinter<adjacency_list<EL,VL,D,VP,EP,GP>,VP,EP>(g);
}
// user methods
//=========================================================================
}// boost
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -1,83 +0,0 @@
// Copyright (c) Jeremy Siek 2001, Marc Wintermantel 2002
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_GRAPH_BANDWIDTH_HPP
#define BOOST_GRAPH_BANDWIDTH_HPP
#include <algorithm> // for std::min and std::max
#include <boost/config.hpp>
#include <boost/graph/graph_traits.hpp>
#include <boost/detail/numeric_traits.hpp>
namespace boost {
template <typename Graph, typename VertexIndexMap>
typename graph_traits<Graph>::vertices_size_type
ith_bandwidth(typename graph_traits<Graph>::vertex_descriptor i,
const Graph& g,
VertexIndexMap index)
{
BOOST_USING_STD_MAX();
typedef typename graph_traits<Graph>::vertices_size_type size_type;
size_type b = 0;
typename graph_traits<Graph>::out_edge_iterator e, end;
for (tie(e, end) = out_edges(i, g); e != end; ++e) {
int f_i = get(index, i);
int f_j = get(index, target(*e, g));
using namespace std; // to call abs() unqualified
if(f_i > f_j)
b = max BOOST_PREVENT_MACRO_SUBSTITUTION (b, size_type(f_i - f_j));
}
return b;
}
template <typename Graph>
typename graph_traits<Graph>::vertices_size_type
ith_bandwidth(typename graph_traits<Graph>::vertex_descriptor i,
const Graph& g)
{
return ith_bandwidth(i, g, get(vertex_index, g));
}
template <typename Graph, typename VertexIndexMap>
typename graph_traits<Graph>::vertices_size_type
bandwidth(const Graph& g, VertexIndexMap index)
{
BOOST_USING_STD_MAX();
typename graph_traits<Graph>::vertices_size_type b = 0;
typename graph_traits<Graph>::vertex_iterator i, end;
for (tie(i, end) = vertices(g); i != end; ++i)
b = max BOOST_PREVENT_MACRO_SUBSTITUTION (b, ith_bandwidth(*i, g, index));
return b;
}
template <typename Graph>
typename graph_traits<Graph>::vertices_size_type
bandwidth(const Graph& g)
{
return bandwidth(g, get(vertex_index, g));
}
template <typename Graph, typename VertexIndexMap>
typename graph_traits<Graph>::vertices_size_type
edgesum(const Graph& g, VertexIndexMap index_map)
{
typedef typename graph_traits<Graph>::vertices_size_type size_type;
typedef typename detail::numeric_traits<size_type>::difference_type diff_t;
size_type sum = 0;
typename graph_traits<Graph>::edge_iterator i, end;
for (tie(i, end) = edges(g); i != end; ++i) {
diff_t f_u = get(index_map, source(*i, g));
diff_t f_v = get(index_map, target(*i, g));
using namespace std; // to call abs() unqualified
sum += abs(f_u - f_v);
}
return sum;
}
} // namespace boost
#endif // BOOST_GRAPH_BANDWIDTH_HPP

View File

@@ -1,199 +0,0 @@
//
//=======================================================================
// Copyright 1997, 1998, 1999, 2000 University of Notre Dame.
// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek
//
// This file is part of the Boost Graph Library
//
// You should have received a copy of the License Agreement for the
// Boost Graph Library along with the software; see the file LICENSE.
// If not, contact Office of Research, University of Notre Dame, Notre
// Dame, IN 46556.
//
// Permission to modify the code and to distribute modified code is
// granted, provided the text of this NOTICE is retained, a notice that
// the code was modified is included with the above COPYRIGHT NOTICE and
// with the COPYRIGHT NOTICE in the LICENSE file, and that the LICENSE
// file is distributed with the modified code.
//
// LICENSOR MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED.
// By way of example, but not limitation, Licensor MAKES NO
// REPRESENTATIONS OR WARRANTIES OF MERCHANTABILITY OR FITNESS FOR ANY
// PARTICULAR PURPOSE OR THAT THE USE OF THE LICENSED SOFTWARE COMPONENTS
// OR DOCUMENTATION WILL NOT INFRINGE ANY PATENTS, COPYRIGHTS, TRADEMARKS
// OR OTHER RIGHTS.
//=======================================================================
//
/*
This file implements the function
template <class EdgeListGraph, class Size, class P, class T, class R>
bool bellman_ford_shortest_paths(EdgeListGraph& g, Size N,
const bgl_named_params<P, T, R>& params)
*/
#ifndef BOOST_GRAPH_BELLMAN_FORD_SHORTEST_PATHS_HPP
#define BOOST_GRAPH_BELLMAN_FORD_SHORTEST_PATHS_HPP
#include <boost/config.hpp>
#include <boost/graph/graph_traits.hpp>
#include <boost/graph/graph_concepts.hpp>
#include <boost/graph/properties.hpp>
#include <boost/graph/relax.hpp>
#include <boost/graph/visitors.hpp>
#include <boost/graph/named_function_params.hpp>
namespace boost {
template <class Visitor, class Graph>
struct BellmanFordVisitorConcept {
void constraints() {
function_requires< CopyConstructibleConcept<Visitor> >();
vis.examine_edge(e, g);
vis.edge_relaxed(e, g);
vis.edge_not_relaxed(e, g);
vis.edge_minimized(e, g);
vis.edge_not_minimized(e, g);
}
Visitor vis;
Graph g;
typename graph_traits<Graph>::edge_descriptor e;
};
template <class Visitors = null_visitor>
class bellman_visitor {
public:
bellman_visitor() { }
bellman_visitor(Visitors vis) : m_vis(vis) { }
template <class Edge, class Graph>
void examine_edge(Edge u, Graph& g) {
invoke_visitors(m_vis, u, g, on_examine_edge());
}
template <class Edge, class Graph>
void edge_relaxed(Edge u, Graph& g) {
invoke_visitors(m_vis, u, g, on_edge_relaxed());
}
template <class Edge, class Graph>
void edge_not_relaxed(Edge u, Graph& g) {
invoke_visitors(m_vis, u, g, on_edge_not_relaxed());
}
template <class Edge, class Graph>
void edge_minimized(Edge u, Graph& g) {
invoke_visitors(m_vis, u, g, on_edge_minimized());
}
template <class Edge, class Graph>
void edge_not_minimized(Edge u, Graph& g) {
invoke_visitors(m_vis, u, g, on_edge_not_minimized());
}
protected:
Visitors m_vis;
};
template <class Visitors>
bellman_visitor<Visitors>
make_bellman_visitor(Visitors vis) {
return bellman_visitor<Visitors>(vis);
}
typedef bellman_visitor<> default_bellman_visitor;
template <class EdgeListGraph, class Size, class WeightMap,
class PredecessorMap, class DistanceMap,
class BinaryFunction, class BinaryPredicate,
class BellmanFordVisitor>
bool bellman_ford_shortest_paths(EdgeListGraph& g, Size N,
WeightMap weight,
PredecessorMap pred,
DistanceMap distance,
BinaryFunction combine,
BinaryPredicate compare,
BellmanFordVisitor v)
{
function_requires<EdgeListGraphConcept<EdgeListGraph> >();
typedef graph_traits<EdgeListGraph> GTraits;
typedef typename GTraits::edge_descriptor Edge;
typedef typename GTraits::vertex_descriptor Vertex;
function_requires<ReadWritePropertyMapConcept<DistanceMap, Vertex> >();
function_requires<ReadablePropertyMapConcept<WeightMap, Edge> >();
typedef typename property_traits<DistanceMap>::value_type D_value;
typedef typename property_traits<WeightMap>::value_type W_value;
typename GTraits::edge_iterator i, end;
for (Size k = 0; k < N; ++k) {
bool at_least_one_edge_relaxed = false;
for (tie(i, end) = edges(g); i != end; ++i) {
v.examine_edge(*i, g);
if (relax(*i, g, weight, pred, distance, combine, compare)) {
at_least_one_edge_relaxed = true;
v.edge_relaxed(*i, g);
} else
v.edge_not_relaxed(*i, g);
}
if (!at_least_one_edge_relaxed)
break;
}
for (tie(i, end) = edges(g); i != end; ++i)
if (compare(combine(get(distance, source(*i, g)),
get(weight, *i)),
get(distance, target(*i,g))))
{
v.edge_not_minimized(*i, g);
return false;
} else
v.edge_minimized(*i, g);
return true;
}
namespace detail {
template <class EdgeListGraph, class Size, class WeightMap,
class DistanceMap, class P, class T, class R>
bool bellman_dispatch(EdgeListGraph& g, Size N,
WeightMap weight, DistanceMap distance,
const bgl_named_params<P, T, R>& params)
{
typedef typename property_traits<DistanceMap>::value_type D;
bellman_visitor<> null_vis;
dummy_property_map dummy_pred;
return bellman_ford_shortest_paths
(g, N, weight,
choose_param(get_param(params, vertex_predecessor), dummy_pred),
distance,
choose_param(get_param(params, distance_combine_t()),
closed_plus<D>()),
choose_param(get_param(params, distance_compare_t()),
std::less<D>()),
choose_param(get_param(params, graph_visitor),
null_vis)
);
}
} // namespace detail
template <class EdgeListGraph, class Size, class P, class T, class R>
bool bellman_ford_shortest_paths
(EdgeListGraph& g, Size N,
const bgl_named_params<P, T, R>& params)
{
return detail::bellman_dispatch
(g, N,
choose_const_pmap(get_param(params, edge_weight), g, edge_weight),
choose_pmap(get_param(params, vertex_distance), g, vertex_distance),
params);
}
template <class EdgeListGraph, class Size>
bool bellman_ford_shortest_paths(EdgeListGraph& g, Size N)
{
bgl_named_params<int,int> params(0);
return bellman_ford_shortest_paths(g, N, params);
}
} // namespace boost
#endif // BOOST_GRAPH_BELLMAN_FORD_SHORTEST_PATHS_HPP

View File

@@ -1,165 +0,0 @@
// Copyright 2004 The Trustees of Indiana University.
// Use, modification and distribution is subject to the Boost Software
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// Authors: Douglas Gregor
// Andrew Lumsdaine
#ifndef BOOST_GRAPH_BETWEENNESS_CENTRALITY_CLUSTERING_HPP
#define BOOST_GRAPH_BETWEENNESS_CENTRALITY_CLUSTERING_HPP
#include <boost/graph/brandes_betweenness_centrality.hpp>
#include <boost/graph/graph_traits.hpp>
#include <boost/pending/indirect_cmp.hpp>
#include <algorithm>
#include <vector>
#include <boost/property_map.hpp>
namespace boost {
/** Threshold termination function for the betweenness centrality
* clustering algorithm.
*/
template<typename T>
struct bc_clustering_threshold
{
typedef T centrality_type;
/// Terminate clustering when maximum absolute edge centrality is
/// below the given threshold.
explicit bc_clustering_threshold(T threshold)
: threshold(threshold), dividend(1.0) {}
/**
* Terminate clustering when the maximum edge centrality is below
* the given threshold.
*
* @param threshold the threshold value
*
* @param g the graph on which the threshold will be calculated
*
* @param normalize when true, the threshold is compared against the
* normalized edge centrality based on the input graph; otherwise,
* the threshold is compared against the absolute edge centrality.
*/
template<typename Graph>
bc_clustering_threshold(T threshold, const Graph& g, bool normalize = true)
: threshold(threshold), dividend(1.0)
{
if (normalize) {
typename graph_traits<Graph>::vertices_size_type n = num_vertices(g);
dividend = T((n - 1) * (n - 2)) / T(2);
}
}
/** Returns true when the given maximum edge centrality (potentially
* normalized) falls below the threshold.
*/
template<typename Graph, typename Edge>
bool operator()(T max_centrality, Edge, const Graph&)
{
return (max_centrality / dividend) < threshold;
}
protected:
T threshold;
T dividend;
};
/** Graph clustering based on edge betweenness centrality.
*
* This algorithm implements graph clustering based on edge
* betweenness centrality. It is an iterative algorithm, where in each
* step it compute the edge betweenness centrality (via @ref
* brandes_betweenness_centrality) and removes the edge with the
* maximum betweenness centrality. The @p done function object
* determines when the algorithm terminates (the edge found when the
* algorithm terminates will not be removed).
*
* @param g The graph on which clustering will be performed. The type
* of this parameter (@c MutableGraph) must be a model of the
* VertexListGraph, IncidenceGraph, EdgeListGraph, and Mutable Graph
* concepts.
*
* @param done The function object that indicates termination of the
* algorithm. It must be a ternary function object thats accepts the
* maximum centrality, the descriptor of the edge that will be
* removed, and the graph @p g.
*
* @param edge_centrality (UTIL/OUT) The property map that will store
* the betweenness centrality for each edge. When the algorithm
* terminates, it will contain the edge centralities for the
* graph. The type of this property map must model the
* ReadWritePropertyMap concept. Defaults to an @c
* iterator_property_map whose value type is
* @c Done::centrality_type and using @c get(edge_index, g) for the
* index map.
*
* @param vertex_index (IN) The property map that maps vertices to
* indices in the range @c [0, num_vertices(g)). This type of this
* property map must model the ReadablePropertyMap concept and its
* value type must be an integral type. Defaults to
* @c get(vertex_index, g).
*/
template<typename MutableGraph, typename Done, typename EdgeCentralityMap,
typename VertexIndexMap>
void
betweenness_centrality_clustering(MutableGraph& g, Done done,
EdgeCentralityMap edge_centrality,
VertexIndexMap vertex_index)
{
typedef typename property_traits<EdgeCentralityMap>::value_type
centrality_type;
typedef typename graph_traits<MutableGraph>::edge_iterator edge_iterator;
typedef typename graph_traits<MutableGraph>::edge_descriptor edge_descriptor;
typedef typename graph_traits<MutableGraph>::vertices_size_type
vertices_size_type;
if (edges(g).first == edges(g).second) return;
// Function object that compares the centrality of edges
indirect_cmp<EdgeCentralityMap, std::less<centrality_type> >
cmp(edge_centrality);
bool is_done;
do {
brandes_betweenness_centrality(g,
edge_centrality_map(edge_centrality)
.vertex_index_map(vertex_index));
edge_descriptor e = *max_element(edges(g).first, edges(g).second, cmp);
centrality_type max_centrality = get(edge_centrality, e);
is_done = done(get(edge_centrality, e), e, g);
if (!is_done) remove_edge(e, g);
} while (!is_done && edges(g).first != edges(g).second);
}
/**
* \overload
*/
template<typename MutableGraph, typename Done, typename EdgeCentralityMap>
void
betweenness_centrality_clustering(MutableGraph& g, Done done,
EdgeCentralityMap edge_centrality)
{
betweenness_centrality_clustering(g, done, edge_centrality,
get(vertex_index, g));
}
/**
* \overload
*/
template<typename MutableGraph, typename Done>
void
betweenness_centrality_clustering(MutableGraph& g, Done done)
{
typedef typename Done::centrality_type centrality_type;
std::vector<centrality_type> edge_centrality(num_edges(g));
betweenness_centrality_clustering(g, done,
make_iterator_property_map(edge_centrality.begin(), get(edge_index, g)),
get(vertex_index, g));
}
} // end namespace boost
#endif // BOOST_GRAPH_BETWEENNESS_CENTRALITY_CLUSTERING_HPP

View File

@@ -1,111 +0,0 @@
// Copyright (c) Jeremy Siek 2001
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// NOTE: this final is generated by libs/graph/doc/biconnected_components.w
#ifndef BOOST_GRAPH_BICONNECTED_COMPONENTS_HPP
#define BOOST_GRAPH_BICONNECTED_COMPONENTS_HPP
#include <stack>
#include <algorithm> // for std::min and std::max
#include <boost/config.hpp>
#include <boost/limits.hpp>
#include <boost/graph/graph_traits.hpp>
#include <boost/graph/graph_concepts.hpp>
#include <boost/property_map.hpp>
namespace boost
{
namespace detail
{
template < typename Graph, typename ComponentMap,
typename DiscoverTimeMap, typename LowPointMap, typename Stack >
void biconnect(typename graph_traits < Graph >::vertex_descriptor v,
typename graph_traits < Graph >::vertex_descriptor u,
bool at_top,
const Graph & g,
ComponentMap comp,
std::size_t & c,
DiscoverTimeMap d,
std::size_t & dfs_time, LowPointMap lowpt, Stack & S)
{
BOOST_USING_STD_MIN();
typedef typename graph_traits < Graph >::vertex_descriptor vertex_t;
typedef typename property_traits < DiscoverTimeMap >::value_type D;
D infinity = (std::numeric_limits < D >::max)();
put(d, v, ++dfs_time);
put(lowpt, v, get(d, v));
typename graph_traits < Graph >::out_edge_iterator ei, ei_end;
for (tie(ei, ei_end) = out_edges(v, g); ei != ei_end; ++ei)
{
vertex_t w = target(*ei, g);
if (get(d, w) == infinity)
{
S.push(*ei);
biconnect(w, v, false, g, comp, c, d, dfs_time, lowpt, S);
put(lowpt, v, min BOOST_PREVENT_MACRO_SUBSTITUTION(get(lowpt, v), get(lowpt, w)));
if (get(lowpt, w) >= get(d, v))
{
while (d[source(S.top(), g)] >= d[w]) {
put(comp, S.top(), c);
S.pop();
}
put(comp, S.top(), c);
S.pop();
++c;
}
} else if (get(d, w) < get(d, v) && (!at_top && w != u))
{
S.push(*ei);
put(lowpt, v, min BOOST_PREVENT_MACRO_SUBSTITUTION(get(lowpt, v), get(d, w)));
}
}
}
}
template < typename Graph, typename ComponentMap,
typename DiscoverTimeMap, typename LowPointMap >
void biconnected_components
(typename graph_traits < Graph >::vertex_descriptor v,
typename graph_traits < Graph >::vertex_descriptor u,
const Graph & g,
ComponentMap comp,
std::size_t & num_components,
DiscoverTimeMap discover_time, LowPointMap lowpt)
{
typedef typename graph_traits < Graph >::vertex_descriptor vertex_t;
typedef typename graph_traits < Graph >::edge_descriptor edge_t;
function_requires < VertexListGraphConcept < Graph > >();
function_requires < IncidenceGraphConcept < Graph > >();
function_requires < WritablePropertyMapConcept < ComponentMap,
edge_t > >();
function_requires < ReadWritePropertyMapConcept < DiscoverTimeMap,
vertex_t > >();
function_requires < ReadWritePropertyMapConcept < LowPointMap,
vertex_t > >();
typedef typename property_traits < DiscoverTimeMap >::value_type D;
num_components = 0;
std::size_t dfs_time = 0;
std::stack < edge_t > S;
typename graph_traits < Graph >::vertex_iterator wi, wi_end;
std::size_t infinity = (std::numeric_limits < std::size_t >::max)();
for (tie(wi, wi_end) = vertices(g); wi != wi_end; ++wi)
put(discover_time, *wi, infinity);
for (tie(wi, wi_end) = vertices(g); wi != wi_end; ++wi)
if (get(discover_time, *wi) == (std::numeric_limits < D >::max)())
detail::biconnect(*wi, *wi, true,
g, comp, num_components,
discover_time, dfs_time, lowpt, S);
}
} // namespace boost
#endif /* BOOST_GRAPH_BICONNECTED_COMPONENTS_HPP */

View File

@@ -1,599 +0,0 @@
// Copyright 2004 The Trustees of Indiana University.
// Use, modification and distribution is subject to the Boost Software
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// Authors: Douglas Gregor
// Andrew Lumsdaine
#ifndef BOOST_GRAPH_BRANDES_BETWEENNESS_CENTRALITY_HPP
#define BOOST_GRAPH_BRANDES_BETWEENNESS_CENTRALITY_HPP
#include <stack>
#include <vector>
#include <boost/graph/dijkstra_shortest_paths.hpp>
#include <boost/graph/breadth_first_search.hpp>
#include <boost/graph/relax.hpp>
#include <boost/graph/graph_traits.hpp>
#include <boost/tuple/tuple.hpp>
#include <boost/type_traits/is_convertible.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/mpl/if.hpp>
#include <boost/property_map.hpp>
#include <boost/graph/named_function_params.hpp>
#include <algorithm>
namespace boost {
namespace detail { namespace graph {
/**
* Customized visitor passed to Dijkstra's algorithm by Brandes'
* betweenness centrality algorithm. This visitor is responsible for
* keeping track of the order in which vertices are discovered, the
* predecessors on the shortest path(s) to a vertex, and the number
* of shortest paths.
*/
template<typename Graph, typename WeightMap, typename IncomingMap,
typename DistanceMap, typename PathCountMap>
struct brandes_dijkstra_visitor : public bfs_visitor<>
{
typedef typename graph_traits<Graph>::vertex_descriptor vertex_descriptor;
typedef typename graph_traits<Graph>::edge_descriptor edge_descriptor;
brandes_dijkstra_visitor(std::stack<vertex_descriptor>& ordered_vertices,
WeightMap weight,
IncomingMap incoming,
DistanceMap distance,
PathCountMap path_count)
: ordered_vertices(ordered_vertices), weight(weight),
incoming(incoming), distance(distance),
path_count(path_count)
{ }
/**
* Whenever an edge e = (v, w) is relaxed, the incoming edge list
* for w is set to {(v, w)} and the shortest path count of w is set to
* the number of paths that reach {v}.
*/
void edge_relaxed(edge_descriptor e, const Graph& g)
{
vertex_descriptor v = source(e, g), w = target(e, g);
incoming[w].clear();
incoming[w].push_back(e);
put(path_count, w, get(path_count, v));
}
/**
* If an edge e = (v, w) was not relaxed, it may still be the case
* that we've found more equally-short paths, so include {(v, w)} in the
* incoming edges of w and add all of the shortest paths to v to the
* shortest path count of w.
*/
void edge_not_relaxed(edge_descriptor e, const Graph& g)
{
typedef typename property_traits<WeightMap>::value_type weight_type;
typedef typename property_traits<DistanceMap>::value_type distance_type;
vertex_descriptor v = source(e, g), w = target(e, g);
distance_type d_v = get(distance, v), d_w = get(distance, w);
weight_type w_e = get(weight, e);
closed_plus<distance_type> combine;
if (d_w == combine(d_v, w_e)) {
put(path_count, w, get(path_count, w) + get(path_count, v));
incoming[w].push_back(e);
}
}
/// Keep track of vertices as they are reached
void examine_vertex(vertex_descriptor w, const Graph&)
{
ordered_vertices.push(w);
}
private:
std::stack<vertex_descriptor>& ordered_vertices;
WeightMap weight;
IncomingMap incoming;
DistanceMap distance;
PathCountMap path_count;
};
/**
* Function object that calls Dijkstra's shortest paths algorithm
* using the Dijkstra visitor for the Brandes betweenness centrality
* algorithm.
*/
template<typename WeightMap>
struct brandes_dijkstra_shortest_paths
{
brandes_dijkstra_shortest_paths(WeightMap weight_map)
: weight_map(weight_map) { }
template<typename Graph, typename IncomingMap, typename DistanceMap,
typename PathCountMap, typename VertexIndexMap>
void
operator()(Graph& g,
typename graph_traits<Graph>::vertex_descriptor s,
std::stack<typename graph_traits<Graph>::vertex_descriptor>& ov,
IncomingMap incoming,
DistanceMap distance,
PathCountMap path_count,
VertexIndexMap vertex_index)
{
typedef brandes_dijkstra_visitor<Graph, WeightMap, IncomingMap,
DistanceMap, PathCountMap> visitor_type;
visitor_type visitor(ov, weight_map, incoming, distance, path_count);
dijkstra_shortest_paths(g, s,
boost::weight_map(weight_map)
.vertex_index_map(vertex_index)
.distance_map(distance)
.visitor(visitor));
}
private:
WeightMap weight_map;
};
/**
* Function object that invokes breadth-first search for the
* unweighted form of the Brandes betweenness centrality algorithm.
*/
struct brandes_unweighted_shortest_paths
{
/**
* Customized visitor passed to breadth-first search, which
* records predecessor and the number of shortest paths to each
* vertex.
*/
template<typename Graph, typename IncomingMap, typename DistanceMap,
typename PathCountMap>
struct visitor_type : public bfs_visitor<>
{
typedef typename graph_traits<Graph>::edge_descriptor edge_descriptor;
typedef typename graph_traits<Graph>::vertex_descriptor
vertex_descriptor;
visitor_type(IncomingMap incoming, DistanceMap distance,
PathCountMap path_count,
std::stack<vertex_descriptor>& ordered_vertices)
: incoming(incoming), distance(distance),
path_count(path_count), ordered_vertices(ordered_vertices) { }
/// Keep track of vertices as they are reached
void examine_vertex(vertex_descriptor v, Graph&)
{
ordered_vertices.push(v);
}
/**
* Whenever an edge e = (v, w) is labelled a tree edge, the
* incoming edge list for w is set to {(v, w)} and the shortest
* path count of w is set to the number of paths that reach {v}.
*/
void tree_edge(edge_descriptor e, Graph& g)
{
vertex_descriptor v = source(e, g);
vertex_descriptor w = target(e, g);
put(distance, w, get(distance, v) + 1);
put(path_count, w, get(path_count, v));
incoming[w].push_back(e);
}
/**
* If an edge e = (v, w) is not a tree edge, it may still be the
* case that we've found more equally-short paths, so include (v, w)
* in the incoming edge list of w and add all of the shortest
* paths to v to the shortest path count of w.
*/
void non_tree_edge(edge_descriptor e, Graph& g)
{
vertex_descriptor v = source(e, g);
vertex_descriptor w = target(e, g);
if (get(distance, w) == get(distance, v) + 1) {
put(path_count, w, get(path_count, w) + get(path_count, v));
incoming[w].push_back(e);
}
}
private:
IncomingMap incoming;
DistanceMap distance;
PathCountMap path_count;
std::stack<vertex_descriptor>& ordered_vertices;
};
template<typename Graph, typename IncomingMap, typename DistanceMap,
typename PathCountMap, typename VertexIndexMap>
void
operator()(Graph& g,
typename graph_traits<Graph>::vertex_descriptor s,
std::stack<typename graph_traits<Graph>::vertex_descriptor>& ov,
IncomingMap incoming,
DistanceMap distance,
PathCountMap path_count,
VertexIndexMap vertex_index)
{
typedef typename graph_traits<Graph>::vertex_descriptor
vertex_descriptor;
visitor_type<Graph, IncomingMap, DistanceMap, PathCountMap>
visitor(incoming, distance, path_count, ov);
std::vector<default_color_type>
colors(num_vertices(g), color_traits<default_color_type>::white());
boost::queue<vertex_descriptor> Q;
breadth_first_visit(g, s, Q, visitor,
make_iterator_property_map(colors.begin(),
vertex_index));
}
};
// When the edge centrality map is a dummy property map, no
// initialization is needed.
template<typename Iter>
inline void
init_centrality_map(std::pair<Iter, Iter>, dummy_property_map) { }
// When we have a real edge centrality map, initialize all of the
// centralities to zero.
template<typename Iter, typename Centrality>
void
init_centrality_map(std::pair<Iter, Iter> keys, Centrality centrality_map)
{
typedef typename property_traits<Centrality>::value_type
centrality_type;
while (keys.first != keys.second) {
put(centrality_map, *keys.first, centrality_type(0));
++keys.first;
}
}
// When the edge centrality map is a dummy property map, no update
// is performed.
template<typename Key, typename T>
inline void
update_centrality(dummy_property_map, const Key&, const T&) { }
// When we have a real edge centrality map, add the value to the map
template<typename CentralityMap, typename Key, typename T>
inline void
update_centrality(CentralityMap centrality_map, Key k, const T& x)
{ put(centrality_map, k, get(centrality_map, k) + x); }
template<typename Iter>
inline void
divide_centrality_by_two(std::pair<Iter, Iter>, dummy_property_map) {}
template<typename Iter, typename CentralityMap>
inline void
divide_centrality_by_two(std::pair<Iter, Iter> keys,
CentralityMap centrality_map)
{
typename property_traits<CentralityMap>::value_type two(2);
while (keys.first != keys.second) {
put(centrality_map, *keys.first, get(centrality_map, *keys.first) / two);
++keys.first;
}
}
template<typename Graph, typename CentralityMap, typename EdgeCentralityMap,
typename IncomingMap, typename DistanceMap,
typename DependencyMap, typename PathCountMap,
typename VertexIndexMap, typename ShortestPaths>
void
brandes_betweenness_centrality_impl(const Graph& g,
CentralityMap centrality, // C_B
EdgeCentralityMap edge_centrality_map,
IncomingMap incoming, // P
DistanceMap distance, // d
DependencyMap dependency, // delta
PathCountMap path_count, // sigma
VertexIndexMap vertex_index,
ShortestPaths shortest_paths)
{
typedef typename graph_traits<Graph>::vertex_iterator vertex_iterator;
typedef typename graph_traits<Graph>::edge_iterator edge_iterator;
typedef typename graph_traits<Graph>::vertex_descriptor vertex_descriptor;
// Initialize centrality
init_centrality_map(vertices(g), centrality);
init_centrality_map(edges(g), edge_centrality_map);
std::stack<vertex_descriptor> ordered_vertices;
vertex_iterator s, s_end;
for (tie(s, s_end) = vertices(g); s != s_end; ++s) {
// Initialize for this iteration
vertex_iterator w, w_end;
for (tie(w, w_end) = vertices(g); w != w_end; ++w) {
incoming[*w].clear();
put(path_count, *w, 0);
put(dependency, *w, 0);
}
put(path_count, *s, 1);
// Execute the shortest paths algorithm. This will be either
// Dijkstra's algorithm or a customized breadth-first search,
// depending on whether the graph is weighted or unweighted.
shortest_paths(g, *s, ordered_vertices, incoming, distance,
path_count, vertex_index);
while (!ordered_vertices.empty()) {
vertex_descriptor w = ordered_vertices.top();
ordered_vertices.pop();
typedef typename property_traits<IncomingMap>::value_type
incoming_type;
typedef typename incoming_type::iterator incoming_iterator;
typedef typename property_traits<DependencyMap>::value_type
dependency_type;
for (incoming_iterator vw = incoming[w].begin();
vw != incoming[w].end(); ++vw) {
vertex_descriptor v = source(*vw, g);
dependency_type factor = dependency_type(get(path_count, v))
/ dependency_type(get(path_count, w));
factor *= (dependency_type(1) + get(dependency, w));
put(dependency, v, get(dependency, v) + factor);
update_centrality(edge_centrality_map, *vw, factor);
}
if (w != *s) {
update_centrality(centrality, w, get(dependency, w));
}
}
}
typedef typename graph_traits<Graph>::directed_category directed_category;
const bool is_undirected =
is_convertible<directed_category*, undirected_tag*>::value;
if (is_undirected) {
divide_centrality_by_two(vertices(g), centrality);
divide_centrality_by_two(edges(g), edge_centrality_map);
}
}
} } // end namespace detail::graph
template<typename Graph, typename CentralityMap, typename EdgeCentralityMap,
typename IncomingMap, typename DistanceMap,
typename DependencyMap, typename PathCountMap,
typename VertexIndexMap>
void
brandes_betweenness_centrality(const Graph& g,
CentralityMap centrality, // C_B
EdgeCentralityMap edge_centrality_map,
IncomingMap incoming, // P
DistanceMap distance, // d
DependencyMap dependency, // delta
PathCountMap path_count, // sigma
VertexIndexMap vertex_index)
{
detail::graph::brandes_unweighted_shortest_paths shortest_paths;
detail::graph::brandes_betweenness_centrality_impl(g, centrality,
edge_centrality_map,
incoming, distance,
dependency, path_count,
vertex_index,
shortest_paths);
}
template<typename Graph, typename CentralityMap, typename EdgeCentralityMap,
typename IncomingMap, typename DistanceMap,
typename DependencyMap, typename PathCountMap,
typename VertexIndexMap, typename WeightMap>
void
brandes_betweenness_centrality(const Graph& g,
CentralityMap centrality, // C_B
EdgeCentralityMap edge_centrality_map,
IncomingMap incoming, // P
DistanceMap distance, // d
DependencyMap dependency, // delta
PathCountMap path_count, // sigma
VertexIndexMap vertex_index,
WeightMap weight_map)
{
detail::graph::brandes_dijkstra_shortest_paths<WeightMap>
shortest_paths(weight_map);
detail::graph::brandes_betweenness_centrality_impl(g, centrality,
edge_centrality_map,
incoming, distance,
dependency, path_count,
vertex_index,
shortest_paths);
}
namespace detail { namespace graph {
template<typename Graph, typename CentralityMap, typename EdgeCentralityMap,
typename WeightMap, typename VertexIndexMap>
void
brandes_betweenness_centrality_dispatch2(const Graph& g,
CentralityMap centrality,
EdgeCentralityMap edge_centrality_map,
WeightMap weight_map,
VertexIndexMap vertex_index)
{
typedef typename graph_traits<Graph>::degree_size_type degree_size_type;
typedef typename graph_traits<Graph>::vertex_descriptor vertex_descriptor;
typedef typename graph_traits<Graph>::edge_descriptor edge_descriptor;
typedef typename mpl::if_c<(is_same<CentralityMap,
dummy_property_map>::value),
EdgeCentralityMap,
CentralityMap>::type a_centrality_map;
typedef typename property_traits<a_centrality_map>::value_type
centrality_type;
typename graph_traits<Graph>::vertices_size_type V = num_vertices(g);
std::vector<std::vector<edge_descriptor> > incoming(V);
std::vector<centrality_type> distance(V);
std::vector<centrality_type> dependency(V);
std::vector<degree_size_type> path_count(V);
brandes_betweenness_centrality(
g, centrality, edge_centrality_map,
make_iterator_property_map(incoming.begin(), vertex_index),
make_iterator_property_map(distance.begin(), vertex_index),
make_iterator_property_map(dependency.begin(), vertex_index),
make_iterator_property_map(path_count.begin(), vertex_index),
vertex_index,
weight_map);
}
template<typename Graph, typename CentralityMap, typename EdgeCentralityMap,
typename VertexIndexMap>
void
brandes_betweenness_centrality_dispatch2(const Graph& g,
CentralityMap centrality,
EdgeCentralityMap edge_centrality_map,
VertexIndexMap vertex_index)
{
typedef typename graph_traits<Graph>::degree_size_type degree_size_type;
typedef typename graph_traits<Graph>::vertex_descriptor vertex_descriptor;
typedef typename graph_traits<Graph>::edge_descriptor edge_descriptor;
typedef typename mpl::if_c<(is_same<CentralityMap,
dummy_property_map>::value),
EdgeCentralityMap,
CentralityMap>::type a_centrality_map;
typedef typename property_traits<a_centrality_map>::value_type
centrality_type;
typename graph_traits<Graph>::vertices_size_type V = num_vertices(g);
std::vector<std::vector<edge_descriptor> > incoming(V);
std::vector<centrality_type> distance(V);
std::vector<centrality_type> dependency(V);
std::vector<degree_size_type> path_count(V);
brandes_betweenness_centrality(
g, centrality, edge_centrality_map,
make_iterator_property_map(incoming.begin(), vertex_index),
make_iterator_property_map(distance.begin(), vertex_index),
make_iterator_property_map(dependency.begin(), vertex_index),
make_iterator_property_map(path_count.begin(), vertex_index),
vertex_index);
}
template<typename WeightMap>
struct brandes_betweenness_centrality_dispatch1
{
template<typename Graph, typename CentralityMap,
typename EdgeCentralityMap, typename VertexIndexMap>
static void
run(const Graph& g, CentralityMap centrality,
EdgeCentralityMap edge_centrality_map, VertexIndexMap vertex_index,
WeightMap weight_map)
{
brandes_betweenness_centrality_dispatch2(g, centrality, edge_centrality_map,
weight_map, vertex_index);
}
};
template<>
struct brandes_betweenness_centrality_dispatch1<error_property_not_found>
{
template<typename Graph, typename CentralityMap,
typename EdgeCentralityMap, typename VertexIndexMap>
static void
run(const Graph& g, CentralityMap centrality,
EdgeCentralityMap edge_centrality_map, VertexIndexMap vertex_index,
error_property_not_found)
{
brandes_betweenness_centrality_dispatch2(g, centrality, edge_centrality_map,
vertex_index);
}
};
} } // end namespace detail::graph
template<typename Graph, typename Param, typename Tag, typename Rest>
void
brandes_betweenness_centrality(const Graph& g,
const bgl_named_params<Param,Tag,Rest>& params)
{
typedef bgl_named_params<Param,Tag,Rest> named_params;
typedef typename property_value<named_params, edge_weight_t>::type ew;
detail::graph::brandes_betweenness_centrality_dispatch1<ew>::run(
g,
choose_param(get_param(params, vertex_centrality),
dummy_property_map()),
choose_param(get_param(params, edge_centrality),
dummy_property_map()),
choose_const_pmap(get_param(params, vertex_index), g, vertex_index),
get_param(params, edge_weight));
}
template<typename Graph, typename CentralityMap>
void
brandes_betweenness_centrality(const Graph& g, CentralityMap centrality)
{
detail::graph::brandes_betweenness_centrality_dispatch2(
g, centrality, dummy_property_map(), get(vertex_index, g));
}
template<typename Graph, typename CentralityMap, typename EdgeCentralityMap>
void
brandes_betweenness_centrality(const Graph& g, CentralityMap centrality,
EdgeCentralityMap edge_centrality_map)
{
detail::graph::brandes_betweenness_centrality_dispatch2(
g, centrality, edge_centrality_map, get(vertex_index, g));
}
/**
* Converts "absolute" betweenness centrality (as computed by the
* brandes_betweenness_centrality algorithm) in the centrality map
* into "relative" centrality. The result is placed back into the
* given centrality map.
*/
template<typename Graph, typename CentralityMap>
void
relative_betweenness_centrality(const Graph& g, CentralityMap centrality)
{
typedef typename graph_traits<Graph>::vertex_iterator vertex_iterator;
typedef typename property_traits<CentralityMap>::value_type centrality_type;
typename graph_traits<Graph>::vertices_size_type n = num_vertices(g);
centrality_type factor = centrality_type(2)/centrality_type(n*n - 3*n + 2);
vertex_iterator v, v_end;
for (tie(v, v_end) = vertices(g); v != v_end; ++v) {
put(centrality, *v, factor * get(centrality, *v));
}
}
// Compute the central point dominance of a graph.
template<typename Graph, typename CentralityMap>
typename property_traits<CentralityMap>::value_type
central_point_dominance(const Graph& g, CentralityMap centrality)
{
using std::max;
typedef typename graph_traits<Graph>::vertex_iterator vertex_iterator;
typedef typename property_traits<CentralityMap>::value_type centrality_type;
typename graph_traits<Graph>::vertices_size_type n = num_vertices(g);
// Find max centrality
centrality_type max_centrality(0);
vertex_iterator v, v_end;
for (tie(v, v_end) = vertices(g); v != v_end; ++v) {
max_centrality = max(max_centrality, get(centrality, *v));
}
// Compute central point dominance
centrality_type sum(0);
for (tie(v, v_end) = vertices(g); v != v_end; ++v) {
sum += (max_centrality - get(centrality, *v));
}
return sum/(n-1);
}
} // end namespace boost
#endif // BOOST_GRAPH_BRANDES_BETWEENNESS_CENTRALITY_HPP

View File

@@ -1,309 +0,0 @@
//
//=======================================================================
// Copyright 1997, 1998, 1999, 2000 University of Notre Dame.
// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek
//
// This file is part of the Boost Graph Library
//
// You should have received a copy of the License Agreement for the
// Boost Graph Library along with the software; see the file LICENSE.
// If not, contact Office of Research, University of Notre Dame, Notre
// Dame, IN 46556.
//
// Permission to modify the code and to distribute modified code is
// granted, provided the text of this NOTICE is retained, a notice that
// the code was modified is included with the above COPYRIGHT NOTICE and
// with the COPYRIGHT NOTICE in the LICENSE file, and that the LICENSE
// file is distributed with the modified code.
//
// LICENSOR MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED.
// By way of example, but not limitation, Licensor MAKES NO
// REPRESENTATIONS OR WARRANTIES OF MERCHANTABILITY OR FITNESS FOR ANY
// PARTICULAR PURPOSE OR THAT THE USE OF THE LICENSED SOFTWARE COMPONENTS
// OR DOCUMENTATION WILL NOT INFRINGE ANY PATENTS, COPYRIGHTS, TRADEMARKS
// OR OTHER RIGHTS.
//=======================================================================
//
#ifndef BOOST_GRAPH_BREADTH_FIRST_SEARCH_HPP
#define BOOST_GRAPH_BREADTH_FIRST_SEARCH_HPP
/*
Breadth First Search Algorithm (Cormen, Leiserson, and Rivest p. 470)
*/
#include <boost/config.hpp>
#include <vector>
#include <boost/pending/queue.hpp>
#include <boost/graph/graph_traits.hpp>
#include <boost/graph/graph_concepts.hpp>
#include <boost/graph/visitors.hpp>
#include <boost/graph/named_function_params.hpp>
namespace boost {
template <class Visitor, class Graph>
struct BFSVisitorConcept {
void constraints() {
function_requires< CopyConstructibleConcept<Visitor> >();
vis.initialize_vertex(u, g);
vis.discover_vertex(u, g);
vis.examine_vertex(u, g);
vis.examine_edge(e, g);
vis.tree_edge(e, g);
vis.non_tree_edge(e, g);
vis.gray_target(e, g);
vis.black_target(e, g);
vis.finish_vertex(u, g);
}
Visitor vis;
Graph g;
typename graph_traits<Graph>::vertex_descriptor u;
typename graph_traits<Graph>::edge_descriptor e;
};
template <class IncidenceGraph, class Buffer, class BFSVisitor,
class ColorMap>
void breadth_first_visit
(const IncidenceGraph& g,
typename graph_traits<IncidenceGraph>::vertex_descriptor s,
Buffer& Q, BFSVisitor vis, ColorMap color)
{
function_requires< IncidenceGraphConcept<IncidenceGraph> >();
typedef graph_traits<IncidenceGraph> GTraits;
typedef typename GTraits::vertex_descriptor Vertex;
typedef typename GTraits::edge_descriptor Edge;
function_requires< BFSVisitorConcept<BFSVisitor, IncidenceGraph> >();
function_requires< ReadWritePropertyMapConcept<ColorMap, Vertex> >();
typedef typename property_traits<ColorMap>::value_type ColorValue;
typedef color_traits<ColorValue> Color;
typename GTraits::out_edge_iterator ei, ei_end;
put(color, s, Color::gray()); vis.discover_vertex(s, g);
Q.push(s);
while (! Q.empty()) {
Vertex u = Q.top(); Q.pop(); vis.examine_vertex(u, g);
for (tie(ei, ei_end) = out_edges(u, g); ei != ei_end; ++ei) {
Vertex v = target(*ei, g); vis.examine_edge(*ei, g);
ColorValue v_color = get(color, v);
if (v_color == Color::white()) { vis.tree_edge(*ei, g);
put(color, v, Color::gray()); vis.discover_vertex(v, g);
Q.push(v);
} else { vis.non_tree_edge(*ei, g);
if (v_color == Color::gray()) vis.gray_target(*ei, g);
else vis.black_target(*ei, g);
}
} // end for
put(color, u, Color::black()); vis.finish_vertex(u, g);
} // end while
} // breadth_first_visit
template <class VertexListGraph, class Buffer, class BFSVisitor,
class ColorMap>
void breadth_first_search
(const VertexListGraph& g,
typename graph_traits<VertexListGraph>::vertex_descriptor s,
Buffer& Q, BFSVisitor vis, ColorMap color)
{
// Initialization
typedef typename property_traits<ColorMap>::value_type ColorValue;
typedef color_traits<ColorValue> Color;
typename boost::graph_traits<VertexListGraph>::vertex_iterator i, i_end;
for (tie(i, i_end) = vertices(g); i != i_end; ++i) {
put(color, *i, Color::white());
vis.initialize_vertex(*i, g);
}
breadth_first_visit(g, s, Q, vis, color);
}
template <class Visitors = null_visitor>
class bfs_visitor {
public:
bfs_visitor() { }
bfs_visitor(Visitors vis) : m_vis(vis) { }
template <class Vertex, class Graph>
void initialize_vertex(Vertex u, Graph& g) {
invoke_visitors(m_vis, u, g, ::boost::on_initialize_vertex());
}
template <class Vertex, class Graph>
void discover_vertex(Vertex u, Graph& g) {
invoke_visitors(m_vis, u, g, ::boost::on_discover_vertex());
}
template <class Vertex, class Graph>
void examine_vertex(Vertex u, Graph& g) {
invoke_visitors(m_vis, u, g, ::boost::on_examine_vertex());
}
template <class Edge, class Graph>
void examine_edge(Edge e, Graph& g) {
invoke_visitors(m_vis, e, g, ::boost::on_examine_edge());
}
template <class Edge, class Graph>
void tree_edge(Edge e, Graph& g) {
invoke_visitors(m_vis, e, g, ::boost::on_tree_edge());
}
template <class Edge, class Graph>
void non_tree_edge(Edge e, Graph& g) {
invoke_visitors(m_vis, e, g, ::boost::on_non_tree_edge());
}
template <class Edge, class Graph>
void gray_target(Edge e, Graph& g) {
invoke_visitors(m_vis, e, g, ::boost::on_gray_target());
}
template <class Edge, class Graph>
void black_target(Edge e, Graph& g) {
invoke_visitors(m_vis, e, g, ::boost::on_black_target());
}
template <class Vertex, class Graph>
void finish_vertex(Vertex u, Graph& g) {
invoke_visitors(m_vis, u, g, ::boost::on_finish_vertex());
}
BOOST_GRAPH_EVENT_STUB(on_initialize_vertex,bfs)
BOOST_GRAPH_EVENT_STUB(on_discover_vertex,bfs)
BOOST_GRAPH_EVENT_STUB(on_examine_vertex,bfs)
BOOST_GRAPH_EVENT_STUB(on_examine_edge,bfs)
BOOST_GRAPH_EVENT_STUB(on_tree_edge,bfs)
BOOST_GRAPH_EVENT_STUB(on_non_tree_edge,bfs)
BOOST_GRAPH_EVENT_STUB(on_gray_target,bfs)
BOOST_GRAPH_EVENT_STUB(on_black_target,bfs)
BOOST_GRAPH_EVENT_STUB(on_finish_vertex,bfs)
protected:
Visitors m_vis;
};
template <class Visitors>
bfs_visitor<Visitors>
make_bfs_visitor(Visitors vis) {
return bfs_visitor<Visitors>(vis);
}
typedef bfs_visitor<> default_bfs_visitor;
namespace detail {
template <class VertexListGraph, class ColorMap, class BFSVisitor,
class P, class T, class R>
void bfs_helper
(VertexListGraph& g,
typename graph_traits<VertexListGraph>::vertex_descriptor s,
ColorMap color,
BFSVisitor vis,
const bgl_named_params<P, T, R>& params)
{
typedef graph_traits<VertexListGraph> Traits;
// Buffer default
typedef typename Traits::vertex_descriptor Vertex;
typedef boost::queue<Vertex> queue_t;
queue_t Q;
detail::wrap_ref<queue_t> Qref(Q);
breadth_first_search
(g, s,
choose_param(get_param(params, buffer_param_t()), Qref).ref,
vis, color);
}
//-------------------------------------------------------------------------
// Choose between default color and color parameters. Using
// function dispatching so that we don't require vertex index if
// the color default is not being used.
template <class ColorMap>
struct bfs_dispatch {
template <class VertexListGraph, class P, class T, class R>
static void apply
(VertexListGraph& g,
typename graph_traits<VertexListGraph>::vertex_descriptor s,
const bgl_named_params<P, T, R>& params,
ColorMap color)
{
bfs_helper
(g, s, color,
choose_param(get_param(params, graph_visitor),
make_bfs_visitor(null_visitor())),
params);
}
};
template <>
struct bfs_dispatch<detail::error_property_not_found> {
template <class VertexListGraph, class P, class T, class R>
static void apply
(VertexListGraph& g,
typename graph_traits<VertexListGraph>::vertex_descriptor s,
const bgl_named_params<P, T, R>& params,
detail::error_property_not_found)
{
std::vector<default_color_type> color_vec(num_vertices(g));
default_color_type c = white_color;
null_visitor null_vis;
bfs_helper
(g, s,
make_iterator_property_map
(color_vec.begin(),
choose_const_pmap(get_param(params, vertex_index),
g, vertex_index), c),
choose_param(get_param(params, graph_visitor),
make_bfs_visitor(null_vis)),
params);
}
};
} // namespace detail
// Named Parameter Variant
template <class VertexListGraph, class P, class T, class R>
void breadth_first_search
(const VertexListGraph& g,
typename graph_traits<VertexListGraph>::vertex_descriptor s,
const bgl_named_params<P, T, R>& params)
{
// The graph is passed by *const* reference so that graph adaptors
// (temporaries) can be passed into this function. However, the
// graph is not really const since we may write to property maps
// of the graph.
VertexListGraph& ng = const_cast<VertexListGraph&>(g);
typedef typename property_value< bgl_named_params<P,T,R>,
vertex_color_t>::type C;
detail::bfs_dispatch<C>::apply(ng, s, params,
get_param(params, vertex_color));
}
// This version does not initialize colors, user has to.
template <class IncidenceGraph, class P, class T, class R>
void breadth_first_visit
(const IncidenceGraph& g,
typename graph_traits<IncidenceGraph>::vertex_descriptor s,
const bgl_named_params<P, T, R>& params)
{
// The graph is passed by *const* reference so that graph adaptors
// (temporaries) can be passed into this function. However, the
// graph is not really const since we may write to property maps
// of the graph.
IncidenceGraph& ng = const_cast<IncidenceGraph&>(g);
typedef graph_traits<IncidenceGraph> Traits;
// Buffer default
typedef typename Traits::vertex_descriptor vertex_descriptor;
typedef boost::queue<vertex_descriptor> queue_t;
queue_t Q;
detail::wrap_ref<queue_t> Qref(Q);
breadth_first_visit
(ng, s,
choose_param(get_param(params, buffer_param_t()), Qref).ref,
choose_param(get_param(params, graph_visitor),
make_bfs_visitor(null_visitor())),
choose_pmap(get_param(params, vertex_color), ng, vertex_color)
);
}
} // namespace boost
#endif // BOOST_GRAPH_BREADTH_FIRST_SEARCH_HPP

View File

@@ -1,53 +0,0 @@
// Copyright 2004 The Trustees of Indiana University.
// Use, modification and distribution is subject to the Boost Software
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// Authors: Douglas Gregor
// Andrew Lumsdaine
#ifndef BOOST_GRAPH_CIRCLE_LAYOUT_HPP
#define BOOST_GRAPH_CIRCLE_LAYOUT_HPP
#include <cmath>
#include <utility>
#include <boost/graph/graph_traits.hpp>
namespace boost {
/**
* \brief Layout the graph with the vertices at the points of a regular
* n-polygon.
*
* The distance from the center of the polygon to each point is
* determined by the @p radius parameter. The @p position parameter
* must be an Lvalue Property Map whose value type is a class type
* containing @c x and @c y members that will be set to the @c x and
* @c y coordinates.
*/
template<typename VertexListGraph, typename PositionMap, typename Radius>
void
circle_graph_layout(const VertexListGraph& g, PositionMap position,
Radius radius)
{
const double pi = 3.14159;
using std::sin;
using std::cos;
typedef typename graph_traits<VertexListGraph>::vertices_size_type
vertices_size_type;
vertices_size_type n = num_vertices(g);
typedef typename graph_traits<VertexListGraph>::vertex_iterator
vertex_iterator;
vertices_size_type i = 0;
for(std::pair<vertex_iterator, vertex_iterator> v = vertices(g);
v.first != v.second; ++v.first, ++i) {
position[*v.first].x = radius * cos(i * 2 * pi / n);
position[*v.first].y = radius * sin(i * 2 * pi / n);
}
}
} // end namespace boost
#endif // BOOST_GRAPH_CIRCLE_LAYOUT_HPP

View File

@@ -1,113 +0,0 @@
//
//=======================================================================
// Copyright 1997-2001 University of Notre Dame.
// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek
//
// This file is part of the Boost Graph Library
//
// You should have received a copy of the License Agreement for the
// Boost Graph Library along with the software; see the file LICENSE.
// If not, contact Office of Research, University of Notre Dame, Notre
// Dame, IN 46556.
//
// Permission to modify the code and to distribute modified code is
// granted, provided the text of this NOTICE is retained, a notice that
// the code was modified is included with the above COPYRIGHT NOTICE and
// with the COPYRIGHT NOTICE in the LICENSE file, and that the LICENSE
// file is distributed with the modified code.
//
// LICENSOR MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED.
// By way of example, but not limitation, Licensor MAKES NO
// REPRESENTATIONS OR WARRANTIES OF MERCHANTABILITY OR FITNESS FOR ANY
// PARTICULAR PURPOSE OR THAT THE USE OF THE LICENSED SOFTWARE COMPONENTS
// OR DOCUMENTATION WILL NOT INFRINGE ANY PATENTS, COPYRIGHTS, TRADEMARKS
// OR OTHER RIGHTS.
//=======================================================================
//
#ifndef BOOST_GRAPH_CONNECTED_COMPONENTS_HPP
#define BOOST_GRAPH_CONNECTED_COMPONENTS_HPP
#include <boost/config.hpp>
#include <boost/graph/depth_first_search.hpp>
#include <boost/graph/properties.hpp>
#include <boost/graph/graph_concepts.hpp>
#include <boost/static_assert.hpp>
namespace boost {
namespace detail {
// This visitor is used both in the connected_components algorithm
// and in the kosaraju strong components algorithm during the
// second DFS traversal.
template <class ComponentsMap>
class components_recorder : public dfs_visitor<>
{
typedef typename property_traits<ComponentsMap>::value_type comp_type;
public:
components_recorder(ComponentsMap c,
comp_type& c_count)
: m_component(c), m_count(c_count) {}
template <class Vertex, class Graph>
void start_vertex(Vertex, Graph&) {
if (m_count == (std::numeric_limits<comp_type>::max)())
m_count = 0; // start counting components at zero
else
++m_count;
}
template <class Vertex, class Graph>
void discover_vertex(Vertex u, Graph&) {
put(m_component, u, m_count);
}
protected:
ComponentsMap m_component;
comp_type& m_count;
};
} // namespace detail
// This function computes the connected components of an undirected
// graph using a single application of depth first search.
template <class Graph, class ComponentMap, class P, class T, class R>
inline typename property_traits<ComponentMap>::value_type
connected_components(const Graph& g, ComponentMap c,
const bgl_named_params<P, T, R>& params)
{
typedef typename graph_traits<Graph>::vertex_descriptor Vertex;
function_requires< WritablePropertyMapConcept<ComponentMap, Vertex> >();
typedef typename boost::graph_traits<Graph>::directed_category directed;
BOOST_STATIC_ASSERT((boost::is_same<directed, undirected_tag>::value));
typedef typename property_traits<ComponentMap>::value_type comp_type;
// c_count initialized to "nil" (with nil represented by max())
comp_type c_count((std::numeric_limits<comp_type>::max)());
detail::components_recorder<ComponentMap> vis(c, c_count);
depth_first_search(g, params.visitor(vis));
return c_count + 1;
}
template <class Graph, class ComponentMap>
inline typename property_traits<ComponentMap>::value_type
connected_components(const Graph& g, ComponentMap c)
{
typedef typename graph_traits<Graph>::vertex_descriptor Vertex;
function_requires< WritablePropertyMapConcept<ComponentMap, Vertex> >();
typedef typename boost::graph_traits<Graph>::directed_category directed;
BOOST_STATIC_ASSERT((boost::is_same<directed, undirected_tag>::value));
typedef typename property_traits<ComponentMap>::value_type comp_type;
// c_count initialized to "nil" (with nil represented by max())
comp_type c_count((std::numeric_limits<comp_type>::max)());
detail::components_recorder<ComponentMap> vis(c, c_count);
depth_first_search(g, visitor(vis));
return c_count + 1;
}
} // namespace boost
#endif // BOOST_GRAPH_CONNECTED_COMPONENTS_HPP

View File

@@ -1,466 +0,0 @@
//
//=======================================================================
// Copyright 1997-2001 University of Notre Dame.
// Authors: Jeremy G. Siek, Lie-Quan Lee, Andrew Lumsdaine
//
// This file is part of the Boost Graph Library
//
// You should have received a copy of the License Agreement for the
// Boost Graph Library along with the software; see the file LICENSE.
// If not, contact Office of Research, University of Notre Dame, Notre
// Dame, IN 46556.
//
// Permission to modify the code and to distribute modified code is
// granted, provided the text of this NOTICE is retained, a notice that
// the code was modified is included with the above COPYRIGHT NOTICE and
// with the COPYRIGHT NOTICE in the LICENSE file, and that the LICENSE
// file is distributed with the modified code.
//
// LICENSOR MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED.
// By way of example, but not limitation, Licensor MAKES NO
// REPRESENTATIONS OR WARRANTIES OF MERCHANTABILITY OR FITNESS FOR ANY
// PARTICULAR PURPOSE OR THAT THE USE OF THE LICENSED SOFTWARE COMPONENTS
// OR DOCUMENTATION WILL NOT INFRINGE ANY PATENTS, COPYRIGHTS, TRADEMARKS
// OR OTHER RIGHTS.
//=======================================================================
//
/*
This file implements the following functions:
template <typename VertexListGraph, typename MutableGraph>
void copy_graph(const VertexListGraph& g_in, MutableGraph& g_out)
template <typename VertexListGraph, typename MutableGraph,
class P, class T, class R>
void copy_graph(const VertexListGraph& g_in, MutableGraph& g_out,
const bgl_named_params<P, T, R>& params)
template <typename IncidenceGraph, typename MutableGraph>
typename graph_traits<MutableGraph>::vertex_descriptor
copy_component(IncidenceGraph& g_in,
typename graph_traits<IncidenceGraph>::vertex_descriptor src,
MutableGraph& g_out)
template <typename IncidenceGraph, typename MutableGraph,
typename P, typename T, typename R>
typename graph_traits<MutableGraph>::vertex_descriptor
copy_component(IncidenceGraph& g_in,
typename graph_traits<IncidenceGraph>::vertex_descriptor src,
MutableGraph& g_out,
const bgl_named_params<P, T, R>& params)
*/
#ifndef BOOST_GRAPH_COPY_HPP
#define BOOST_GRAPH_COPY_HPP
#include <boost/config.hpp>
#include <vector>
#include <boost/graph/graph_traits.hpp>
#include <boost/property_map.hpp>
#include <boost/graph/named_function_params.hpp>
#include <boost/graph/breadth_first_search.hpp>
#include <boost/type_traits/conversion_traits.hpp>
namespace boost {
namespace detail {
// Default edge and vertex property copiers
template <typename Graph1, typename Graph2>
struct edge_copier {
edge_copier(const Graph1& g1, Graph2& g2)
: edge_all_map1(get(edge_all, g1)),
edge_all_map2(get(edge_all, g2)) { }
template <typename Edge1, typename Edge2>
void operator()(const Edge1& e1, Edge2& e2) const {
put(edge_all_map2, e2, get(edge_all_map1, e1));
}
typename property_map<Graph1, edge_all_t>::const_type edge_all_map1;
mutable typename property_map<Graph2, edge_all_t>::type edge_all_map2;
};
template <typename Graph1, typename Graph2>
inline edge_copier<Graph1,Graph2>
make_edge_copier(const Graph1& g1, Graph2& g2)
{
return edge_copier<Graph1,Graph2>(g1, g2);
}
template <typename Graph1, typename Graph2>
struct vertex_copier {
vertex_copier(const Graph1& g1, Graph2& g2)
: vertex_all_map1(get(vertex_all, g1)),
vertex_all_map2(get(vertex_all, g2)) { }
template <typename Vertex1, typename Vertex2>
void operator()(const Vertex1& v1, Vertex2& v2) const {
put(vertex_all_map2, v2, get(vertex_all_map1, v1));
}
typename property_map<Graph1, vertex_all_t>::const_type vertex_all_map1;
mutable typename property_map<Graph2, vertex_all_t>::type
vertex_all_map2;
};
template <typename Graph1, typename Graph2>
inline vertex_copier<Graph1,Graph2>
make_vertex_copier(const Graph1& g1, Graph2& g2)
{
return vertex_copier<Graph1,Graph2>(g1, g2);
}
// Copy all the vertices and edges of graph g_in into graph g_out.
// The copy_vertex and copy_edge function objects control how vertex
// and edge properties are copied.
template <int Version>
struct copy_graph_impl { };
template <> struct copy_graph_impl<0>
{
template <typename Graph, typename MutableGraph,
typename CopyVertex, typename CopyEdge, typename IndexMap,
typename Orig2CopyVertexIndexMap>
static void apply(const Graph& g_in, MutableGraph& g_out,
CopyVertex copy_vertex, CopyEdge copy_edge,
Orig2CopyVertexIndexMap orig2copy, IndexMap)
{
typename graph_traits<Graph>::vertex_iterator vi, vi_end;
for (tie(vi, vi_end) = vertices(g_in); vi != vi_end; ++vi) {
typename graph_traits<MutableGraph>::vertex_descriptor
new_v = add_vertex(g_out);
put(orig2copy, *vi, new_v);
copy_vertex(*vi, new_v);
}
typename graph_traits<Graph>::edge_iterator ei, ei_end;
for (tie(ei, ei_end) = edges(g_in); ei != ei_end; ++ei) {
typename graph_traits<MutableGraph>::edge_descriptor new_e;
bool inserted;
tie(new_e, inserted) = add_edge(get(orig2copy, source(*ei, g_in)),
get(orig2copy, target(*ei, g_in)),
g_out);
copy_edge(*ei, new_e);
}
}
};
// for directed graphs
template <> struct copy_graph_impl<1>
{
template <typename Graph, typename MutableGraph,
typename CopyVertex, typename CopyEdge, typename IndexMap,
typename Orig2CopyVertexIndexMap>
static void apply(const Graph& g_in, MutableGraph& g_out,
CopyVertex copy_vertex, CopyEdge copy_edge,
Orig2CopyVertexIndexMap orig2copy, IndexMap)
{
typename graph_traits<Graph>::vertex_iterator vi, vi_end;
for (tie(vi, vi_end) = vertices(g_in); vi != vi_end; ++vi) {
typename graph_traits<MutableGraph>::vertex_descriptor
new_v = add_vertex(g_out);
put(orig2copy, *vi, new_v);
copy_vertex(*vi, new_v);
}
for (tie(vi, vi_end) = vertices(g_in); vi != vi_end; ++vi) {
typename graph_traits<Graph>::out_edge_iterator ei, ei_end;
for (tie(ei, ei_end) = out_edges(*vi, g_in); ei != ei_end; ++ei) {
typename graph_traits<MutableGraph>::edge_descriptor new_e;
bool inserted;
tie(new_e, inserted) = add_edge(get(orig2copy, source(*ei, g_in)),
get(orig2copy, target(*ei, g_in)),
g_out);
copy_edge(*ei, new_e);
}
}
}
};
// for undirected graphs
template <> struct copy_graph_impl<2>
{
template <typename Graph, typename MutableGraph,
typename CopyVertex, typename CopyEdge, typename IndexMap,
typename Orig2CopyVertexIndexMap>
static void apply(const Graph& g_in, MutableGraph& g_out,
CopyVertex copy_vertex, CopyEdge copy_edge,
Orig2CopyVertexIndexMap orig2copy,
IndexMap index_map)
{
typedef color_traits<default_color_type> Color;
std::vector<default_color_type>
color(num_vertices(g_in), Color::white());
typename graph_traits<Graph>::vertex_iterator vi, vi_end;
for (tie(vi, vi_end) = vertices(g_in); vi != vi_end; ++vi) {
typename graph_traits<MutableGraph>::vertex_descriptor
new_v = add_vertex(g_out);
put(orig2copy, *vi, new_v);
copy_vertex(*vi, new_v);
}
for (tie(vi, vi_end) = vertices(g_in); vi != vi_end; ++vi) {
typename graph_traits<Graph>::out_edge_iterator ei, ei_end;
for (tie(ei, ei_end) = out_edges(*vi, g_in); ei != ei_end; ++ei) {
typename graph_traits<MutableGraph>::edge_descriptor new_e;
bool inserted;
if (color[get(index_map, target(*ei, g_in))] == Color::white()) {
tie(new_e, inserted) = add_edge(get(orig2copy, source(*ei,g_in)),
get(orig2copy, target(*ei,g_in)),
g_out);
copy_edge(*ei, new_e);
}
}
color[get(index_map, *vi)] = Color::black();
}
}
};
template <class Graph>
struct choose_graph_copy {
typedef typename Graph::traversal_category Trv;
typedef typename Graph::directed_category Dr;
enum { algo =
(is_convertible<Trv, vertex_list_graph_tag>::value
&& is_convertible<Trv, edge_list_graph_tag>::value)
? 0 : is_convertible<Dr, directed_tag>::value ? 1 : 2 };
typedef copy_graph_impl<algo> type;
};
//-------------------------------------------------------------------------
struct choose_copier_parameter {
template <class P, class G1, class G2>
struct bind_ {
typedef const P& result_type;
static result_type apply(const P& p, const G1&, G2&)
{ return p; }
};
};
struct choose_default_edge_copier {
template <class P, class G1, class G2>
struct bind_ {
typedef edge_copier<G1, G2> result_type;
static result_type apply(const P&, const G1& g1, G2& g2) {
return result_type(g1, g2);
}
};
};
template <class Param>
struct choose_edge_copy {
typedef choose_copier_parameter type;
};
template <>
struct choose_edge_copy<detail::error_property_not_found> {
typedef choose_default_edge_copier type;
};
template <class Param, class G1, class G2>
struct choose_edge_copier_helper {
typedef typename choose_edge_copy<Param>::type Selector;
typedef typename Selector:: template bind_<Param, G1, G2> Bind;
typedef Bind type;
typedef typename Bind::result_type result_type;
};
template <typename Param, typename G1, typename G2>
typename detail::choose_edge_copier_helper<Param,G1,G2>::result_type
choose_edge_copier(const Param& params, const G1& g_in, G2& g_out)
{
typedef typename
detail::choose_edge_copier_helper<Param,G1,G2>::type Choice;
return Choice::apply(params, g_in, g_out);
}
struct choose_default_vertex_copier {
template <class P, class G1, class G2>
struct bind_ {
typedef vertex_copier<G1, G2> result_type;
static result_type apply(const P&, const G1& g1, G2& g2) {
return result_type(g1, g2);
}
};
};
template <class Param>
struct choose_vertex_copy {
typedef choose_copier_parameter type;
};
template <>
struct choose_vertex_copy<detail::error_property_not_found> {
typedef choose_default_vertex_copier type;
};
template <class Param, class G1, class G2>
struct choose_vertex_copier_helper {
typedef typename choose_vertex_copy<Param>::type Selector;
typedef typename Selector:: template bind_<Param, G1, G2> Bind;
typedef Bind type;
typedef typename Bind::result_type result_type;
};
template <typename Param, typename G1, typename G2>
typename detail::choose_vertex_copier_helper<Param,G1,G2>::result_type
choose_vertex_copier(const Param& params, const G1& g_in, G2& g_out)
{
typedef typename
detail::choose_vertex_copier_helper<Param,G1,G2>::type Choice;
return Choice::apply(params, g_in, g_out);
}
} // namespace detail
template <typename VertexListGraph, typename MutableGraph>
void copy_graph(const VertexListGraph& g_in, MutableGraph& g_out)
{
if (num_vertices(g_in) == 0)
return;
typedef typename graph_traits<MutableGraph>::vertex_descriptor vertex_t;
std::vector<vertex_t> orig2copy(num_vertices(g_in));
typedef typename detail::choose_graph_copy<VertexListGraph>::type
copy_impl;
copy_impl::apply
(g_in, g_out,
detail::make_vertex_copier(g_in, g_out),
detail::make_edge_copier(g_in, g_out),
make_iterator_property_map(orig2copy.begin(),
get(vertex_index, g_in), orig2copy[0]),
get(vertex_index, g_in)
);
}
template <typename VertexListGraph, typename MutableGraph,
class P, class T, class R>
void copy_graph(const VertexListGraph& g_in, MutableGraph& g_out,
const bgl_named_params<P, T, R>& params)
{
typename std::vector<T>::size_type n;
n = is_default_param(get_param(params, orig_to_copy_t()))
? num_vertices(g_in) : 1;
if (n == 0)
return;
std::vector<BOOST_DEDUCED_TYPENAME graph_traits<MutableGraph>::vertex_descriptor>
orig2copy(n);
typedef typename detail::choose_graph_copy<VertexListGraph>::type
copy_impl;
copy_impl::apply
(g_in, g_out,
detail::choose_vertex_copier(get_param(params, vertex_copy_t()),
g_in, g_out),
detail::choose_edge_copier(get_param(params, edge_copy_t()),
g_in, g_out),
choose_param(get_param(params, orig_to_copy_t()),
make_iterator_property_map
(orig2copy.begin(),
choose_const_pmap(get_param(params, vertex_index),
g_in, vertex_index), orig2copy[0])),
choose_const_pmap(get_param(params, vertex_index), g_in, vertex_index)
);
}
namespace detail {
template <class NewGraph, class Copy2OrigIndexMap,
class CopyVertex, class CopyEdge>
struct graph_copy_visitor : public bfs_visitor<>
{
graph_copy_visitor(NewGraph& graph, Copy2OrigIndexMap c,
CopyVertex cv, CopyEdge ce)
: g_out(graph), orig2copy(c), copy_vertex(cv), copy_edge(ce) { }
template <class Vertex, class Graph>
void examine_vertex(Vertex u, const Graph& g_in) const {
typename graph_traits<NewGraph>::vertex_descriptor
new_u = add_vertex(g_out);
put(orig2copy, u, new_u);
copy_vertex(u, new_u);
}
template <class Edge, class Graph>
void examine_edge(Edge e, const Graph& g_in) const {
typename graph_traits<NewGraph>::edge_descriptor new_e;
bool inserted;
tie(new_e, inserted) = add_edge(get(orig2copy, source(e, g_in)),
get(orig2copy, target(e, g_in)),
g_out);
copy_edge(e, new_e);
}
private:
NewGraph& g_out;
Copy2OrigIndexMap orig2copy;
CopyVertex copy_vertex;
CopyEdge copy_edge;
};
template <typename Graph, typename MutableGraph,
typename CopyVertex, typename CopyEdge,
typename Orig2CopyVertexIndexMap, typename Params>
typename graph_traits<MutableGraph>::vertex_descriptor
copy_component_impl
(const Graph& g_in,
typename graph_traits<Graph>::vertex_descriptor src,
MutableGraph& g_out,
CopyVertex copy_vertex, CopyEdge copy_edge,
Orig2CopyVertexIndexMap orig2copy,
const Params& params)
{
graph_copy_visitor<MutableGraph, Orig2CopyVertexIndexMap,
CopyVertex, CopyEdge> vis(g_out, orig2copy, copy_vertex, copy_edge);
breadth_first_search(g_in, src, params.visitor(vis));
return get(orig2copy, src);
}
} // namespace detail
// Copy all the vertices and edges of graph g_in that are reachable
// from the source vertex into graph g_out. Return the vertex
// in g_out that matches the source vertex of g_in.
template <typename IncidenceGraph, typename MutableGraph,
typename P, typename T, typename R>
typename graph_traits<MutableGraph>::vertex_descriptor
copy_component(IncidenceGraph& g_in,
typename graph_traits<IncidenceGraph>::vertex_descriptor src,
MutableGraph& g_out,
const bgl_named_params<P, T, R>& params)
{
typename std::vector<T>::size_type n;
n = is_default_param(get_param(params, orig_to_copy_t()))
? num_vertices(g_in) : 1;
std::vector<typename graph_traits<IncidenceGraph>::vertex_descriptor>
orig2copy(n);
return detail::copy_component_impl
(g_in, src, g_out,
detail::choose_vertex_copier(get_param(params, vertex_copy_t()),
g_in, g_out),
detail::choose_edge_copier(get_param(params, edge_copy_t()),
g_in, g_out),
choose_param(get_param(params, orig_to_copy_t()),
make_iterator_property_map
(orig2copy.begin(),
choose_pmap(get_param(params, vertex_index),
g_in, vertex_index), orig2copy[0])),
params
);
}
template <typename IncidenceGraph, typename MutableGraph>
typename graph_traits<MutableGraph>::vertex_descriptor
copy_component(IncidenceGraph& g_in,
typename graph_traits<IncidenceGraph>::vertex_descriptor src,
MutableGraph& g_out)
{
std::vector<typename graph_traits<IncidenceGraph>::vertex_descriptor>
orig2copy(num_vertices(g_in));
return detail::copy_component_impl
(g_in, src, g_out,
make_vertex_copier(g_in, g_out),
make_edge_copier(g_in, g_out),
make_iterator_property_map(orig2copy.begin(),
get(vertex_index, g_in), orig2copy[0]),
bgl_named_params<char,char>('x') // dummy param object
);
}
} // namespace boost
#endif // BOOST_GRAPH_COPY_HPP

View File

@@ -1,97 +0,0 @@
//=======================================================================
// Copyright 2002 Indiana University.
// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek
//
// This file is part of the Boost Graph Library
//
// You should have received a copy of the License Agreement for the
// Boost Graph Library along with the software; see the file LICENSE.
//
// Permission to modify the code and to distribute modified code is
// granted, provided the text of this NOTICE is retained, a notice that
// the code was modified is included with the above COPYRIGHT NOTICE and
// with the COPYRIGHT NOTICE in the LICENSE file, and that the LICENSE
// file is distributed with the modified code.
//
// LICENSOR MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED.
// By way of example, but not limitation, Licensor MAKES NO
// REPRESENTATIONS OR WARRANTIES OF MERCHANTABILITY OR FITNESS FOR ANY
// PARTICULAR PURPOSE OR THAT THE USE OF THE LICENSED SOFTWARE COMPONENTS
// OR DOCUMENTATION WILL NOT INFRINGE ANY PATENTS, COPYRIGHTS, TRADEMARKS
// OR OTHER RIGHTS.
//=======================================================================
#ifndef BOOST_CREATE_CONDENSATION_GRAPH_HPP
#define BOOST_CREATE_CONDENSATION_GRAPH_HPP
#include <boost/graph/graph_traits.hpp>
#include <boost/property_map.hpp>
namespace boost {
template <typename Graph, typename ComponentLists,
typename ComponentNumberMap,
typename CondensationGraph, typename EdgeMultiplicityMap>
void create_condensation_graph(const Graph& g,
const ComponentLists& components,
ComponentNumberMap component_number,
CondensationGraph& cg,
EdgeMultiplicityMap edge_mult_map)
{
typedef typename graph_traits<Graph>::vertex_descriptor vertex;
typedef typename graph_traits<Graph>::vertices_size_type size_type;
typedef typename graph_traits<CondensationGraph>::vertex_descriptor
cg_vertex;
std::vector<cg_vertex> to_cg_vertex(components.size());
for (size_type s = 0; s < components.size(); ++s)
to_cg_vertex[s] = add_vertex(cg);
for (size_type si = 0; si < components.size(); ++si) {
cg_vertex s = to_cg_vertex[si];
std::vector<cg_vertex> adj;
for (size_type i = 0; i < components[si].size(); ++i) {
vertex u = components[s][i];
typename graph_traits<Graph>::adjacency_iterator v, v_end;
for (tie(v, v_end) = adjacent_vertices(u, g); v != v_end; ++v) {
cg_vertex t = to_cg_vertex[component_number[*v]];
if (s != t) // Avoid loops in the condensation graph
adj.push_back(t);
}
}
std::sort(adj.begin(), adj.end());
if (! adj.empty()) {
size_type i = 0;
cg_vertex t = adj[i];
typename graph_traits<CondensationGraph>::edge_descriptor e;
bool inserted;
tie(e, inserted) = add_edge(s, t, cg);
put(edge_mult_map, e, 1);
++i;
while (i < adj.size()) {
if (adj[i] == t)
put(edge_mult_map, e, get(edge_mult_map, e) + 1);
else {
t = adj[i];
tie(e, inserted) = add_edge(s, t, cg);
put(edge_mult_map, e, 1);
}
++i;
}
}
}
}
template <typename Graph, typename ComponentLists,
typename ComponentNumberMap, typename CondensationGraph>
void create_condensation_graph(const Graph& g,
const ComponentLists& components,
ComponentNumberMap component_number,
CondensationGraph& cg)
{
create_condensation_graph(g, components, component_number, cg,
dummy_property_map());
}
} // namespace boost
#endif // BOOST_CREATE_CONDENSATION_GRAPH_HPP

View File

@@ -1,242 +0,0 @@
//
//=======================================================================
// Copyright 1997, 1998, 1999, 2000 University of Notre Dame.
// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek
//
// This file is part of the Boost Graph Library
//
// You should have received a copy of the License Agreement for the
// Boost Graph Library along with the software; see the file LICENSE.
// If not, contact Office of Research, University of Notre Dame, Notre
// Dame, IN 46556.
//
// Permission to modify the code and to distribute modified code is
// granted, provided the text of this NOTICE is retained, a notice that
// the code was modified is included with the above COPYRIGHT NOTICE and
// with the COPYRIGHT NOTICE in the LICENSE file, and that the LICENSE
// file is distributed with the modified code.
//
// LICENSOR MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED.
// By way of example, but not limitation, Licensor MAKES NO
// REPRESENTATIONS OR WARRANTIES OF MERCHANTABILITY OR FITNESS FOR ANY
// PARTICULAR PURPOSE OR THAT THE USE OF THE LICENSED SOFTWARE COMPONENTS
// OR DOCUMENTATION WILL NOT INFRINGE ANY PATENTS, COPYRIGHTS, TRADEMARKS
// OR OTHER RIGHTS.
//=======================================================================
//
#ifndef BOOST_GRAPH_CUTHILL_MCKEE_HPP
#define BOOST_GRAPH_CUTHILL_MCKEE_HPP
#include <boost/config.hpp>
#include <vector>
#include <queue>
#include <boost/pending/queue.hpp>
#include <boost/graph/graph_traits.hpp>
#include <boost/graph/breadth_first_search.hpp>
#include <boost/graph/properties.hpp>
#include <boost/pending/indirect_cmp.hpp>
#include <boost/property_map.hpp>
/*
(Reverse) Cuthill-McKee Algorithm for matrix reordering
*/
namespace boost {
namespace detail {
// rcm_queue
//
// This is a custom queue type used in the
// reverse_cuthill_mckee_ordering algorithm.
// In addition to the normal queue operations, the
// rcm_queue provides:
//
// int eccentricity() const;
// value_type spouse() const;
//
template < class Vertex, class DegreeMap,
class Container = std::deque<Vertex> >
class rcm_queue : public std::queue<Vertex, Container> {
typedef std::queue<Vertex> base;
public:
typedef typename base::value_type value_type;
typedef typename base::size_type size_type;
/* SGI queue has not had a contructor queue(const Container&) */
inline rcm_queue(DegreeMap deg)
: _size(0), Qsize(1), eccen(-1), degree(deg) { }
inline void pop() {
if ( !_size )
Qsize = base::size();
base::pop();
if ( _size == Qsize-1 ) {
_size = 0;
++eccen;
} else
++_size;
}
inline value_type& front() {
value_type& u = base::front();
if ( _size == 0 )
w = u;
else if (get(degree,u) < get(degree,w) )
w = u;
return u;
}
inline const value_type& front() const {
const value_type& u = base::front();
if ( _size == 0 )
w = u;
else if (get(degree,u) < get(degree,w) )
w = u;
return u;
}
inline value_type& top() { return front(); }
inline const value_type& top() const { return front(); }
inline size_type size() const { return base::size(); }
inline size_type eccentricity() const { return eccen; }
inline value_type spouse() const { return w; }
protected:
size_type _size;
size_type Qsize;
int eccen;
mutable value_type w;
DegreeMap degree;
};
} // namespace detail
// Compute Pseudo peripheral
//
// To compute an approximated peripheral for a given vertex.
// Used in <tt>reverse_cuthill_mckee_ordering</tt> algorithm.
//
template <class Graph, class Vertex, class ColorMap, class DegreeMap>
Vertex
pseudo_peripheral_pair(Graph& G, const Vertex& u, int& ecc,
ColorMap color, DegreeMap degree)
{
typedef typename property_traits<ColorMap>::value_type ColorValue;
typedef color_traits<ColorValue> Color;
detail::rcm_queue<Vertex, DegreeMap> Q(degree);
typename boost::graph_traits<Graph>::vertex_iterator ui, ui_end;
for (tie(ui, ui_end) = vertices(G); ui != ui_end; ++ui)
put(color, *ui, Color::white());
breadth_first_search(G, u, buffer(Q).color_map(color));
ecc = Q.eccentricity();
return Q.spouse();
}
// Find a good starting node
//
// This is to find a good starting node for the
// reverse_cuthill_mckee_ordering algorithm. "good" is in the sense
// of the ordering generated by RCM.
//
template <class Graph, class Vertex, class Color, class Degree>
Vertex find_starting_node(Graph& G, Vertex r, Color color, Degree degree)
{
Vertex x, y;
int eccen_r, eccen_x;
x = pseudo_peripheral_pair(G, r, eccen_r, color, degree);
y = pseudo_peripheral_pair(G, x, eccen_x, color, degree);
while (eccen_x > eccen_r) {
r = x;
eccen_r = eccen_x;
x = y;
y = pseudo_peripheral_pair(G, x, eccen_x, color, degree);
}
return x;
}
// Reverse Cuthill-McKee algorithm with a given starting Vertex.
//
// This algorithm requires user to provide a starting vertex to
// compute RCM ordering.
template <class Graph, class OutputIterator,
class ColorMap, class DegreeMap>
OutputIterator
cuthill_mckee_ordering(Graph& g,
typename graph_traits<Graph>::vertex_descriptor s,
OutputIterator inverse_permutation,
ColorMap color, DegreeMap degree)
{
typedef typename property_traits<DegreeMap>::value_type DS;
typedef typename property_traits<ColorMap>::value_type ColorValue;
typedef color_traits<ColorValue> Color;
typedef typename graph_traits<Graph>::vertex_descriptor Vertex;
typename graph_traits<Graph>::vertex_iterator ui, ui_end;
for (tie(ui, ui_end) = vertices(g); ui != ui_end; ++ui)
put(color, *ui, Color::white());
typedef indirect_cmp<DegreeMap, std::greater<DS> > Compare;
Compare comp(degree);
boost::queue<Vertex> bfs_queue;
std::priority_queue<Vertex, std::vector<Vertex>, Compare>
degree_queue(comp);
Vertex u, v;
// Like BFS, except the adjacent vertices are visited
// in increasing order of degree.
put(color, s, Color::gray());
bfs_queue.push(s);
while (! bfs_queue.empty()) {
u = bfs_queue.top(); bfs_queue.pop();
*inverse_permutation++ = u;
typename graph_traits<Graph>::out_edge_iterator ei, ei_end;
for (tie(ei, ei_end) = out_edges(u, g); ei != ei_end; ++ei) {
v = target(*ei, g);
if (get(color, v) == Color::white()) {
put(color, v, Color::gray());
degree_queue.push(v);
}
}
while (!degree_queue.empty()) {
v = degree_queue.top(); degree_queue.pop();
bfs_queue.push(v);
}
put(color, u, Color::black());
} // while
return inverse_permutation;
}
template < class Graph, class OutputIterator,
class Color, class Degree >
inline OutputIterator
cuthill_mckee_ordering(Graph& G, OutputIterator inverse_permutation,
Color color, Degree degree)
{
typedef typename boost::graph_traits<Graph>::vertex_descriptor Vertex;
typedef typename boost::graph_traits<Graph>::vertex_iterator VerIter;
VerIter ri = vertices(G).first;
Vertex r = *ri;
//if G has several forests, how to let is cover all. ??
Vertex s = find_starting_node(G, r, color, degree);
return cuthill_mckee_ordering(G, s, inverse_permutation, color, degree);
}
} // namespace boost
#endif // BOOST_GRAPH_CUTHILL_MCKEE_HPP

View File

@@ -1,163 +0,0 @@
//=======================================================================
// Copyright 2002 Indiana University.
// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek
//
// This file is part of the Boost Graph Library
//
// You should have received a copy of the License Agreement for the
// Boost Graph Library along with the software; see the file LICENSE.
//
// Permission to modify the code and to distribute modified code is
// granted, provided the text of this NOTICE is retained, a notice that
// the code was modified is included with the above COPYRIGHT NOTICE and
// with the COPYRIGHT NOTICE in the LICENSE file, and that the LICENSE
// file is distributed with the modified code.
//
// LICENSOR MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED.
// By way of example, but not limitation, Licensor MAKES NO
// REPRESENTATIONS OR WARRANTIES OF MERCHANTABILITY OR FITNESS FOR ANY
// PARTICULAR PURPOSE OR THAT THE USE OF THE LICENSED SOFTWARE COMPONENTS
// OR DOCUMENTATION WILL NOT INFRINGE ANY PATENTS, COPYRIGHTS, TRADEMARKS
// OR OTHER RIGHTS.
//=======================================================================
#ifndef BOOST_GRAPH_DAG_SHORTEST_PATHS_HPP
#define BOOST_GRAPH_DAG_SHORTEST_PATHS_HPP
#include <boost/graph/topological_sort.hpp>
#include <boost/graph/dijkstra_shortest_paths.hpp>
// single-source shortest paths for a Directed Acyclic Graph (DAG)
namespace boost {
// Initalize distances and call depth first search
template <class VertexListGraph, class DijkstraVisitor,
class DistanceMap, class WeightMap, class ColorMap,
class PredecessorMap,
class Compare, class Combine,
class DistInf, class DistZero>
inline void
dag_shortest_paths
(const VertexListGraph& g,
typename graph_traits<VertexListGraph>::vertex_descriptor s,
DistanceMap distance, WeightMap weight, ColorMap color,
PredecessorMap pred,
DijkstraVisitor vis, Compare compare, Combine combine,
DistInf inf, DistZero zero)
{
typedef typename graph_traits<VertexListGraph>::vertex_descriptor Vertex;
std::vector<Vertex> rev_topo_order;
rev_topo_order.reserve(num_vertices(g));
topological_sort(g, std::back_inserter(rev_topo_order));
typename graph_traits<VertexListGraph>::vertex_iterator ui, ui_end;
for (tie(ui, ui_end) = vertices(g); ui != ui_end; ++ui) {
put(distance, *ui, inf);
put(pred, *ui, *ui);
}
put(distance, s, zero);
vis.discover_vertex(s, g);
typename std::vector<Vertex>::reverse_iterator i;
for (i = rev_topo_order.rbegin(); i != rev_topo_order.rend(); ++i) {
Vertex u = *i;
vis.examine_vertex(u, g);
typename graph_traits<VertexListGraph>::out_edge_iterator e, e_end;
for (tie(e, e_end) = out_edges(u, g); e != e_end; ++e) {
vis.discover_vertex(target(*e, g), g);
bool decreased = relax(*e, g, weight, pred, distance,
combine, compare);
if (decreased)
vis.edge_relaxed(*e, g);
else
vis.edge_not_relaxed(*e, g);
}
vis.finish_vertex(u, g);
}
}
namespace detail {
// Defaults are the same as Dijkstra's algorithm
// Handle Distance Compare, Combine, Inf and Zero defaults
template <class VertexListGraph, class DijkstraVisitor,
class DistanceMap, class WeightMap, class ColorMap,
class IndexMap, class Params>
inline void
dag_sp_dispatch2
(const VertexListGraph& g,
typename graph_traits<VertexListGraph>::vertex_descriptor s,
DistanceMap distance, WeightMap weight, ColorMap color, IndexMap id,
DijkstraVisitor vis, const Params& params)
{
typedef typename property_traits<DistanceMap>::value_type D;
dummy_property_map p_map;
dag_shortest_paths
(g, s, distance, weight, color,
choose_param(get_param(params, vertex_predecessor), p_map),
vis,
choose_param(get_param(params, distance_compare_t()), std::less<D>()),
choose_param(get_param(params, distance_combine_t()), closed_plus<D>()),
choose_param(get_param(params, distance_inf_t()),
(std::numeric_limits<D>::max)()),
choose_param(get_param(params, distance_zero_t()),
D()));
}
// Handle DistanceMap and ColorMap defaults
template <class VertexListGraph, class DijkstraVisitor,
class DistanceMap, class WeightMap, class ColorMap,
class IndexMap, class Params>
inline void
dag_sp_dispatch1
(const VertexListGraph& g,
typename graph_traits<VertexListGraph>::vertex_descriptor s,
DistanceMap distance, WeightMap weight, ColorMap color, IndexMap id,
DijkstraVisitor vis, const Params& params)
{
typedef typename property_traits<WeightMap>::value_type T;
typename std::vector<T>::size_type n;
n = is_default_param(distance) ? num_vertices(g) : 1;
std::vector<T> distance_map(n);
n = is_default_param(color) ? num_vertices(g) : 1;
std::vector<default_color_type> color_map(n);
dag_sp_dispatch2
(g, s,
choose_param(distance,
make_iterator_property_map(distance_map.begin(), id,
distance_map[0])),
weight,
choose_param(color,
make_iterator_property_map(color_map.begin(), id,
color_map[0])),
id, vis, params);
}
} // namespace detail
template <class VertexListGraph, class Param, class Tag, class Rest>
inline void
dag_shortest_paths
(const VertexListGraph& g,
typename graph_traits<VertexListGraph>::vertex_descriptor s,
const bgl_named_params<Param,Tag,Rest>& params)
{
// assert that the graph is directed...
null_visitor null_vis;
detail::dag_sp_dispatch1
(g, s,
get_param(params, vertex_distance),
choose_const_pmap(get_param(params, edge_weight), g, edge_weight),
get_param(params, vertex_color),
choose_const_pmap(get_param(params, vertex_index), g, vertex_index),
choose_param(get_param(params, graph_visitor),
make_dijkstra_visitor(null_vis)),
params);
}
} // namespace boost
#endif // BOOST_GRAPH_DAG_SHORTEST_PATHS_HPP

View File

@@ -1,386 +0,0 @@
//
//=======================================================================
// Copyright 1997, 1998, 1999, 2000 University of Notre Dame.
// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek
//
// This file is part of the Boost Graph Library
//
// You should have received a copy of the License Agreement for the
// Boost Graph Library along with the software; see the file LICENSE.
// If not, contact Office of Research, University of Notre Dame, Notre
// Dame, IN 46556.
//
// Permission to modify the code and to distribute modified code is
// granted, provided the text of this NOTICE is retained, a notice that
// the code was modified is included with the above COPYRIGHT NOTICE and
// with the COPYRIGHT NOTICE in the LICENSE file, and that the LICENSE
// file is distributed with the modified code.
//
// LICENSOR MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED.
// By way of example, but not limitation, Licensor MAKES NO
// REPRESENTATIONS OR WARRANTIES OF MERCHANTABILITY OR FITNESS FOR ANY
// PARTICULAR PURPOSE OR THAT THE USE OF THE LICENSED SOFTWARE COMPONENTS
// OR DOCUMENTATION WILL NOT INFRINGE ANY PATENTS, COPYRIGHTS, TRADEMARKS
// OR OTHER RIGHTS.
//=======================================================================
//
// Nonrecursive implementation of depth_first_visit_impl submitted by
// Bruce Barr, schmoost <at> yahoo.com, May/June 2003.
//
// (C) Copyright Bruce Barr, 2003
// Permission to copy, use, modify, sell and distribute this software
// is granted provided this copyright notice appears in all copies.
// This software is provided "as is" without express or implied
// warranty, and with no claim as to its suitability for any purpose.
#ifndef BOOST_GRAPH_RECURSIVE_DFS_HPP
#define BOOST_GRAPH_RECURSIVE_DFS_HPP
#include <boost/config.hpp>
#include <boost/graph/graph_traits.hpp>
#include <boost/graph/graph_concepts.hpp>
#include <boost/graph/properties.hpp>
#include <boost/graph/visitors.hpp>
#include <boost/graph/named_function_params.hpp>
#include <boost/ref.hpp>
#include <boost/implicit_cast.hpp>
#include <vector>
#include <utility>
namespace boost {
template <class Visitor, class Graph>
class DFSVisitorConcept {
public:
void constraints() {
function_requires< CopyConstructibleConcept<Visitor> >();
vis.initialize_vertex(u, g);
vis.start_vertex(u, g);
vis.discover_vertex(u, g);
vis.examine_edge(e, g);
vis.tree_edge(e, g);
vis.back_edge(e, g);
vis.forward_or_cross_edge(e, g);
vis.finish_vertex(u, g);
}
private:
Visitor vis;
Graph g;
typename graph_traits<Graph>::vertex_descriptor u;
typename graph_traits<Graph>::edge_descriptor e;
};
namespace detail {
struct nontruth2 {
template<class T, class T2>
bool operator()(const T&, const T2&) const { return false; }
};
// Define BOOST_RECURSIVE_DFS to use older, recursive version.
// It is retained for a while in order to perform performance
// comparison.
#ifndef BOOST_RECURSIVE_DFS
// If the vertex u and the iterators ei and ei_end are thought of as the
// context of the algorithm, each push and pop from the stack could
// be thought of as a context shift.
// Each pass through "while (ei != ei_end)" may refer to the out-edges of
// an entirely different vertex, because the context of the algorithm
// shifts every time a white adjacent vertex is discovered.
// The corresponding context shift back from the adjacent vertex occurs
// after all of its out-edges have been examined.
//
// See http://lists.boost.org/MailArchives/boost/msg48752.php for FAQ.
template <class IncidenceGraph, class DFSVisitor, class ColorMap,
class TerminatorFunc>
void depth_first_visit_impl
(const IncidenceGraph& g,
typename graph_traits<IncidenceGraph>::vertex_descriptor u,
DFSVisitor& vis,
ColorMap color, TerminatorFunc func = TerminatorFunc())
{
function_requires<IncidenceGraphConcept<IncidenceGraph> >();
function_requires<DFSVisitorConcept<DFSVisitor, IncidenceGraph> >();
typedef typename graph_traits<IncidenceGraph>::vertex_descriptor Vertex;
function_requires< ReadWritePropertyMapConcept<ColorMap, Vertex> >();
typedef typename property_traits<ColorMap>::value_type ColorValue;
function_requires< ColorValueConcept<ColorValue> >();
typedef color_traits<ColorValue> Color;
typedef typename graph_traits<IncidenceGraph>::out_edge_iterator Iter;
typedef std::pair<Vertex, std::pair<Iter, Iter> > VertexInfo;
Iter ei, ei_end;
std::vector<VertexInfo> stack;
// Possible optimization for vector
//stack.reserve(num_vertices(g));
typedef typename unwrap_reference<TerminatorFunc>::type TF;
put(color, u, Color::gray());
vis.discover_vertex(u, g);
tie(ei, ei_end) = out_edges(u, g);
// Variable is needed to workaround a borland bug.
TF& fn = static_cast<TF&>(func);
if (fn(u, g)) {
// If this vertex terminates the search, we push empty range
stack.push_back(std::make_pair(u, std::make_pair(ei_end, ei_end)));
} else {
stack.push_back(std::make_pair(u, std::make_pair(ei, ei_end)));
}
while (!stack.empty()) {
VertexInfo& back = stack.back();
u = back.first;
tie(ei, ei_end) = back.second;
stack.pop_back();
while (ei != ei_end) {
Vertex v = target(*ei, g);
vis.examine_edge(*ei, g);
ColorValue v_color = get(color, v);
if (v_color == Color::white()) {
vis.tree_edge(*ei, g);
stack.push_back(std::make_pair(u, std::make_pair(++ei, ei_end)));
u = v;
put(color, u, Color::gray());
vis.discover_vertex(u, g);
tie(ei, ei_end) = out_edges(u, g);
if (fn(u, g)) {
ei = ei_end;
}
} else if (v_color == Color::gray()) {
vis.back_edge(*ei, g);
++ei;
} else {
vis.forward_or_cross_edge(*ei, g);
++ei;
}
}
put(color, u, Color::black());
vis.finish_vertex(u, g);
}
}
#else // BOOST_RECURSIVE_DFS is defined
template <class IncidenceGraph, class DFSVisitor, class ColorMap,
class TerminatorFunc>
void depth_first_visit_impl
(const IncidenceGraph& g,
typename graph_traits<IncidenceGraph>::vertex_descriptor u,
DFSVisitor& vis, // pass-by-reference here, important!
ColorMap color, TerminatorFunc func)
{
function_requires<IncidenceGraphConcept<IncidenceGraph> >();
function_requires<DFSVisitorConcept<DFSVisitor, IncidenceGraph> >();
typedef typename graph_traits<IncidenceGraph>::vertex_descriptor Vertex;
function_requires< ReadWritePropertyMapConcept<ColorMap, Vertex> >();
typedef typename property_traits<ColorMap>::value_type ColorValue;
function_requires< ColorValueConcept<ColorValue> >();
typedef color_traits<ColorValue> Color;
typename graph_traits<IncidenceGraph>::out_edge_iterator ei, ei_end;
put(color, u, Color::gray()); vis.discover_vertex(u, g);
typedef typename unwrap_reference<TerminatorFunc>::type TF;
// Variable is needed to workaround a borland bug.
TF& fn = static_cast<TF&>(func);
if (!fn(u, g))
for (tie(ei, ei_end) = out_edges(u, g); ei != ei_end; ++ei) {
Vertex v = target(*ei, g); vis.examine_edge(*ei, g);
ColorValue v_color = get(color, v);
if (v_color == Color::white()) { vis.tree_edge(*ei, g);
depth_first_visit_impl(g, v, vis, color, func);
} else if (v_color == Color::gray()) vis.back_edge(*ei, g);
else vis.forward_or_cross_edge(*ei, g);
}
put(color, u, Color::black()); vis.finish_vertex(u, g);
}
#endif
} // namespace detail
template <class VertexListGraph, class DFSVisitor, class ColorMap>
void
depth_first_search(const VertexListGraph& g, DFSVisitor vis, ColorMap color,
typename graph_traits<VertexListGraph>::vertex_descriptor start_vertex)
{
typedef typename graph_traits<VertexListGraph>::vertex_descriptor Vertex;
function_requires<DFSVisitorConcept<DFSVisitor, VertexListGraph> >();
typedef typename property_traits<ColorMap>::value_type ColorValue;
typedef color_traits<ColorValue> Color;
typename graph_traits<VertexListGraph>::vertex_iterator ui, ui_end;
for (tie(ui, ui_end) = vertices(g); ui != ui_end; ++ui) {
put(color, *ui, Color::white()); vis.initialize_vertex(*ui, g);
}
if (start_vertex != implicit_cast<Vertex>(*vertices(g).first)){ vis.start_vertex(start_vertex, g);
detail::depth_first_visit_impl(g, start_vertex, vis, color,
detail::nontruth2());
}
for (tie(ui, ui_end) = vertices(g); ui != ui_end; ++ui) {
ColorValue u_color = get(color, *ui);
if (u_color == Color::white()) { vis.start_vertex(*ui, g);
detail::depth_first_visit_impl(g, *ui, vis, color, detail::nontruth2());
}
}
}
template <class VertexListGraph, class DFSVisitor, class ColorMap>
void
depth_first_search(const VertexListGraph& g, DFSVisitor vis, ColorMap color)
{
depth_first_search(g, vis, color, *vertices(g).first);
}
namespace detail {
template <class ColorMap>
struct dfs_dispatch {
template <class VertexListGraph, class Vertex, class DFSVisitor,
class P, class T, class R>
static void
apply(const VertexListGraph& g, DFSVisitor vis, Vertex start_vertex,
const bgl_named_params<P, T, R>&,
ColorMap color)
{
depth_first_search(g, vis, color, start_vertex);
}
};
template <>
struct dfs_dispatch<detail::error_property_not_found> {
template <class VertexListGraph, class Vertex, class DFSVisitor,
class P, class T, class R>
static void
apply(const VertexListGraph& g, DFSVisitor vis, Vertex start_vertex,
const bgl_named_params<P, T, R>& params,
detail::error_property_not_found)
{
std::vector<default_color_type> color_vec(num_vertices(g));
default_color_type c = white_color; // avoid warning about un-init
depth_first_search
(g, vis, make_iterator_property_map
(color_vec.begin(),
choose_const_pmap(get_param(params, vertex_index),
g, vertex_index), c),
start_vertex);
}
};
} // namespace detail
template <class Visitors = null_visitor>
class dfs_visitor {
public:
dfs_visitor() { }
dfs_visitor(Visitors vis) : m_vis(vis) { }
template <class Vertex, class Graph>
void initialize_vertex(Vertex u, const Graph& g) {
invoke_visitors(m_vis, u, g, ::boost::on_initialize_vertex());
}
template <class Vertex, class Graph>
void start_vertex(Vertex u, const Graph& g) {
invoke_visitors(m_vis, u, g, ::boost::on_start_vertex());
}
template <class Vertex, class Graph>
void discover_vertex(Vertex u, const Graph& g) {
invoke_visitors(m_vis, u, g, ::boost::on_discover_vertex());
}
template <class Edge, class Graph>
void examine_edge(Edge u, const Graph& g) {
invoke_visitors(m_vis, u, g, ::boost::on_examine_edge());
}
template <class Edge, class Graph>
void tree_edge(Edge u, const Graph& g) {
invoke_visitors(m_vis, u, g, ::boost::on_tree_edge());
}
template <class Edge, class Graph>
void back_edge(Edge u, const Graph& g) {
invoke_visitors(m_vis, u, g, ::boost::on_back_edge());
}
template <class Edge, class Graph>
void forward_or_cross_edge(Edge u, const Graph& g) {
invoke_visitors(m_vis, u, g, ::boost::on_forward_or_cross_edge());
}
template <class Vertex, class Graph>
void finish_vertex(Vertex u, const Graph& g) {
invoke_visitors(m_vis, u, g, ::boost::on_finish_vertex());
}
BOOST_GRAPH_EVENT_STUB(on_initialize_vertex,dfs)
BOOST_GRAPH_EVENT_STUB(on_start_vertex,dfs)
BOOST_GRAPH_EVENT_STUB(on_discover_vertex,dfs)
BOOST_GRAPH_EVENT_STUB(on_examine_edge,dfs)
BOOST_GRAPH_EVENT_STUB(on_tree_edge,dfs)
BOOST_GRAPH_EVENT_STUB(on_back_edge,dfs)
BOOST_GRAPH_EVENT_STUB(on_forward_or_cross_edge,dfs)
BOOST_GRAPH_EVENT_STUB(on_finish_vertex,dfs)
protected:
Visitors m_vis;
};
template <class Visitors>
dfs_visitor<Visitors>
make_dfs_visitor(Visitors vis) {
return dfs_visitor<Visitors>(vis);
}
typedef dfs_visitor<> default_dfs_visitor;
// Named Parameter Variant
template <class VertexListGraph, class P, class T, class R>
void
depth_first_search(const VertexListGraph& g,
const bgl_named_params<P, T, R>& params)
{
typedef typename property_value< bgl_named_params<P, T, R>,
vertex_color_t>::type C;
detail::dfs_dispatch<C>::apply
(g,
choose_param(get_param(params, graph_visitor),
make_dfs_visitor(null_visitor())),
choose_param(get_param(params, root_vertex_t()),
*vertices(g).first),
params,
get_param(params, vertex_color)
);
}
template <class IncidenceGraph, class DFSVisitor, class ColorMap>
void depth_first_visit
(const IncidenceGraph& g,
typename graph_traits<IncidenceGraph>::vertex_descriptor u,
DFSVisitor vis, ColorMap color)
{
vis.start_vertex(u, g);
detail::depth_first_visit_impl(g, u, vis, color, detail::nontruth2());
}
template <class IncidenceGraph, class DFSVisitor, class ColorMap,
class TerminatorFunc>
void depth_first_visit
(const IncidenceGraph& g,
typename graph_traits<IncidenceGraph>::vertex_descriptor u,
DFSVisitor vis, ColorMap color, TerminatorFunc func = TerminatorFunc())
{
vis.start_vertex(u, g);
detail::depth_first_visit_impl(g, u, vis, color, func);
}
} // namespace boost
#endif

View File

@@ -1,107 +0,0 @@
//
//=======================================================================
// Copyright 1997, 1998, 1999, 2000 University of Notre Dame.
// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek
//
// This file is part of the Boost Graph Library
//
// You should have received a copy of the License Agreement for the
// Boost Graph Library along with the software; see the file LICENSE.
// If not, contact Office of Research, University of Notre Dame, Notre
// Dame, IN 46556.
//
// Permission to modify the code and to distribute modified code is
// granted, provided the text of this NOTICE is retained, a notice that
// the code was modified is included with the above COPYRIGHT NOTICE and
// with the COPYRIGHT NOTICE in the LICENSE file, and that the LICENSE
// file is distributed with the modified code.
//
// LICENSOR MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED.
// By way of example, but not limitation, Licensor MAKES NO
// REPRESENTATIONS OR WARRANTIES OF MERCHANTABILITY OR FITNESS FOR ANY
// PARTICULAR PURPOSE OR THAT THE USE OF THE LICENSED SOFTWARE COMPONENTS
// OR DOCUMENTATION WILL NOT INFRINGE ANY PATENTS, COPYRIGHTS, TRADEMARKS
// OR OTHER RIGHTS.
//=======================================================================
//
#ifndef BOOST_GRAPH_DETAIL_ADJ_LIST_EDGE_ITERATOR_HPP
#define BOOST_GRAPH_DETAIL_ADJ_LIST_EDGE_ITERATOR_HPP
#include <iterator>
namespace boost {
namespace detail {
template <class VertexIterator, class OutEdgeIterator, class Graph>
class adj_list_edge_iterator {
typedef adj_list_edge_iterator self;
public:
typedef std::forward_iterator_tag iterator_category;
typedef typename OutEdgeIterator::value_type value_type;
typedef typename OutEdgeIterator::reference reference;
typedef typename OutEdgeIterator::pointer pointer;
typedef typename OutEdgeIterator::difference_type difference_type;
typedef difference_type distance_type;
inline adj_list_edge_iterator() {}
inline adj_list_edge_iterator(const self& x)
: vBegin(x.vBegin), vCurr(x.vCurr), vEnd(x.vEnd),
eCurr(x.eCurr), eEnd(x.eEnd), m_g(x.m_g) { }
template <class G>
inline adj_list_edge_iterator(VertexIterator b,
VertexIterator c,
VertexIterator e,
const G& g)
: vBegin(b), vCurr(c), vEnd(e), m_g(&g) {
if ( vCurr != vEnd ) {
while ( vCurr != vEnd && out_degree(*vCurr, *m_g) == 0 )
++vCurr;
if ( vCurr != vEnd )
tie(eCurr, eEnd) = out_edges(*vCurr, *m_g);
}
}
/*Note:
In the directed graph cases, it is fine.
For undirected graphs, one edge go through twice.
*/
inline self& operator++() {
++eCurr;
if ( eCurr == eEnd ) {
++vCurr;
while ( vCurr != vEnd && out_degree(*vCurr, *m_g) == 0 )
++vCurr;
if ( vCurr != vEnd )
tie(eCurr, eEnd) = out_edges(*vCurr, *m_g);
}
return *this;
}
inline self operator++(int) {
self tmp = *this;
++(*this);
return tmp;
}
inline value_type operator*() const { return *eCurr; }
inline bool operator==(const self& x) const {
return vCurr == x.vCurr && (vCurr == vEnd || eCurr == x.eCurr);
}
inline bool operator!=(const self& x) const {
return vCurr != x.vCurr || (vCurr != vEnd && eCurr != x.eCurr);
}
protected:
VertexIterator vBegin;
VertexIterator vCurr;
VertexIterator vEnd;
OutEdgeIterator eCurr;
OutEdgeIterator eEnd;
const Graph* m_g;
};
} // namespace detail
}
#endif // BOOST_GRAPH_DETAIL_ADJ_LIST_EDGE_ITERATOR_HPP

File diff suppressed because it is too large Load Diff

View File

@@ -1,196 +0,0 @@
//
//=======================================================================
// Copyright 1997, 1998, 1999, 2000 University of Notre Dame.
// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek
//
// This file is part of the Boost Graph Library
//
// You should have received a copy of the License Agreement for the
// Boost Graph Library along with the software; see the file LICENSE.
// If not, contact Office of Research, University of Notre Dame, Notre
// Dame, IN 46556.
//
// Permission to modify the code and to distribute modified code is
// granted, provided the text of this NOTICE is retained, a notice that
// the code was modified is included with the above COPYRIGHT NOTICE and
// with the COPYRIGHT NOTICE in the LICENSE file, and that the LICENSE
// file is distributed with the modified code.
//
// LICENSOR MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED.
// By way of example, but not limitation, Licensor MAKES NO
// REPRESENTATIONS OR WARRANTIES OF MERCHANTABILITY OR FITNESS FOR ANY
// PARTICULAR PURPOSE OR THAT THE USE OF THE LICENSED SOFTWARE COMPONENTS
// OR DOCUMENTATION WILL NOT INFRINGE ANY PATENTS, COPYRIGHTS, TRADEMARKS
// OR OTHER RIGHTS.
//=======================================================================
//
#ifndef ADSTL_ARRAY_BINARY_TREE_HPP
#define ADSTL_ARRAY_BINARY_TREE_HPP
#include <iterator>
#include <functional>
#include <boost/config.hpp>
namespace adstl {
/*
Note: array_binary_tree is a completey balanced binary tree
*/
#if !defined BOOST_NO_STD_ITERATOR_TRAITS
template <class RandomAccessIterator, class ID>
#else
template <class RandomAccessIterator, class ValueType, class ID>
#endif
class array_binary_tree_node {
public:
typedef array_binary_tree_node ArrayBinaryTreeNode;
typedef RandomAccessIterator rep_iterator;
#if !defined BOOST_NO_STD_ITERATOR_TRAITS
typedef typename std::iterator_traits<RandomAccessIterator>::difference_type
difference_type;
typedef typename std::iterator_traits<RandomAccessIterator>::value_type
value_type;
#else
typedef int difference_type;
typedef ValueType value_type;
#endif
typedef difference_type size_type;
struct children_type {
struct iterator
: boost::iterator<std::bidirectional_iterator_tag, ArrayBinaryTreeNode,
difference_type, array_binary_tree_node*, ArrayBinaryTreeNode&>
{ // replace with iterator_adaptor implementation -JGS
inline iterator() : i(0), n(0) { }
inline iterator(const iterator& x) : r(x.r), i(x.i), n(x.n), id(x.id) { }
inline iterator& operator=(const iterator& x) {
r = x.r; i = x.i; n = x.n;
/*egcs generate a warning*/
id = x.id;
return *this;
}
inline iterator(rep_iterator rr,
size_type ii,
size_type nn,
const ID& _id) : r(rr), i(ii), n(nn), id(_id) { }
inline array_binary_tree_node operator*() {
return ArrayBinaryTreeNode(r, i, n, id); }
inline iterator& operator++() { ++i; return *this; }
inline iterator operator++(int)
{ iterator t = *this; ++(*this); return t; }
inline bool operator==(const iterator& x) const { return i == x.i; }
inline bool operator!=(const iterator& x) const
{ return !(*this == x); }
rep_iterator r;
size_type i;
size_type n;
ID id;
};
inline children_type() : i(0), n(0) { }
inline children_type(const children_type& x)
: r(x.r), i(x.i), n(x.n), id(x.id) { }
inline children_type& operator=(const children_type& x) {
r = x.r; i = x.i; n = x.n;
/*egcs generate a warning*/
id = x.id;
return *this;
}
inline children_type(rep_iterator rr,
size_type ii,
size_type nn,
const ID& _id) : r(rr), i(ii), n(nn), id(_id) { }
inline iterator begin() { return iterator(r, 2 * i + 1, n, id); }
inline iterator end() { return iterator(r, 2 * i + 1 + size(), n, id); }
inline size_type size() const {
size_type c = 2 * i + 1;
size_type s;
if (c + 1 < n) s = 2;
else if (c < n) s = 1;
else s = 0;
return s;
}
rep_iterator r;
size_type i;
size_type n;
ID id;
};
inline array_binary_tree_node() : i(0), n(0) { }
inline array_binary_tree_node(const array_binary_tree_node& x)
: r(x.r), i(x.i), n(x.n), id(x.id) { }
inline ArrayBinaryTreeNode& operator=(const ArrayBinaryTreeNode& x) {
r = x.r;
i = x.i;
n = x.n;
/*egcs generate a warning*/
id = x.id;
return *this;
}
inline array_binary_tree_node(rep_iterator start,
rep_iterator end,
rep_iterator pos, const ID& _id)
: r(start), i(pos - start), n(end - start), id(_id) { }
inline array_binary_tree_node(rep_iterator rr,
size_type ii,
size_type nn, const ID& _id)
: r(rr), i(ii), n(nn), id(_id) { }
inline value_type& value() { return *(r + i); }
inline const value_type& value() const { return *(r + i); }
inline ArrayBinaryTreeNode parent() const {
return ArrayBinaryTreeNode(r, (i - 1) / 2, n, id);
}
inline bool has_parent() const { return i != 0; }
inline children_type children() { return children_type(r, i, n, id); }
/*
inline void swap(array_binary_tree_node x) {
value_type tmp = x.value();
x.value() = value();
value() = tmp;
i = x.i;
}
*/
template <class ExternalData>
inline void swap(ArrayBinaryTreeNode x, ExternalData& edata ) {
value_type tmp = x.value();
/*swap external data*/
edata[ boost::get(id, tmp) ] = i;
edata[ boost::get(id, value()) ] = x.i;
x.value() = value();
value() = tmp;
i = x.i;
}
inline const children_type children() const {
return children_type(r, i, n);
}
inline size_type index() const { return i; }
rep_iterator r;
size_type i;
size_type n;
ID id;
};
template <class RandomAccessContainer,
class Compare = std::less<typename RandomAccessContainer::value_type> >
struct compare_array_node {
typedef typename RandomAccessContainer::value_type value_type;
compare_array_node(const Compare& x) : comp(x) {}
compare_array_node(const compare_array_node& x) : comp(x.comp) {}
template< class node_type >
inline bool operator()(const node_type& x, const node_type& y) {
return comp(x.value(), y.value());
}
template< class node_type >
inline bool operator()(const node_type& x, const node_type& y) const {
return comp(x.value(), y.value());
}
Compare comp;
};
} /* namespace adstl */
#endif /* ADSTL_ARRAY_BINARY_TREE_H */

View File

@@ -1,907 +0,0 @@
// (C) Copyright Jeremy Siek 2001. Permission to copy, use, modify,
// sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
/*
* Copyright (c) 1998
* Silicon Graphics Computer Systems, Inc.
*
* Permission to use, copy, modify, distribute and sell this software
* and its documentation for any purpose is hereby granted without fee,
* provided that the above copyright notice appear in all copies and
* that both that copyright notice and this permission notice appear
* in supporting documentation. Silicon Graphics makes no
* representations about the suitability of this software for any
* purpose. It is provided "as is" without express or implied warranty.
*/
#include <boost/config.hpp>
#include <memory>
#include <stdexcept>
#include <algorithm>
#include <string>
#include <boost/config.hpp>
#include <boost/pending/ct_if.hpp>
#include <boost/graph/detail/bitset_adaptor.hpp>
// This provides versions of std::bitset with both static and dynamic size.
// UNDER CONSTRUCTION
// replace this later
#include <cassert>
#define BOOST_ASSERT_THROW(expr, except) assert(expr)
namespace boost {
namespace detail {
// structure to aid in counting bits
template<bool dummy = true>
struct bit_count {
static unsigned char value[256];
};
// Mapping from 8 bit unsigned integers to the index of the first bit
template<bool dummy = true>
struct first_bit_location {
static unsigned char value[256];
};
template <typename WordType> // this size is in bits
struct word_traits {
typedef WordType word_type;
static const std::size_t word_size = CHAR_BIT * sizeof(word_type);
};
//=========================================================================
template <class WordTraits, class SizeType, class Derived>
class bitset_base
: public bitset_adaptor< SizeType,
bitset_base<WordTraits, SizeType, Derived> >
{
// private:
public:
typedef SizeType size_type;
typedef typename WordTraits::word_type word_type;
static size_type s_which_word(size_type pos) {
return pos / WordTraits::word_size;
}
static size_type s_which_byte(size_type pos) {
return (pos % WordTraits::word_size) / CHAR_BIT;
}
static size_type s_which_bit(size_type pos) {
return pos % WordTraits::word_size;
}
static word_type s_mask_bit(size_type pos) {
return (static_cast<word_type>(1)) << s_which_bit(pos);
}
word_type& m_get_word(size_type pos) {
return data()[s_which_word(pos)];
}
word_type m_get_word(size_type pos) const {
return data()[s_which_word(pos)];
}
word_type& m_hi_word() { return data()[num_words() - 1]; }
word_type m_hi_word() const { return data()[num_words() - 1]; }
void m_sanitize_highest() {
size_type extra_bits = size() % WordTraits::word_size;
if (extra_bits)
m_hi_word() &= ~((~static_cast<word_type>(0)) << extra_bits);
}
public:
class reference {
friend class bitset_base;
word_type *m_word_ptr;
size_type m_bit_pos;
// left undefined
reference();
reference(bitset_base& b, size_type pos ) {
m_word_ptr = &b.m_get_word(pos);
m_bit_pos = s_which_bit(pos);
}
public:
~reference() {}
// for b[i] = x;
reference& operator=(bool x) {
if ( x )
*m_word_ptr |= s_mask_bit(m_bit_pos);
else
*m_word_ptr &= ~s_mask_bit(m_bit_pos);
return *this;
}
// for b[i] = b[j];
reference& operator=(const reference& j) {
if ( (*(j.m_word_ptr) & s_mask_bit(j.m_bit_pos)) )
*m_word_ptr |= s_mask_bit(m_bit_pos);
else
*m_word_ptr &= ~s_mask_bit(m_bit_pos);
return *this;
}
// flips the bit
bool operator~() const {
return (*(m_word_ptr) & s_mask_bit(m_bit_pos)) == 0;
}
// for x = b[i];
operator bool() const {
return (*(m_word_ptr) & s_mask_bit(m_bit_pos)) != 0;
}
// for b[i].flip();
reference& flip() {
*m_word_ptr ^= s_mask_bit(m_bit_pos);
return *this;
}
};
void init_from_ulong(unsigned long val) {
reset();
const size_type n = (std::min)(sizeof(unsigned long) * CHAR_BIT,
WordTraits::word_size * num_words());
for(size_type i = 0; i < n; ++i, val >>= 1)
if ( val & 0x1 )
m_get_word(i) |= s_mask_bit(i);
}
// intersection: this = this & x
Derived& operator&=(const Derived& x) {
for (size_type i = 0; i < num_words(); ++i)
data()[i] &= x.data()[i];
return static_cast<Derived&>(*this);
}
// union: this = this | x
Derived& operator|=(const Derived& x) {
for (size_type i = 0; i < num_words(); ++i)
data()[i] |= x.data()[i];
return static_cast<Derived&>(*this);
}
// exclusive or: this = this ^ x
Derived& operator^=(const Derived& x) {
for (size_type i = 0; i < num_words(); ++i)
data()[i] ^= x.data()[i];
return static_cast<Derived&>(*this);
}
// left shift
Derived& operator<<=(size_type pos);
// right shift
Derived& operator>>=(size_type pos);
Derived& set() {
for (size_type i = 0; i < num_words(); ++i)
data()[i] = ~static_cast<word_type>(0);
m_sanitize_highest();
return static_cast<Derived&>(*this);
}
Derived& set(size_type pos, int val = true)
{
BOOST_ASSERT_THROW(pos < size(), std::out_of_range("boost::bitset::set(pos,value)"));
if (val)
m_get_word(pos) |= s_mask_bit(pos);
else
m_get_word(pos) &= ~s_mask_bit(pos);
return static_cast<Derived&>(*this);
}
Derived& reset() {
for (size_type i = 0; i < num_words(); ++i)
data()[i] = 0;
return static_cast<Derived&>(*this);
}
Derived& reset(size_type pos) {
BOOST_ASSERT_THROW(pos < size(), std::out_of_range("boost::bitset::reset(pos)"));
m_get_word(pos) &= ~s_mask_bit(pos);
return static_cast<Derived&>(*this);
}
// compliment
Derived operator~() const {
return Derived(static_cast<const Derived&>(*this)).flip();
}
Derived& flip() {
for (size_type i = 0; i < num_words(); ++i)
data()[i] = ~data()[i];
m_sanitize_highest();
return static_cast<Derived&>(*this);
}
Derived& flip(size_type pos) {
BOOST_ASSERT_THROW(pos < size(), std::out_of_range("boost::bitset::flip(pos)"));
m_get_word(pos) ^= s_mask_bit(pos);
return static_cast<Derived&>(*this);
}
// element access
reference operator[](size_type pos) { return reference(*this, pos); }
bool operator[](size_type pos) const { return test(pos); }
unsigned long to_ulong() const;
// to_string
size_type count() const {
size_type result = 0;
const unsigned char* byte_ptr = (const unsigned char*)data();
const unsigned char* end_ptr =
(const unsigned char*)(data() + num_words());
while ( byte_ptr < end_ptr ) {
result += bit_count<>::value[*byte_ptr];
byte_ptr++;
}
return result;
}
// size() must be provided by Derived class
bool operator==(const Derived& x) const {
return std::equal(data(), data() + num_words(), x.data());
}
bool operator!=(const Derived& x) const {
return ! this->operator==(x);
}
bool test(size_type pos) const {
BOOST_ASSERT_THROW(pos < size(), std::out_of_range("boost::bitset::test(pos)"));
return (m_get_word(pos) & s_mask_bit(pos))
!= static_cast<word_type>(0);
}
bool any() const {
for (size_type i = 0; i < num_words(); ++i) {
if ( data()[i] != static_cast<word_type>(0) )
return true;
}
return false;
}
bool none() const {
return !any();
}
Derived operator<<(size_type pos) const
{ return Derived(static_cast<const Derived&>(*this)) <<= pos; }
Derived operator>>(size_type pos) const
{ return Derived(static_cast<const Derived&>(*this)) >>= pos; }
template <class CharT, class Traits, class Alloc>
void m_copy_from_string(const basic_string<CharT,Traits,Alloc>& s,
size_type pos, size_type n)
{
reset();
const size_type nbits = (std::min)(size(), (std::min)(n, s.size() - pos));
for (size_type i = 0; i < nbits; ++i) {
switch(s[pos + nbits - i - 1]) {
case '0':
break;
case '1':
this->set(i);
break;
default:
throw std::invalid_argument
("boost::bitset_base::m_copy_from_string(s, pos, n)");
}
}
}
template <class CharT, class Traits, class Alloc>
void m_copy_to_string(basic_string<CharT, Traits, Alloc>& s) const
{
s.assign(size(), '0');
for (size_type i = 0; i < size(); ++i)
if (test(i))
s[size() - 1 - i] = '1';
}
//-----------------------------------------------------------------------
// Stuff not in std::bitset
// difference: this = this - x
Derived& operator-=(const Derived& x) {
for (size_type i = 0; i < num_words(); ++i)
data()[i] &= ~x.data()[i];
return static_cast<Derived&>(*this);
}
// this wasn't working, why?
int compare_3way(const Derived& x) const {
return std::lexicographical_compare_3way
(data(), data() + num_words(), x.data(), x.data() + x.num_words());
}
// less-than compare
bool operator<(const Derived& x) const {
return std::lexicographical_compare
(data(), data() + num_words(), x.data(), x.data() + x.num_words());
}
// find the index of the first "on" bit
size_type find_first() const;
// find the index of the next "on" bit after prev
size_type find_next(size_type prev) const;
size_type _Find_first() const { return find_first(); }
// find the index of the next "on" bit after prev
size_type _Find_next(size_type prev) const { return find_next(prev); }
// private:
word_type* data()
{ return static_cast<Derived*>(this)->data(); }
const word_type* data() const
{ return static_cast<const Derived*>(this)->data(); }
size_type num_words() const
{ return static_cast<const Derived*>(this)->num_words(); }
size_type size() const
{ return static_cast<const Derived*>(this)->size(); }
};
// 23.3.5.3 bitset operations:
template <class W, class S, class D>
inline D operator&(const bitset_base<W,S,D>& x,
const bitset_base<W,S,D>& y) {
D result(static_cast<const D&>(x));
result &= static_cast<const D&>(y);
return result;
}
template <class W, class S, class D>
inline D operator|(const bitset_base<W,S,D>& x,
const bitset_base<W,S,D>& y) {
D result(static_cast<const D&>(x));
result |= static_cast<const D&>(y);
return result;
}
template <class W, class S, class D>
inline D operator^(const bitset_base<W,S,D>& x,
const bitset_base<W,S,D>& y) {
D result(static_cast<const D&>(x));
result ^= static_cast<const D&>(y);
return result;
}
// this one is an extension
template <class W, class S, class D>
inline D operator-(const bitset_base<W,S,D>& x,
const bitset_base<W,S,D>& y) {
D result(static_cast<const D&>(x));
result -= static_cast<const D&>(y);
return result;
}
template <class W, class S, class D>
inline int compare_3way(const bitset_base<W,S,D>& x,
const bitset_base<W,S,D>& y) {
return std::lexicographical_compare_3way
(x.data(), x.data() + x.num_words(),
y.data(), y.data() + y.num_words());
}
template <class W, class S, class D>
std::istream&
operator>>(std::istream& is, bitset_base<W,S,D>& x) {
std::string tmp;
tmp.reserve(x.size());
// In new templatized iostreams, use istream::sentry
if (is.flags() & ios::skipws) {
char c;
do
is.get(c);
while (is && isspace(c));
if (is)
is.putback(c);
}
for (S i = 0; i < x.size(); ++i) {
char c;
is.get(c);
if (!is)
break;
else if (c != '0' && c != '1') {
is.putback(c);
break;
}
else
// tmp.push_back(c);
tmp += c;
}
if (tmp.empty())
is.clear(is.rdstate() | ios::failbit);
else
x.m_copy_from_string(tmp, static_cast<S>(0), x.size());
return is;
}
template <class W, class S, class D>
std::ostream& operator<<(std::ostream& os,
const bitset_base<W,S,D>& x) {
std::string tmp;
x.m_copy_to_string(tmp);
return os << tmp;
}
//=========================================================================
template <typename WordType = unsigned long,
typename SizeType = std::size_t,
typename Allocator = std::allocator<WordType>
>
class dyn_size_bitset
: public bitset_base<word_traits<WordType>, SizeType,
dyn_size_bitset<WordType,SizeType,Allocator> >
{
typedef dyn_size_bitset self;
public:
typedef SizeType size_type;
private:
typedef word_traits<WordType> WordTraits;
static const size_type word_size = WordTraits::word_size;
public:
dyn_size_bitset(unsigned long val,
size_type n,
const Allocator& alloc = Allocator())
: m_data(alloc.allocate((n + word_size - 1) / word_size)),
m_size(n),
m_num_words((n + word_size - 1) / word_size),
m_alloc(alloc)
{
init_from_ulong(val);
}
dyn_size_bitset(size_type n, // size of the set's "universe"
const Allocator& alloc = Allocator())
: m_data(alloc.allocate((n + word_size - 1) / word_size)),
m_size(n), m_num_words((n + word_size - 1) / word_size),
m_alloc(alloc)
{ }
template<class CharT, class Traits, class Alloc>
explicit dyn_size_bitset
(const basic_string<CharT,Traits,Alloc>& s,
std::size_t pos = 0,
std::size_t n = std::size_t(basic_string<CharT,Traits,Alloc>::npos),
const Allocator& alloc = Allocator())
: m_data(alloc.allocate((n + word_size - 1) / word_size)),
m_size(n), m_num_words((n + word_size - 1) / word_size),
m_alloc(alloc)
{
BOOST_ASSERT_THROW(pos < s.size(), std::out_of_range("dyn_size_bitset::dyn_size_bitset(s,pos,n,alloc)"));
m_copy_from_string(s, pos, n);
}
template <typename InputIterator>
explicit dyn_size_bitset
(InputIterator first, InputIterator last,
size_type n, // size of the set's "universe"
const Allocator& alloc = Allocator())
: m_data(alloc.allocate((n + word_size - 1) / word_size)),
m_size(N), m_num_words((n + word_size - 1) / word_size),
m_alloc(alloc)
{
while (first != last)
this->set(*first++);
}
~dyn_size_bitset() {
m_alloc.deallocate(m_data, m_num_words);
}
size_type size() const { return m_size; }
// protected:
size_type num_words() const { return m_num_words; }
word_type* data() { return m_data; }
const word_type* data() const { return m_data; }
protected:
word_type* m_data;
SizeType m_size;
SizeType m_num_words;
Allocator m_alloc;
};
//=========================================================================
template <std::size_t N, typename WordType = unsigned long,
typename SizeType = std::size_t>
class bitset
: public bitset_base<word_traits<WordType>, SizeType,
bitset<N, WordType, SizeType> >
{
typedef bitset self;
static const std::size_t word_size = word_traits<WordType>::word_size;
public:
// 23.3.5.1 constructors:
bitset() {
#if defined(__GNUC__)
for (size_type i = 0; i < num_words(); ++i)
m_data[i] = static_cast<WordType>(0);
#endif
}
bitset(unsigned long val) {
init_from_ulong(val);
}
template<class CharT, class Traits, class Alloc>
explicit bitset
(const basic_string<CharT,Traits,Alloc>& s,
std::size_t pos = 0,
std::size_t n = std::size_t(basic_string<CharT,Traits,Alloc>::npos))
{
BOOST_ASSERT_THROW
(pos < s.size(), std::out_of_range("bitset::bitset(s,pos,n)"));
m_copy_from_string(s, pos, n);
}
size_type size() const { return N; }
// protected:
size_type num_words() const { return (N + word_size - 1) / word_size; }
word_type* data() { return m_data; }
const word_type* data() const { return m_data; }
protected:
word_type m_data[(N + word_size - 1) / word_size];
};
//=========================================================================
struct select_static_bitset {
template <std::size_t N, typename WordT, typename SizeT, typename Alloc>
struct bind_ {
typedef bitset<N, WordT, SizeT> type;
};
};
struct select_dyn_size_bitset {
template <std::size_t N, typename WordT, typename SizeT, typename Alloc>
struct bind_ {
typedef dyn_size_bitset<WordT, SizeT, Alloc> type;
};
};
template <std::size_t N = 0, // 0 means use dynamic
typename WordType = unsigned long,
typename Size_type = std::size_t,
typename Allocator = std::allocator<WordType>
>
class bitset_generator {
typedef typename ct_if<N, select_dyn_size_bitset,
select_static_bitset>::type selector;
public:
typedef typename selector
::template bind_<N, WordType, SizeType, Allocator>::type type;
};
//=========================================================================
// bitset_base non-inline member function implementations
template <class WordTraits, class SizeType, class Derived>
Derived&
bitset_base<WordTraits, SizeType, Derived>::
operator<<=(size_type shift)
{
typedef typename WordTraits::word_type word_type;
typedef SizeType size_type;
if (shift != 0) {
const size_type wshift = shift / WordTraits::word_size;
const size_type offset = shift % WordTraits::word_size;
const size_type sub_offset = WordTraits::word_size - offset;
size_type n = num_words() - 1;
for ( ; n > wshift; --n)
data()[n] = (data()[n - wshift] << offset) |
(data()[n - wshift - 1] >> sub_offset);
if (n == wshift)
data()[n] = data()[0] << offset;
for (size_type n1 = 0; n1 < n; ++n1)
data()[n1] = static_cast<word_type>(0);
}
m_sanitize_highest();
return static_cast<Derived&>(*this);
} // end operator<<=
template <class WordTraits, class SizeType, class Derived>
Derived&
bitset_base<WordTraits, SizeType, Derived>::
operator>>=(size_type shift)
{
typedef typename WordTraits::word_type word_type;
typedef SizeType size_type;
if (shift != 0) {
const size_type wshift = shift / WordTraits::word_size;
const size_type offset = shift % WordTraits::word_size;
const size_type sub_offset = WordTraits::word_size - offset;
const size_type limit = num_words() - wshift - 1;
size_type n = 0;
for ( ; n < limit; ++n)
data()[n] = (data()[n + wshift] >> offset) |
(data()[n + wshift + 1] << sub_offset);
data()[limit] = data()[num_words()-1] >> offset;
for (size_type n1 = limit + 1; n1 < num_words(); ++n1)
data()[n1] = static_cast<word_type>(0);
}
m_sanitize_highest();
return static_cast<Derived&>(*this);
} // end operator>>=
template <class WordTraits, class SizeType, class Derived>
unsigned long bitset_base<WordTraits, SizeType, Derived>::
to_ulong() const
{
typedef typename WordTraits::word_type word_type;
typedef SizeType size_type;
const std::overflow_error
overflow("boost::bit_set::operator unsigned long()");
if (sizeof(word_type) >= sizeof(unsigned long)) {
for (size_type i = 1; i < num_words(); ++i)
BOOST_ASSERT_THROW(! data()[i], overflow);
const word_type mask
= static_cast<word_type>(static_cast<unsigned long>(-1));
BOOST_ASSERT_THROW(! (data()[0] & ~mask), overflow);
return static_cast<unsigned long>(data()[0] & mask);
}
else { // sizeof(word_type) < sizeof(unsigned long).
const size_type nwords =
(sizeof(unsigned long) + sizeof(word_type) - 1) / sizeof(word_type);
size_type min_nwords = nwords;
if (num_words() > nwords) {
for (size_type i = nwords; i < num_words(); ++i)
BOOST_ASSERT_THROW(!data()[i], overflow);
}
else
min_nwords = num_words();
// If unsigned long is 8 bytes and word_type is 6 bytes, then
// an unsigned long consists of all of one word plus 2 bytes
// from another word.
const size_type part = sizeof(unsigned long) % sizeof(word_type);
#if 0
// bug in here?
// >> to far?
BOOST_ASSERT_THROW((part != 0
&& nwords <= num_words()
&& (data()[min_nwords - 1] >>
((sizeof(word_type) - part) * CHAR_BIT)) != 0),
overflow);
#endif
unsigned long result = 0;
for (size_type i = 0; i < min_nwords; ++i) {
result |= static_cast<unsigned long>(
data()[i]) << (i * sizeof(word_type) * CHAR_BIT);
}
return result;
}
}// end operator unsigned long()
template <class WordTraits, class SizeType, class Derived>
SizeType bitset_base<WordTraits,SizeType,Derived>::
find_first() const
{
SizeType not_found = size();
for (size_type i = 0; i < num_words(); i++ ) {
word_type thisword = data()[i];
if ( thisword != static_cast<word_type>(0) ) {
// find byte within word
for ( std::size_t j = 0; j < sizeof(word_type); j++ ) {
unsigned char this_byte
= static_cast<unsigned char>(thisword & (~(unsigned char)0));
if ( this_byte )
return i * WordTraits::word_size + j * CHAR_BIT +
first_bit_location<>::value[this_byte];
thisword >>= CHAR_BIT;
}
}
}
// not found, so return an indication of failure.
return not_found;
}
template <class WordTraits, class SizeType, class Derived>
SizeType bitset_base<WordTraits, SizeType, Derived>::
bitset_base<WordTraits,SizeType,Derived>::
find_next(size_type prev) const
{
SizeType not_found = size();
// make bound inclusive
++prev;
// check out of bounds
if ( prev >= num_words() * WordTraits::word_size )
return not_found;
// search first word
size_type i = s_which_word(prev);
word_type thisword = data()[i];
// mask off bits below bound
thisword &= (~static_cast<word_type>(0)) << s_which_bit(prev);
if ( thisword != static_cast<word_type>(0) ) {
// find byte within word
// get first byte into place
thisword >>= s_which_byte(prev) * CHAR_BIT;
for ( size_type j = s_which_byte(prev); j < sizeof(word_type); j++ ) {
unsigned char this_byte
= static_cast<unsigned char>(thisword & (~(unsigned char)0));
if ( this_byte )
return i * WordTraits::word_size + j * CHAR_BIT +
first_bit_location<>::value[this_byte];
thisword >>= CHAR_BIT;
}
}
// check subsequent words
i++;
for ( ; i < num_words(); i++ ) {
word_type thisword = data()[i];
if ( thisword != static_cast<word_type>(0) ) {
// find byte within word
for ( size_type j = 0; j < sizeof(word_type); j++ ) {
unsigned char this_byte
= static_cast<unsigned char>(thisword & (~(unsigned char)0));
if ( this_byte )
return i * WordTraits::word_size + j * CHAR_BIT +
first_bit_location<>::value[this_byte];
thisword >>= CHAR_BIT;
}
}
}
// not found, so return an indication of failure.
return not_found;
} // end find_next
template <bool dummy>
unsigned char bit_count<dummy>::value[] = {
0, /* 0 */ 1, /* 1 */ 1, /* 2 */ 2, /* 3 */ 1, /* 4 */
2, /* 5 */ 2, /* 6 */ 3, /* 7 */ 1, /* 8 */ 2, /* 9 */
2, /* 10 */ 3, /* 11 */ 2, /* 12 */ 3, /* 13 */ 3, /* 14 */
4, /* 15 */ 1, /* 16 */ 2, /* 17 */ 2, /* 18 */ 3, /* 19 */
2, /* 20 */ 3, /* 21 */ 3, /* 22 */ 4, /* 23 */ 2, /* 24 */
3, /* 25 */ 3, /* 26 */ 4, /* 27 */ 3, /* 28 */ 4, /* 29 */
4, /* 30 */ 5, /* 31 */ 1, /* 32 */ 2, /* 33 */ 2, /* 34 */
3, /* 35 */ 2, /* 36 */ 3, /* 37 */ 3, /* 38 */ 4, /* 39 */
2, /* 40 */ 3, /* 41 */ 3, /* 42 */ 4, /* 43 */ 3, /* 44 */
4, /* 45 */ 4, /* 46 */ 5, /* 47 */ 2, /* 48 */ 3, /* 49 */
3, /* 50 */ 4, /* 51 */ 3, /* 52 */ 4, /* 53 */ 4, /* 54 */
5, /* 55 */ 3, /* 56 */ 4, /* 57 */ 4, /* 58 */ 5, /* 59 */
4, /* 60 */ 5, /* 61 */ 5, /* 62 */ 6, /* 63 */ 1, /* 64 */
2, /* 65 */ 2, /* 66 */ 3, /* 67 */ 2, /* 68 */ 3, /* 69 */
3, /* 70 */ 4, /* 71 */ 2, /* 72 */ 3, /* 73 */ 3, /* 74 */
4, /* 75 */ 3, /* 76 */ 4, /* 77 */ 4, /* 78 */ 5, /* 79 */
2, /* 80 */ 3, /* 81 */ 3, /* 82 */ 4, /* 83 */ 3, /* 84 */
4, /* 85 */ 4, /* 86 */ 5, /* 87 */ 3, /* 88 */ 4, /* 89 */
4, /* 90 */ 5, /* 91 */ 4, /* 92 */ 5, /* 93 */ 5, /* 94 */
6, /* 95 */ 2, /* 96 */ 3, /* 97 */ 3, /* 98 */ 4, /* 99 */
3, /* 100 */ 4, /* 101 */ 4, /* 102 */ 5, /* 103 */ 3, /* 104 */
4, /* 105 */ 4, /* 106 */ 5, /* 107 */ 4, /* 108 */ 5, /* 109 */
5, /* 110 */ 6, /* 111 */ 3, /* 112 */ 4, /* 113 */ 4, /* 114 */
5, /* 115 */ 4, /* 116 */ 5, /* 117 */ 5, /* 118 */ 6, /* 119 */
4, /* 120 */ 5, /* 121 */ 5, /* 122 */ 6, /* 123 */ 5, /* 124 */
6, /* 125 */ 6, /* 126 */ 7, /* 127 */ 1, /* 128 */ 2, /* 129 */
2, /* 130 */ 3, /* 131 */ 2, /* 132 */ 3, /* 133 */ 3, /* 134 */
4, /* 135 */ 2, /* 136 */ 3, /* 137 */ 3, /* 138 */ 4, /* 139 */
3, /* 140 */ 4, /* 141 */ 4, /* 142 */ 5, /* 143 */ 2, /* 144 */
3, /* 145 */ 3, /* 146 */ 4, /* 147 */ 3, /* 148 */ 4, /* 149 */
4, /* 150 */ 5, /* 151 */ 3, /* 152 */ 4, /* 153 */ 4, /* 154 */
5, /* 155 */ 4, /* 156 */ 5, /* 157 */ 5, /* 158 */ 6, /* 159 */
2, /* 160 */ 3, /* 161 */ 3, /* 162 */ 4, /* 163 */ 3, /* 164 */
4, /* 165 */ 4, /* 166 */ 5, /* 167 */ 3, /* 168 */ 4, /* 169 */
4, /* 170 */ 5, /* 171 */ 4, /* 172 */ 5, /* 173 */ 5, /* 174 */
6, /* 175 */ 3, /* 176 */ 4, /* 177 */ 4, /* 178 */ 5, /* 179 */
4, /* 180 */ 5, /* 181 */ 5, /* 182 */ 6, /* 183 */ 4, /* 184 */
5, /* 185 */ 5, /* 186 */ 6, /* 187 */ 5, /* 188 */ 6, /* 189 */
6, /* 190 */ 7, /* 191 */ 2, /* 192 */ 3, /* 193 */ 3, /* 194 */
4, /* 195 */ 3, /* 196 */ 4, /* 197 */ 4, /* 198 */ 5, /* 199 */
3, /* 200 */ 4, /* 201 */ 4, /* 202 */ 5, /* 203 */ 4, /* 204 */
5, /* 205 */ 5, /* 206 */ 6, /* 207 */ 3, /* 208 */ 4, /* 209 */
4, /* 210 */ 5, /* 211 */ 4, /* 212 */ 5, /* 213 */ 5, /* 214 */
6, /* 215 */ 4, /* 216 */ 5, /* 217 */ 5, /* 218 */ 6, /* 219 */
5, /* 220 */ 6, /* 221 */ 6, /* 222 */ 7, /* 223 */ 3, /* 224 */
4, /* 225 */ 4, /* 226 */ 5, /* 227 */ 4, /* 228 */ 5, /* 229 */
5, /* 230 */ 6, /* 231 */ 4, /* 232 */ 5, /* 233 */ 5, /* 234 */
6, /* 235 */ 5, /* 236 */ 6, /* 237 */ 6, /* 238 */ 7, /* 239 */
4, /* 240 */ 5, /* 241 */ 5, /* 242 */ 6, /* 243 */ 5, /* 244 */
6, /* 245 */ 6, /* 246 */ 7, /* 247 */ 5, /* 248 */ 6, /* 249 */
6, /* 250 */ 7, /* 251 */ 6, /* 252 */ 7, /* 253 */ 7, /* 254 */
8 /* 255 */
}; // end _Bit_count
template <bool dummy>
unsigned char first_bit_location<dummy>::value[] = {
0, /* 0 */ 0, /* 1 */ 1, /* 2 */ 0, /* 3 */ 2, /* 4 */
0, /* 5 */ 1, /* 6 */ 0, /* 7 */ 3, /* 8 */ 0, /* 9 */
1, /* 10 */ 0, /* 11 */ 2, /* 12 */ 0, /* 13 */ 1, /* 14 */
0, /* 15 */ 4, /* 16 */ 0, /* 17 */ 1, /* 18 */ 0, /* 19 */
2, /* 20 */ 0, /* 21 */ 1, /* 22 */ 0, /* 23 */ 3, /* 24 */
0, /* 25 */ 1, /* 26 */ 0, /* 27 */ 2, /* 28 */ 0, /* 29 */
1, /* 30 */ 0, /* 31 */ 5, /* 32 */ 0, /* 33 */ 1, /* 34 */
0, /* 35 */ 2, /* 36 */ 0, /* 37 */ 1, /* 38 */ 0, /* 39 */
3, /* 40 */ 0, /* 41 */ 1, /* 42 */ 0, /* 43 */ 2, /* 44 */
0, /* 45 */ 1, /* 46 */ 0, /* 47 */ 4, /* 48 */ 0, /* 49 */
1, /* 50 */ 0, /* 51 */ 2, /* 52 */ 0, /* 53 */ 1, /* 54 */
0, /* 55 */ 3, /* 56 */ 0, /* 57 */ 1, /* 58 */ 0, /* 59 */
2, /* 60 */ 0, /* 61 */ 1, /* 62 */ 0, /* 63 */ 6, /* 64 */
0, /* 65 */ 1, /* 66 */ 0, /* 67 */ 2, /* 68 */ 0, /* 69 */
1, /* 70 */ 0, /* 71 */ 3, /* 72 */ 0, /* 73 */ 1, /* 74 */
0, /* 75 */ 2, /* 76 */ 0, /* 77 */ 1, /* 78 */ 0, /* 79 */
4, /* 80 */ 0, /* 81 */ 1, /* 82 */ 0, /* 83 */ 2, /* 84 */
0, /* 85 */ 1, /* 86 */ 0, /* 87 */ 3, /* 88 */ 0, /* 89 */
1, /* 90 */ 0, /* 91 */ 2, /* 92 */ 0, /* 93 */ 1, /* 94 */
0, /* 95 */ 5, /* 96 */ 0, /* 97 */ 1, /* 98 */ 0, /* 99 */
2, /* 100 */ 0, /* 101 */ 1, /* 102 */ 0, /* 103 */ 3, /* 104 */
0, /* 105 */ 1, /* 106 */ 0, /* 107 */ 2, /* 108 */ 0, /* 109 */
1, /* 110 */ 0, /* 111 */ 4, /* 112 */ 0, /* 113 */ 1, /* 114 */
0, /* 115 */ 2, /* 116 */ 0, /* 117 */ 1, /* 118 */ 0, /* 119 */
3, /* 120 */ 0, /* 121 */ 1, /* 122 */ 0, /* 123 */ 2, /* 124 */
0, /* 125 */ 1, /* 126 */ 0, /* 127 */ 7, /* 128 */ 0, /* 129 */
1, /* 130 */ 0, /* 131 */ 2, /* 132 */ 0, /* 133 */ 1, /* 134 */
0, /* 135 */ 3, /* 136 */ 0, /* 137 */ 1, /* 138 */ 0, /* 139 */
2, /* 140 */ 0, /* 141 */ 1, /* 142 */ 0, /* 143 */ 4, /* 144 */
0, /* 145 */ 1, /* 146 */ 0, /* 147 */ 2, /* 148 */ 0, /* 149 */
1, /* 150 */ 0, /* 151 */ 3, /* 152 */ 0, /* 153 */ 1, /* 154 */
0, /* 155 */ 2, /* 156 */ 0, /* 157 */ 1, /* 158 */ 0, /* 159 */
5, /* 160 */ 0, /* 161 */ 1, /* 162 */ 0, /* 163 */ 2, /* 164 */
0, /* 165 */ 1, /* 166 */ 0, /* 167 */ 3, /* 168 */ 0, /* 169 */
1, /* 170 */ 0, /* 171 */ 2, /* 172 */ 0, /* 173 */ 1, /* 174 */
0, /* 175 */ 4, /* 176 */ 0, /* 177 */ 1, /* 178 */ 0, /* 179 */
2, /* 180 */ 0, /* 181 */ 1, /* 182 */ 0, /* 183 */ 3, /* 184 */
0, /* 185 */ 1, /* 186 */ 0, /* 187 */ 2, /* 188 */ 0, /* 189 */
1, /* 190 */ 0, /* 191 */ 6, /* 192 */ 0, /* 193 */ 1, /* 194 */
0, /* 195 */ 2, /* 196 */ 0, /* 197 */ 1, /* 198 */ 0, /* 199 */
3, /* 200 */ 0, /* 201 */ 1, /* 202 */ 0, /* 203 */ 2, /* 204 */
0, /* 205 */ 1, /* 206 */ 0, /* 207 */ 4, /* 208 */ 0, /* 209 */
1, /* 210 */ 0, /* 211 */ 2, /* 212 */ 0, /* 213 */ 1, /* 214 */
0, /* 215 */ 3, /* 216 */ 0, /* 217 */ 1, /* 218 */ 0, /* 219 */
2, /* 220 */ 0, /* 221 */ 1, /* 222 */ 0, /* 223 */ 5, /* 224 */
0, /* 225 */ 1, /* 226 */ 0, /* 227 */ 2, /* 228 */ 0, /* 229 */
1, /* 230 */ 0, /* 231 */ 3, /* 232 */ 0, /* 233 */ 1, /* 234 */
0, /* 235 */ 2, /* 236 */ 0, /* 237 */ 1, /* 238 */ 0, /* 239 */
4, /* 240 */ 0, /* 241 */ 1, /* 242 */ 0, /* 243 */ 2, /* 244 */
0, /* 245 */ 1, /* 246 */ 0, /* 247 */ 3, /* 248 */ 0, /* 249 */
1, /* 250 */ 0, /* 251 */ 2, /* 252 */ 0, /* 253 */ 1, /* 254 */
0, /* 255 */
}; // end _First_one
} // namespace detail
} // namespace boost

View File

@@ -1,104 +0,0 @@
//=======================================================================
// Copyright 2002 Indiana University.
// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek
//
// This file is part of the Boost Graph Library
//
// You should have received a copy of the License Agreement for the
// Boost Graph Library along with the software; see the file LICENSE.
//
// Permission to modify the code and to distribute modified code is
// granted, provided the text of this NOTICE is retained, a notice that
// the code was modified is included with the above COPYRIGHT NOTICE and
// with the COPYRIGHT NOTICE in the LICENSE file, and that the LICENSE
// file is distributed with the modified code.
//
// LICENSOR MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED.
// By way of example, but not limitation, Licensor MAKES NO
// REPRESENTATIONS OR WARRANTIES OF MERCHANTABILITY OR FITNESS FOR ANY
// PARTICULAR PURPOSE OR THAT THE USE OF THE LICENSED SOFTWARE COMPONENTS
// OR DOCUMENTATION WILL NOT INFRINGE ANY PATENTS, COPYRIGHTS, TRADEMARKS
// OR OTHER RIGHTS.
//=======================================================================
#ifndef BOOST_BITSET_ADAPTOR_HPP
#define BOOST_BITSET_ADAPTOR_HPP
template <class T, class Derived>
struct bitset_adaptor {
Derived& derived() { return static_cast<Derived&>(*this); }
const Derived& derived() const {
return static_cast<const Derived&>(*this);
}
};
template <class T, class D, class V>
bool set_contains(const bitset_adaptor<T,D>& s, const V& x) {
return s.derived().test(x);
}
template <class T, class D>
bool set_equal(const bitset_adaptor<T,D>& x,
const bitset_adaptor<T,D>& y) {
return x.derived() == y.derived();
}
template <class T, class D>
int set_lex_order(const bitset_adaptor<T,D>& x,
const bitset_adaptor<T,D>& y) {
return compare_3way(x.derived(), y.derived());
}
template <class T, class D>
void set_clear(bitset_adaptor<T,D>& x) {
x.derived().reset();
}
template <class T, class D>
bool set_empty(const bitset_adaptor<T,D>& x) {
return x.derived().none();
}
template <class T, class D, class V>
void set_insert(bitset_adaptor<T,D>& x, const V& a) {
x.derived().set(a);
}
template <class T, class D, class V>
void set_remove(bitset_adaptor<T,D>& x, const V& a) {
x.derived().set(a, false);
}
template <class T, class D>
void set_intersect(const bitset_adaptor<T,D>& x,
const bitset_adaptor<T,D>& y,
bitset_adaptor<T,D>& z)
{
z.derived() = x.derived() & y.derived();
}
template <class T, class D>
void set_union(const bitset_adaptor<T,D>& x,
const bitset_adaptor<T,D>& y,
bitset_adaptor<T,D>& z)
{
z.derived() = x.derived() | y.derived();
}
template <class T, class D>
void set_difference(const bitset_adaptor<T,D>& x,
const bitset_adaptor<T,D>& y,
bitset_adaptor<T,D>& z)
{
z.derived() = x.derived() - y.derived();
}
template <class T, class D>
void set_compliment(const bitset_adaptor<T,D>& x,
bitset_adaptor<T,D>& z)
{
z.derived() = x.derived();
z.derived().flip();
}
#endif // BOOST_BITSET_ADAPTOR_HPP

View File

@@ -1,224 +0,0 @@
//=======================================================================
// Copyright 1997, 1998, 1999, 2000 University of Notre Dame.
// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek
//
// This file is part of the Boost Graph Library
//
// You should have received a copy of the License Agreement for the
// Boost Graph Library along with the software; see the file LICENSE.
// If not, contact Office of Research, University of Notre Dame, Notre
// Dame, IN 46556.
//
// Permission to modify the code and to distribute modified code is
// granted, provided the text of this NOTICE is retained, a notice that
// the code was modified is included with the above COPYRIGHT NOTICE and
// with the COPYRIGHT NOTICE in the LICENSE file, and that the LICENSE
// file is distributed with the modified code.
//
// LICENSOR MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED.
// By way of example, but not limitation, Licensor MAKES NO
// REPRESENTATIONS OR WARRANTIES OF MERCHANTABILITY OR FITNESS FOR ANY
// PARTICULAR PURPOSE OR THAT THE USE OF THE LICENSED SOFTWARE COMPONENTS
// OR DOCUMENTATION WILL NOT INFRINGE ANY PATENTS, COPYRIGHTS, TRADEMARKS
// OR OTHER RIGHTS.
//=======================================================================
#ifndef BOOST_GRAPH_DETAIL_CONNECTED_COMPONENTS_HPP
#define BOOST_GRAPH_DETAIL_CONNECTED_COMPONENTS_HPP
#if defined(__sgi) && !defined(__GNUC__)
#pragma set woff 1234
#endif
#include <boost/operators.hpp>
namespace boost {
namespace detail {
//=========================================================================
// Implementation details of connected_components
// This is used both in the connected_components algorithm and in
// the kosaraju strong components algorithm during the second DFS
// traversal.
template <class ComponentsPA, class DFSVisitor>
class components_recorder : public DFSVisitor
{
typedef typename property_traits<ComponentsPA>::value_type comp_type;
public:
components_recorder(ComponentsPA c,
comp_type& c_count,
DFSVisitor v)
: DFSVisitor(v), m_component(c), m_count(c_count) {}
template <class Vertex, class Graph>
void start_vertex(Vertex u, Graph& g) {
++m_count;
DFSVisitor::start_vertex(u, g);
}
template <class Vertex, class Graph>
void discover_vertex(Vertex u, Graph& g) {
put(m_component, u, m_count);
DFSVisitor::discover_vertex(u, g);
}
protected:
ComponentsPA m_component;
comp_type& m_count;
};
template <class DiscoverTimeMap, class FinishTimeMap, class TimeT,
class DFSVisitor>
class time_recorder : public DFSVisitor
{
public:
time_recorder(DiscoverTimeMap d, FinishTimeMap f, TimeT& t, DFSVisitor v)
: DFSVisitor(v), m_discover_time(d), m_finish_time(f), m_t(t) {}
template <class Vertex, class Graph>
void discover_vertex(Vertex u, Graph& g) {
put(m_discover_time, u, ++m_t);
DFSVisitor::discover_vertex(u, g);
}
template <class Vertex, class Graph>
void finish_vertex(Vertex u, Graph& g) {
put(m_finish_time, u, ++m_t);
DFSVisitor::discover_vertex(u, g);
}
protected:
DiscoverTimeMap m_discover_time;
FinishTimeMap m_finish_time;
TimeT m_t;
};
template <class DiscoverTimeMap, class FinishTimeMap, class TimeT,
class DFSVisitor>
time_recorder<DiscoverTimeMap, FinishTimeMap, TimeT, DFSVisitor>
record_times(DiscoverTimeMap d, FinishTimeMap f, TimeT& t, DFSVisitor vis)
{
return time_recorder<DiscoverTimeMap, FinishTimeMap, TimeT, DFSVisitor>
(d, f, t, vis);
}
//=========================================================================
// Implementation detail of dynamic_components
//-------------------------------------------------------------------------
// Helper functions for the component_index class
// Record the representative vertices in the header array.
// Representative vertices now point to the component number.
template <class Parent, class OutputIterator, class Integer>
inline void
build_components_header(Parent p,
OutputIterator header,
Integer num_nodes)
{
Parent component = p;
Integer component_num = 0;
for (Integer v = 0; v != num_nodes; ++v)
if (p[v] == v) {
*header++ = v;
component[v] = component_num++;
}
}
// Pushes x onto the front of the list. The list is represented in
// an array.
template <class Next, class T, class V>
inline void push_front(Next next, T& head, V x)
{
T tmp = head;
head = x;
next[x] = tmp;
}
// Create a linked list of the vertices in each component
// by reusing the representative array.
template <class Parent1, class Parent2,
class Integer>
void
link_components(Parent1 component, Parent2 header,
Integer num_nodes, Integer num_components)
{
// Make the non-representative vertices point to their component
Parent1 representative = component;
for (Integer v = 0; v != num_nodes; ++v)
if (component[v] >= num_components || header[component[v]] != v)
component[v] = component[representative[v]];
// initialize the "head" of the lists to "NULL"
std::fill_n(header, num_components, num_nodes);
// Add each vertex to the linked list for its component
Parent1 next = component;
for (Integer k = 0; k != num_nodes; ++k)
push_front(next, header[component[k]], k);
}
template <class IndexContainer, class HeaderContainer>
void
construct_component_index(IndexContainer& index, HeaderContainer& header)
{
build_components_header(index.begin(),
std::back_inserter(header),
index.end() - index.begin());
link_components(index.begin(), header.begin(),
index.end() - index.begin(),
header.end() - header.begin());
}
template <class IndexIterator, class Integer, class Distance>
class component_iterator
: boost::forward_iterator_helper<
component_iterator<IndexIterator,Integer,Distance>,
Integer, Distance,Integer*, Integer&>
{
public:
typedef component_iterator self;
IndexIterator next;
Integer node;
typedef std::forward_iterator_tag iterator_category;
typedef Integer value_type;
typedef Integer& reference;
typedef Integer* pointer;
typedef Distance difference_type;
component_iterator() {}
component_iterator(IndexIterator x, Integer i)
: next(x), node(i) {}
Integer operator*() const {
return node;
}
self& operator++() {
node = next[node];
return *this;
}
};
template <class IndexIterator, class Integer, class Distance>
inline bool
operator==(const component_iterator<IndexIterator, Integer, Distance>& x,
const component_iterator<IndexIterator, Integer, Distance>& y)
{
return x.node == y.node;
}
} // namespace detail
} // namespace detail
#if defined(__sgi) && !defined(__GNUC__)
#pragma reset woff 1234
#endif
#endif

View File

@@ -1,110 +0,0 @@
//
//=======================================================================
// Copyright 1997, 1998, 1999, 2000 University of Notre Dame.
// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek
//
// This file is part of the Boost Graph Library
//
// You should have received a copy of the License Agreement for the
// Boost Graph Library along with the software; see the file LICENSE.
// If not, contact Office of Research, University of Notre Dame, Notre
// Dame, IN 46556.
//
// Permission to modify the code and to distribute modified code is
// granted, provided the text of this NOTICE is retained, a notice that
// the code was modified is included with the above COPYRIGHT NOTICE and
// with the COPYRIGHT NOTICE in the LICENSE file, and that the LICENSE
// file is distributed with the modified code.
//
// LICENSOR MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED.
// By way of example, but not limitation, Licensor MAKES NO
// REPRESENTATIONS OR WARRANTIES OF MERCHANTABILITY OR FITNESS FOR ANY
// PARTICULAR PURPOSE OR THAT THE USE OF THE LICENSED SOFTWARE COMPONENTS
// OR DOCUMENTATION WILL NOT INFRINGE ANY PATENTS, COPYRIGHTS, TRADEMARKS
// OR OTHER RIGHTS.
//=======================================================================
#ifndef BOOST_GRAPH_DETAIL_EDGE_HPP
#define BOOST_GRAPH_DETAIL_EDGE_HPP
#if __GNUC__ < 3
#include <iostream>
#else
#include <iosfwd>
#endif
namespace boost {
namespace detail {
template <typename Directed, typename Vertex>
struct edge_base
{
inline edge_base() {}
inline edge_base(Vertex s, Vertex d)
: m_source(s), m_target(d) { }
Vertex m_source;
Vertex m_target;
};
template <typename Directed, typename Vertex>
class edge_desc_impl : public edge_base<Directed,Vertex> {
typedef edge_desc_impl self;
typedef edge_base<Directed,Vertex> Base;
public:
typedef void property_type;
inline edge_desc_impl() : m_eproperty(0) {}
inline edge_desc_impl(Vertex s, Vertex d, const property_type* eplug)
: Base(s,d), m_eproperty(const_cast<property_type*>(eplug)) { }
property_type* get_property() { return m_eproperty; }
const property_type* get_property() const { return m_eproperty; }
// protected:
property_type* m_eproperty;
};
template <class D, class V>
inline bool
operator==(const detail::edge_desc_impl<D,V>& a,
const detail::edge_desc_impl<D,V>& b)
{
return a.get_property() == b.get_property();
}
template <class D, class V>
inline bool
operator!=(const detail::edge_desc_impl<D,V>& a,
const detail::edge_desc_impl<D,V>& b)
{
return ! (a.get_property() == b.get_property());
}
} //namespace detail
} // namespace boost
namespace std {
#if __GNUC__ < 3
template <class D, class V>
std::ostream&
operator<<(std::ostream& os, const boost::detail::edge_desc_impl<D,V>& e)
{
return os << "(" << e.m_source << "," << e.m_target << ")";
}
#else
template <class Char, class Traits, class D, class V>
std::basic_ostream<Char, Traits>&
operator<<(std::basic_ostream<Char, Traits>& os,
const boost::detail::edge_desc_impl<D,V>& e)
{
return os << "(" << e.m_source << "," << e.m_target << ")";
}
#endif
}
#endif // BOOST_GRAPH_DETAIL_DETAIL_EDGE_HPP

View File

@@ -1,95 +0,0 @@
//
//=======================================================================
// Copyright 1997, 1998, 1999, 2000 University of Notre Dame.
// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek
//
// This file is part of the Boost Graph Library
//
// You should have received a copy of the License Agreement for the
// Boost Graph Library along with the software; see the file LICENSE.
// If not, contact Office of Research, University of Notre Dame, Notre
// Dame, IN 46556.
//
// Permission to modify the code and to distribute modified code is
// granted, provided the text of this NOTICE is retained, a notice that
// the code was modified is included with the above COPYRIGHT NOTICE and
// with the COPYRIGHT NOTICE in the LICENSE file, and that the LICENSE
// file is distributed with the modified code.
//
// LICENSOR MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED.
// By way of example, but not limitation, Licensor MAKES NO
// REPRESENTATIONS OR WARRANTIES OF MERCHANTABILITY OR FITNESS FOR ANY
// PARTICULAR PURPOSE OR THAT THE USE OF THE LICENSED SOFTWARE COMPONENTS
// OR DOCUMENTATION WILL NOT INFRINGE ANY PATENTS, COPYRIGHTS, TRADEMARKS
// OR OTHER RIGHTS.
//=======================================================================
//
#ifndef BOOST_GRAPH_DETAIL_INCIDENCE_ITERATOR_HPP
#define BOOST_GRAPH_DETAIL_INCIDENCE_ITERATOR_HPP
#include <utility>
#include <iterator>
// OBSOLETE
namespace boost {
namespace detail {
// EdgeDir tags
struct in_edge_tag { };
struct out_edge_tag { };
template <class Vertex, class Edge, class Iterator1D, class EdgeDir>
struct bidir_incidence_iterator {
typedef bidir_incidence_iterator self;
typedef Edge edge_type;
typedef typename Edge::property_type EdgeProperty;
public:
typedef int difference_type;
typedef std::forward_iterator_tag iterator_category;
typedef edge_type reference;
typedef edge_type value_type;
typedef value_type* pointer;
inline bidir_incidence_iterator() {}
inline bidir_incidence_iterator(Iterator1D ii, Vertex src)
: i(ii), _src(src) { }
inline self& operator++() { ++i; return *this; }
inline self operator++(int) { self tmp = *this; ++(*this); return tmp; }
inline reference operator*() const {
return deref_helper(EdgeDir());
}
inline self* operator->() { return this; }
Iterator1D& iter() { return i; }
const Iterator1D& iter() const { return i; }
Iterator1D i;
Vertex _src;
protected:
inline reference deref_helper(out_edge_tag) const {
return edge_type( _src, (*i).get_target(), &(*i).get_property() );
}
inline reference deref_helper(in_edge_tag) const {
return edge_type((*i).get_target(), _src, &(*i).get_property() );
}
};
template <class V, class E, class Iter, class Dir>
inline bool operator==(const bidir_incidence_iterator<V,E,Iter,Dir>& x,
const bidir_incidence_iterator<V,E,Iter,Dir>& y)
{
return x.i == y.i;
}
template <class V, class E, class Iter, class Dir>
inline bool operator!=(const bidir_incidence_iterator<V,E,Iter,Dir>& x,
const bidir_incidence_iterator<V,E,Iter,Dir>& y)
{
return x.i != y.i;
}
}
}
#endif

View File

@@ -1,154 +0,0 @@
//=======================================================================
// Copyright 2002 Indiana University.
// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek
//
// This file is part of the Boost Graph Library
//
// You should have received a copy of the License Agreement for the
// Boost Graph Library along with the software; see the file LICENSE.
//
// Permission to modify the code and to distribute modified code is
// granted, provided the text of this NOTICE is retained, a notice that
// the code was modified is included with the above COPYRIGHT NOTICE and
// with the COPYRIGHT NOTICE in the LICENSE file, and that the LICENSE
// file is distributed with the modified code.
//
// LICENSOR MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED.
// By way of example, but not limitation, Licensor MAKES NO
// REPRESENTATIONS OR WARRANTIES OF MERCHANTABILITY OR FITNESS FOR ANY
// PARTICULAR PURPOSE OR THAT THE USE OF THE LICENSED SOFTWARE COMPONENTS
// OR DOCUMENTATION WILL NOT INFRINGE ANY PATENTS, COPYRIGHTS, TRADEMARKS
// OR OTHER RIGHTS.
//=======================================================================
#ifndef BOOST_GRAPH_DETAIL_INCREMENTAL_COMPONENTS_HPP
#define BOOST_GRAPH_DETAIL_INCREMENTAL_COMPONENTS_HPP
#include <boost/operators.hpp>
namespace boost {
namespace detail {
//=========================================================================
// Implementation detail of incremental_components
//-------------------------------------------------------------------------
// Helper functions for the component_index class
// Record the representative vertices in the header array.
// Representative vertices now point to the component number.
template <class Parent, class OutputIterator, class Integer>
inline void
build_components_header(Parent p,
OutputIterator header,
Integer num_nodes)
{
Parent component = p;
Integer component_num = 0;
for (Integer v = 0; v != num_nodes; ++v)
if (p[v] == v) {
*header++ = v;
component[v] = component_num++;
}
}
// Pushes x onto the front of the list. The list is represented in
// an array.
template <class Next, class T, class V>
inline void array_push_front(Next next, T& head, V x)
{
T tmp = head;
head = x;
next[x] = tmp;
}
// Create a linked list of the vertices in each component
// by reusing the representative array.
template <class Parent1, class Parent2,
class Integer>
void
link_components(Parent1 component, Parent2 header,
Integer num_nodes, Integer num_components)
{
// Make the non-representative vertices point to their component
Parent1 representative = component;
for (Integer v = 0; v != num_nodes; ++v)
if (component[v] >= num_components
|| header[component[v]] != v)
component[v] = component[representative[v]];
// initialize the "head" of the lists to "NULL"
std::fill_n(header, num_components, num_nodes);
// Add each vertex to the linked list for its component
Parent1 next = component;
for (Integer k = 0; k != num_nodes; ++k)
array_push_front(next, header[component[k]], k);
}
template <class IndexContainer, class HeaderContainer>
void
construct_component_index(IndexContainer& index, HeaderContainer& header)
{
typedef typename IndexContainer::value_type Integer;
build_components_header(index.begin(),
std::back_inserter(header),
Integer(index.end() - index.begin()));
link_components(index.begin(), header.begin(),
Integer(index.end() - index.begin()),
Integer(header.end() - header.begin()));
}
template <class IndexIterator, class Integer, class Distance>
class component_iterator
: boost::forward_iterator_helper<
component_iterator<IndexIterator,Integer,Distance>,
Integer, Distance,Integer*, Integer&>
{
public:
typedef component_iterator self;
IndexIterator next;
Integer node;
typedef std::forward_iterator_tag iterator_category;
typedef Integer value_type;
typedef Integer& reference;
typedef Integer* pointer;
typedef Distance difference_type;
component_iterator() {}
component_iterator(IndexIterator x, Integer i)
: next(x), node(i) {}
Integer operator*() const {
return node;
}
self& operator++() {
node = next[node];
return *this;
}
};
template <class IndexIterator, class Integer, class Distance>
inline bool
operator==(const component_iterator<IndexIterator, Integer, Distance>& x,
const component_iterator<IndexIterator, Integer, Distance>& y)
{
return x.node == y.node;
}
} // namespace detail
} // namespace detail
#endif // BOOST_GRAPH_DETAIL_INCREMENTAL_COMPONENTS_HPP

View File

@@ -1,56 +0,0 @@
//=======================================================================
// Copyright 1997, 1998, 1999, 2000 University of Notre Dame.
// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek
//
// This file is part of the Boost Graph Library
//
// You should have received a copy of the License Agreement for the
// Boost Graph Library along with the software; see the file LICENSE.
// If not, contact Office of Research, University of Notre Dame, Notre
// Dame, IN 46556.
//
// Permission to modify the code and to distribute modified code is
// granted, provided the text of this NOTICE is retained, a notice that
// the code was modified is included with the above COPYRIGHT NOTICE and
// with the COPYRIGHT NOTICE in the LICENSE file, and that the LICENSE
// file is distributed with the modified code.
//
// LICENSOR MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED.
// By way of example, but not limitation, Licensor MAKES NO
// REPRESENTATIONS OR WARRANTIES OF MERCHANTABILITY OR FITNESS FOR ANY
// PARTICULAR PURPOSE OR THAT THE USE OF THE LICENSED SOFTWARE COMPONENTS
// OR DOCUMENTATION WILL NOT INFRINGE ANY PATENTS, COPYRIGHTS, TRADEMARKS
// OR OTHER RIGHTS.
//=======================================================================
#ifndef BOOST_GRAPH_DETAIL_IS_SAME_HPP
#define BOOST_GRAPH_DETAIL_IS_SAME_HPP
#include <boost/pending/ct_if.hpp>
namespace boost {
struct false_tag;
struct true_tag;
namespace graph_detail {
#if !defined BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
template <class U, class V>
struct is_same {
typedef boost::false_tag is_same_tag;
};
template <class U>
struct is_same<U, U> {
typedef boost::true_tag is_same_tag;
};
#else
template <class U, class V>
struct is_same {
enum { Unum = U::num, Vnum = V::num };
typedef typename boost::ct_if< (Unum == Vnum),
boost::true_tag, boost::false_tag>::type is_same_tag;
};
#endif
} // namespace graph_detail
} // namespace boost
#endif

View File

@@ -1,234 +0,0 @@
//=======================================================================
// Copyright 2002 Indiana University.
// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek
//
// This file is part of the Boost Graph Library
//
// You should have received a copy of the License Agreement for the
// Boost Graph Library along with the software; see the file LICENSE.
//
// Permission to modify the code and to distribute modified code is
// granted, provided the text of this NOTICE is retained, a notice that
// the code was modified is included with the above COPYRIGHT NOTICE and
// with the COPYRIGHT NOTICE in the LICENSE file, and that the LICENSE
// file is distributed with the modified code.
//
// LICENSOR MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED.
// By way of example, but not limitation, Licensor MAKES NO
// REPRESENTATIONS OR WARRANTIES OF MERCHANTABILITY OR FITNESS FOR ANY
// PARTICULAR PURPOSE OR THAT THE USE OF THE LICENSED SOFTWARE COMPONENTS
// OR DOCUMENTATION WILL NOT INFRINGE ANY PATENTS, COPYRIGHTS, TRADEMARKS
// OR OTHER RIGHTS.
//=======================================================================
#ifndef BOOST_LIST_BASE_HPP
#define BOOST_LIST_BASE_HPP
#include <boost/iterator_adaptors.hpp>
// Perhaps this should go through formal review, and move to <boost/>.
/*
An alternate interface idea:
Extend the std::list functionality by creating remove/insert
functions that do not require the container object!
*/
namespace boost {
namespace detail {
//=========================================================================
// Linked-List Generic Implementation Functions
template <class Node, class Next>
inline Node
slist_insert_after(Node pos, Node x,
Next next)
{
next(x) = next(pos);
next(pos) = x;
return x;
}
// return next(pos) or next(next(pos)) ?
template <class Node, class Next>
inline Node
slist_remove_after(Node pos,
Next next)
{
Node n = next(pos);
next(pos) = next(n);
return n;
}
template <class Node, class Next>
inline Node
slist_remove_range(Node before_first, Node last,
Next next)
{
next(before_first) = last;
return last;
}
template <class Node, class Next>
inline Node
slist_previous(Node head, Node x, Node nil,
Next next)
{
while (head != nil && next(head) != x)
head = next(head);
return head;
}
template<class Node, class Next>
inline void
slist_splice_after(Node pos, Node before_first, Node before_last,
Next next)
{
if (pos != before_first && pos != before_last) {
Node first = next(before_first);
Node after = next(pos);
next(before_first) = next(before_last);
next(pos) = first;
next(before_last) = after;
}
}
template <class Node, class Next>
inline Node
slist_reverse(Node node, Node nil,
Next next)
{
Node result = node;
node = next(node);
next(result) = nil;
while(node) {
Node next = next(node);
next(node) = result;
result = node;
node = next;
}
return result;
}
template <class Node, class Next>
inline std::size_t
slist_size(Node head, Node nil,
Next next)
{
std::size_t s = 0;
for ( ; head != nil; head = next(head))
++s;
return s;
}
template <class Next, class Data>
class slist_iterator_policies
{
public:
explicit slist_iterator_policies(const Next& n, const Data& d)
: m_next(n), m_data(d) { }
template <class Reference, class Node>
Reference dereference(type<Reference>, const Node& x) const
{ return m_data(x); }
template <class Node>
void increment(Node& x) const
{ x = m_next(x); }
template <class Node>
bool equal(Node& x, Node& y) const
{ return x == y; }
protected:
Next m_next;
Data m_data;
};
//===========================================================================
// Doubly-Linked List Generic Implementation Functions
template <class Node, class Next, class Prev>
inline void
dlist_insert_before(Node pos, Node x,
Next next, Prev prev)
{
next(x) = pos;
prev(x) = prev(pos);
next(prev(pos)) = x;
prev(pos) = x;
}
template <class Node, class Next, class Prev>
void
dlist_remove(Node pos,
Next next, Prev prev)
{
Node next_node = next(pos);
Node prev_node = prev(pos);
next(prev_node) = next_node;
prev(next_node) = prev_node;
}
// This deletes every node in the list except the
// sentinel node.
template <class Node, class Delete>
inline void
dlist_clear(Node sentinel, Delete del)
{
Node i, tmp;
i = next(sentinel);
while (i != sentinel) {
tmp = i;
i = next(i);
del(tmp);
}
}
template <class Node>
inline bool
dlist_empty(Node dummy)
{
return next(dummy) == dummy;
}
template <class Node, class Next, class Prev>
void
dlist_transfer(Node pos, Node first, Node last,
Next next, Prev prev)
{
if (pos != last) {
// Remove [first,last) from its old position
next(prev(last)) = pos;
next(prev(first)) = last;
next(prev(pos)) = first;
// Splice [first,last) into its new position
Node tmp = prev(pos);
prev(pos) = prev(last);
prev(last) = prev(first);
prev(first) = tmp;
}
}
template <class Next, class Prev, class Data>
class dlist_iterator_policies
: public slist_iterator_policies<Next, Data>
{
typedef slist_iterator_policies<Next, Data> Base;
public:
template <class Node>
void decrement(Node& x) const
{ x = m_prev(x); }
dlist_iterator_policies(Next n, Prev p, Data d)
: Base(n,d), m_prev(p) { }
protected:
Prev m_prev;
};
} // namespace detail
} // namespace boost
#endif // BOOST_LIST_BASE_HPP

View File

@@ -1,205 +0,0 @@
// (C) Copyright Jeremy Siek 2001.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_PERMUTATION_HPP
#define BOOST_PERMUTATION_HPP
#include <vector>
#include <memory>
#include <functional>
#include <algorithm>
#include <boost/graph/detail/shadow_iterator.hpp>
namespace boost {
template <class Iter1, class Iter2>
void permute_serial(Iter1 permuter, Iter1 last, Iter2 result)
{
#ifdef BOOST_NO_STD_ITERATOR_TRAITS
typedef std::ptrdiff_t D:
#else
typedef typename std::iterator_traits<Iter1>::difference_type D;
#endif
D n = 0;
while (permuter != last) {
std::swap(result[n], result[*permuter]);
++n;
++permuter;
}
}
template <class InIter, class RandIterP, class RandIterR>
void permute_copy(InIter first, InIter last, RandIterP p, RandIterR result)
{
#ifdef BOOST_NO_STD_ITERATOR_TRAITS
typedef std::ptrdiff_t i = 0;
#else
typename std::iterator_traits<RandIterP>::difference_type i = 0;
#endif
for (; first != last; ++first, ++i)
result[p[i]] = *first;
}
namespace detail {
template <class RandIter, class RandIterPerm, class D, class T>
void permute_helper(RandIter first, RandIter last, RandIterPerm p, D, T)
{
D i = 0, pi, n = last - first, cycle_start;
T tmp;
std::vector<int> visited(n, false);
while (i != n) { // continue until all elements have been processed
cycle_start = i;
tmp = first[i];
do { // walk around a cycle
pi = p[i];
visited[pi] = true;
std::swap(tmp, first[pi]);
i = pi;
} while (i != cycle_start);
// find the next cycle
for (i = 0; i < n; ++i)
if (visited[i] == false)
break;
}
}
} // namespace detail
template <class RandIter, class RandIterPerm>
void permute(RandIter first, RandIter last, RandIterPerm p)
{
detail::permute_helper(first, last, p, last - first, *first);
}
// Knuth 1.3.3, Vol. 1 p 176
// modified for zero-based arrays
// time complexity?
//
// WARNING: T must be a signed integer!
template <class PermIter>
void invert_permutation(PermIter X, PermIter Xend)
{
#ifdef BOOST_NO_STD_ITERATOR_TRAITS
typedef std::ptrdiff_t T:
#else
typedef typename std::iterator_traits<PermIter>::value_type T;
#endif
T n = Xend - X;
T m = n;
T j = -1;
while (m > 0) {
T i = X[m-1] + 1;
if (i > 0) {
do {
X[m-1] = j - 1;
j = -m;
m = i;
i = X[m-1] + 1;
} while (i > 0);
i = j;
}
X[m-1] = -i - 1;
--m;
}
}
// Takes a "normal" permutation array (and its inverse), and turns it
// into a BLAS-style permutation array (which can be thought of as a
// serialized permutation).
template <class Iter1, class Iter2, class Iter3>
inline void serialize_permutation(Iter1 q, Iter1 q_end, Iter2 q_inv, Iter3 p)
{
#ifdef BOOST_NO_STD_ITERATOR_TRAITS
typedef std::ptrdiff_t P1;
typedef std::ptrdiff_t P2;
typedef std::ptrdiff_t D;
#else
typedef typename std::iterator_traits<Iter1>::value_type P1;
typedef typename std::iterator_traits<Iter2>::value_type P2;
typedef typename std::iterator_traits<Iter1>::difference_type D;
#endif
D n = q_end - q;
for (D i = 0; i < n; ++i) {
P1 qi = q[i];
P2 qii = q_inv[i];
*p++ = qii;
std::swap(q[i], q[qii]);
std::swap(q_inv[i], q_inv[qi]);
}
}
// Not used anymore, leaving it here for future reference.
template <typename Iter, typename Compare>
void merge_sort(Iter first, Iter last, Compare cmp)
{
if (first + 1 < last) {
Iter mid = first + (last - first)/2;
merge_sort(first, mid, cmp);
merge_sort(mid, last, cmp);
std::inplace_merge(first, mid, last, cmp);
}
}
// time: N log N + 3N + ?
// space: 2N
template <class Iter, class IterP, class Cmp, class Alloc>
inline void sortp(Iter first, Iter last, IterP p, Cmp cmp, Alloc alloc)
{
typedef typename std::iterator_traits<IterP>::value_type P;
typedef typename std::iterator_traits<IterP>::difference_type D;
D n = last - first;
std::vector<P, Alloc> q(n);
for (D i = 0; i < n; ++i)
q[i] = i;
std::sort(make_shadow_iter(first, q.begin()),
make_shadow_iter(last, q.end()),
shadow_cmp<Cmp>(cmp));
invert_permutation(q.begin(), q.end());
std::copy(q.begin(), q.end(), p);
}
template <class Iter, class IterP, class Cmp>
inline void sortp(Iter first, Iter last, IterP p, Cmp cmp)
{
typedef typename std::iterator_traits<IterP>::value_type P;
sortp(first, last, p, cmp, std::allocator<P>());
}
template <class Iter, class IterP>
inline void sortp(Iter first, Iter last, IterP p)
{
typedef typename std::iterator_traits<Iter>::value_type T;
typedef typename std::iterator_traits<IterP>::value_type P;
sortp(first, last, p, std::less<T>(), std::allocator<P>());
}
template <class Iter, class IterP, class Cmp, class Alloc>
inline void sortv(Iter first, Iter last, IterP p, Cmp cmp, Alloc alloc)
{
typedef typename std::iterator_traits<IterP>::value_type P;
typedef typename std::iterator_traits<IterP>::difference_type D;
D n = last - first;
std::vector<P, Alloc> q(n), q_inv(n);
for (D i = 0; i < n; ++i)
q_inv[i] = i;
std::sort(make_shadow_iter(first, q_inv.begin()),
make_shadow_iter(last, q_inv.end()),
shadow_cmp<Cmp>(cmp));
std::copy(q_inv, q_inv.end(), q.begin());
invert_permutation(q.begin(), q.end());
serialize_permutation(q.begin(), q.end(), q_inv.end(), p);
}
} // namespace boost
#endif // BOOST_PERMUTATION_HPP

View File

@@ -1,434 +0,0 @@
//=======================================================================
// Copyright 1997, 1998, 1999, 2000 University of Notre Dame.
// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek
//
// This file is part of the Boost Graph Library
//
// You should have received a copy of the License Agreement for the
// Boost Graph Library along with the software; see the file LICENSE.
// If not, contact Office of Research, University of Notre Dame, Notre
// Dame, IN 46556.
//
// Permission to modify the code and to distribute modified code is
// granted, provided the text of this NOTICE is retained, a notice that
// the code was modified is included with the above COPYRIGHT NOTICE and
// with the COPYRIGHT NOTICE in the LICENSE file, and that the LICENSE
// file is distributed with the modified code.
//
// LICENSOR MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED.
// By way of example, but not limitation, Licensor MAKES NO
// REPRESENTATIONS OR WARRANTIES OF MERCHANTABILITY OR FITNESS FOR ANY
// PARTICULAR PURPOSE OR THAT THE USE OF THE LICENSED SOFTWARE COMPONENTS
// OR DOCUMENTATION WILL NOT INFRINGE ANY PATENTS, COPYRIGHTS, TRADEMARKS
// OR OTHER RIGHTS.
//=======================================================================
#ifndef BOOST_SELF_AVOIDING_WALK_HPP
#define BOOST_SELF_AVOIDING_WALK_HPP
/*
This file defines necessary components for SAW.
mesh language: (defined by myself to clearify what is what)
A triangle in mesh is called an triangle.
An edge in mesh is called an line.
A vertex in mesh is called a point.
A triangular mesh corresponds to a graph in which a vertex is a
triangle and an edge(u, v) stands for triangle u and triangle v
share an line.
After this point, a vertex always refers to vertex in graph,
therefore it is a traingle in mesh.
*/
#include <utility>
#include <boost/config.hpp>
#include <boost/graph/graph_traits.hpp>
#include <boost/property_map.hpp>
#define SAW_SENTINAL -1
namespace boost {
template <class T1, class T2, class T3>
struct triple {
T1 first;
T2 second;
T3 third;
triple(const T1& a, const T2& b, const T3& c) : first(a), second(b), third(c) {}
triple() : first(SAW_SENTINAL), second(SAW_SENTINAL), third(SAW_SENTINAL) {}
};
typedef triple<int, int, int> Triple;
/* Define a vertex property which has a triangle inside. Triangle is
represented by a triple. */
struct triangle_tag { enum { num = 100 }; };
typedef property<triangle_tag,Triple> triangle_property;
/* Define an edge property with a line. A line is represented by a
pair. This is not required for SAW though.
*/
struct line_tag { enum { num = 101 }; };
template <class T> struct line_property
: public property<line_tag, std::pair<T,T> > { };
/*Precondition: Points in a Triangle are in order */
template <class Triangle, class Line>
inline void get_sharing(const Triangle& a, const Triangle& b, Line& l)
{
l.first = SAW_SENTINAL;
l.second = SAW_SENTINAL;
if ( a.first == b.first ) {
l.first = a.first;
if ( a.second == b.second || a.second == b.third )
l.second = a.second;
else if ( a.third == b.second || a.third == b.third )
l.second = a.third;
} else if ( a.first == b.second ) {
l.first = a.first;
if ( a.second == b.third )
l.second = a.second;
else if ( a.third == b.third )
l.second = a.third;
} else if ( a.first == b.third ) {
l.first = a.first;
} else if ( a.second == b.first ) {
l.first = a.second;
if ( a.third == b.second || a.third == b.third )
l.second = a.third;
} else if ( a.second == b.second ) {
l.first = a.second;
if ( a.third == b.third )
l.second = a.third;
} else if ( a.second == b.third ) {
l.first = a.second;
} else if ( a.third == b.first
|| a.third == b.second
|| a.third == b.third )
l.first = a.third;
/*Make it in order*/
if ( l.first > l.second ) {
typename Line::first_type i = l.first;
l.first = l.second;
l.second = i;
}
}
template <class TriangleDecorator, class Vertex, class Line>
struct get_vertex_sharing {
typedef std::pair<Vertex, Line> Pair;
get_vertex_sharing(const TriangleDecorator& _td) : td(_td) {}
inline Line operator()(const Vertex& u, const Vertex& v) const {
Line l;
get_sharing(td[u], td[v], l);
return l;
}
inline Line operator()(const Pair& u, const Vertex& v) const {
Line l;
get_sharing(td[u.first], td[v], l);
return l;
}
inline Line operator()(const Pair& u, const Pair& v) const {
Line l;
get_sharing(td[u.first], td[v.first], l);
return l;
}
TriangleDecorator td;
};
/* HList has to be a handle of data holder so that pass-by-value is
* in right logic.
*
* The element of HList is a pair of vertex and line. (remember a
* line is a pair of two ints.). That indicates the walk w from
* current vertex is across line. (If the first of line is -1, it is
* a point though.
*/
template < class TriangleDecorator, class HList, class IteratorD>
class SAW_visitor
: public bfs_visitor<>, public dfs_visitor<>
{
typedef typename boost::property_traits<IteratorD>::value_type iter;
/*use boost shared_ptr*/
typedef typename HList::element_type::value_type::second_type Line;
public:
typedef tree_edge_tag category;
inline SAW_visitor(TriangleDecorator _td, HList _hlist, IteratorD ia)
: td(_td), hlist(_hlist), iter_d(ia) {}
template <class Vertex, class Graph>
inline void start_vertex(Vertex v, Graph&) {
Line l1;
l1.first = SAW_SENTINAL;
l1.second = SAW_SENTINAL;
hlist->push_front(std::make_pair(v, l1));
iter_d[v] = hlist->begin();
}
/*Several symbols:
w(i): i-th triangle in walk w
w(i) |- w(i+1): w enter w(i+1) from w(i) over a line
w(i) ~> w(i+1): w enter w(i+1) from w(i) over a point
w(i) -> w(i+1): w enter w(i+1) from w(i)
w(i) ^ w(i+1): the line or point w go over from w(i) to w(i+1)
*/
template <class Edge, class Graph>
bool tree_edge(Edge e, Graph& G) {
using std::make_pair;
typedef typename boost::graph_traits<Graph>::vertex_descriptor Vertex;
Vertex tau = target(e, G);
Vertex i = source(e, G);
get_vertex_sharing<TriangleDecorator, Vertex, Line> get_sharing_line(td);
Line tau_i = get_sharing_line(tau, i);
iter w_end = hlist->end();
iter w_i = iter_d[i];
iter w_i_m_1 = w_i;
iter w_i_p_1 = w_i;
/*----------------------------------------------------------
* true false
*==========================================================
*a w(i-1) |- w(i) w(i-1) ~> w(i) or w(i-1) is null
*----------------------------------------------------------
*b w(i) |- w(i+1) w(i) ~> w(i+1) or no w(i+1) yet
*----------------------------------------------------------
*/
bool a = false, b = false;
--w_i_m_1;
++w_i_p_1;
b = ( w_i->second.first != SAW_SENTINAL );
if ( w_i_m_1 != w_end ) {
a = ( w_i_m_1->second.first != SAW_SENTINAL );
}
if ( a ) {
if ( b ) {
/*Case 1:
w(i-1) |- w(i) |- w(i+1)
*/
Line l1 = get_sharing_line(*w_i_m_1, tau);
iter w_i_m_2 = w_i_m_1;
--w_i_m_2;
bool c = true;
if ( w_i_m_2 != w_end ) {
c = w_i_m_2->second != l1;
}
if ( c ) { /* w(i-1) ^ tau != w(i-2) ^ w(i-1) */
/*extension: w(i-1) -> tau |- w(i) */
w_i_m_1->second = l1;
/*insert(pos, const T&) is to insert before pos*/
iter_d[tau] = hlist->insert(w_i, make_pair(tau, tau_i));
} else { /* w(i-1) ^ tau == w(i-2) ^ w(i-1) */
/*must be w(i-2) ~> w(i-1) */
bool d = true;
//need to handle the case when w_i_p_1 is null
Line l3 = get_sharing_line(*w_i_p_1, tau);
if ( w_i_p_1 != w_end )
d = w_i_p_1->second != l3;
if ( d ) { /* w(i+1) ^ tau != w(i+1) ^ w(i+2) */
/*extension: w(i) |- tau -> w(i+1) */
w_i->second = tau_i;
iter_d[tau] = hlist->insert(w_i_p_1, make_pair(tau, l3));
} else { /* w(i+1) ^ tau == w(i+1) ^ w(i+2) */
/*must be w(1+1) ~> w(i+2) */
Line l5 = get_sharing_line(*w_i_m_1, *w_i_p_1);
if ( l5 != w_i_p_1->second ) { /* w(i-1) ^ w(i+1) != w(i+1) ^ w(i+2) */
/*extension: w(i-2) -> tau |- w(i) |- w(i-1) -> w(i+1) */
w_i_m_2->second = get_sharing_line(*w_i_m_2, tau);
iter_d[tau] = hlist->insert(w_i, make_pair(tau, tau_i));
w_i->second = w_i_m_1->second;
w_i_m_1->second = l5;
iter_d[w_i_m_1->first] = hlist->insert(w_i_p_1, *w_i_m_1);
hlist->erase(w_i_m_1);
} else {
/*mesh is tetrahedral*/
// dont know what that means.
;
}
}
}
} else {
/*Case 2:
w(i-1) |- w(i) ~> w(1+1)
*/
if ( w_i->second.second == tau_i.first
|| w_i->second.second == tau_i.second ) { /*w(i) ^ w(i+1) < w(i) ^ tau*/
/*extension: w(i) |- tau -> w(i+1) */
w_i->second = tau_i;
Line l1 = get_sharing_line(*w_i_p_1, tau);
iter_d[tau] = hlist->insert(w_i_p_1, make_pair(tau, l1));
} else { /*w(i) ^ w(i+1) !< w(i) ^ tau*/
Line l1 = get_sharing_line(*w_i_m_1, tau);
bool c = true;
iter w_i_m_2 = w_i_m_1;
--w_i_m_2;
if ( w_i_m_2 != w_end )
c = l1 != w_i_m_2->second;
if (c) { /*w(i-1) ^ tau != w(i-2) ^ w(i-1)*/
/*extension: w(i-1) -> tau |- w(i)*/
w_i_m_1->second = l1;
iter_d[tau] = hlist->insert(w_i, make_pair(tau, tau_i));
} else { /*w(i-1) ^ tau == w(i-2) ^ w(i-1)*/
/*must be w(i-2)~>w(i-1)*/
/*extension: w(i-2) -> tau |- w(i) |- w(i-1) -> w(i+1)*/
w_i_m_2->second = get_sharing_line(*w_i_m_2, tau);
iter_d[tau] = hlist->insert(w_i, make_pair(tau, tau_i));
w_i->second = w_i_m_1->second;
w_i_m_1->second = get_sharing_line(*w_i_m_1, *w_i_p_1);
iter_d[w_i_m_1->first] = hlist->insert(w_i_p_1, *w_i_m_1);
hlist->erase(w_i_m_1);
}
}
}
} else {
if ( b ) {
/*Case 3:
w(i-1) ~> w(i) |- w(i+1)
*/
bool c = false;
if ( w_i_m_1 != w_end )
c = ( w_i_m_1->second.second == tau_i.first)
|| ( w_i_m_1->second.second == tau_i.second);
if ( c ) { /*w(i-1) ^ w(i) < w(i) ^ tau*/
/* extension: w(i-1) -> tau |- w(i) */
if ( w_i_m_1 != w_end )
w_i_m_1->second = get_sharing_line(*w_i_m_1, tau);
iter_d[tau] = hlist->insert(w_i, make_pair(tau, tau_i));
} else {
bool d = true;
Line l1;
l1.first = SAW_SENTINAL;
l1.second = SAW_SENTINAL;
if ( w_i_p_1 != w_end ) {
l1 = get_sharing_line(*w_i_p_1, tau);
d = l1 != w_i_p_1->second;
}
if (d) { /*w(i+1) ^ tau != w(i+1) ^ w(i+2)*/
/*extension: w(i) |- tau -> w(i+1) */
w_i->second = tau_i;
iter_d[tau] = hlist->insert(w_i_p_1, make_pair(tau, l1));
} else {
/*must be w(i+1) ~> w(i+2)*/
/*extension: w(i-1) -> w(i+1) |- w(i) |- tau -> w(i+2) */
iter w_i_p_2 = w_i_p_1;
++w_i_p_2;
w_i_p_1->second = w_i->second;
iter_d[i] = hlist->insert(w_i_p_2, make_pair(i, tau_i));
hlist->erase(w_i);
Line l2 = get_sharing_line(*w_i_p_2, tau);
iter_d[tau] = hlist->insert(w_i_p_2, make_pair(tau, l2));
}
}
} else {
/*Case 4:
w(i-1) ~> w(i) ~> w(i+1)
*/
bool c = false;
if ( w_i_m_1 != w_end ) {
c = (w_i_m_1->second.second == tau_i.first)
|| (w_i_m_1->second.second == tau_i.second);
}
if ( c ) { /*w(i-1) ^ w(i) < w(i) ^ tau */
/*extension: w(i-1) -> tau |- w(i) */
if ( w_i_m_1 != w_end )
w_i_m_1->second = get_sharing_line(*w_i_m_1, tau);
iter_d[tau] = hlist->insert(w_i, make_pair(tau, tau_i));
} else {
/*extension: w(i) |- tau -> w(i+1) */
w_i->second = tau_i;
Line l1;
l1.first = SAW_SENTINAL;
l1.second = SAW_SENTINAL;
if ( w_i_p_1 != w_end )
l1 = get_sharing_line(*w_i_p_1, tau);
iter_d[tau] = hlist->insert(w_i_p_1, make_pair(tau, l1));
}
}
}
return true;
}
protected:
TriangleDecorator td; /*a decorator for vertex*/
HList hlist;
/*This must be a handle of list to record the SAW
The element type of the list is pair<Vertex, Line>
*/
IteratorD iter_d;
/*Problem statement: Need a fast access to w for triangle i.
*Possible solution: mantain an array to record.
iter_d[i] will return an iterator
which points to w(i), where i is a vertex
representing triangle i.
*/
};
template <class Triangle, class HList, class Iterator>
inline
SAW_visitor<Triangle, HList, Iterator>
visit_SAW(Triangle t, HList hl, Iterator i) {
return SAW_visitor<Triangle, HList, Iterator>(t, hl, i);
}
template <class Tri, class HList, class Iter>
inline
SAW_visitor< random_access_iterator_property_map<Tri*,Tri,Tri&>,
HList, random_access_iterator_property_map<Iter*,Iter,Iter&> >
visit_SAW_ptr(Tri* t, HList hl, Iter* i) {
typedef random_access_iterator_property_map<Tri*,Tri,Tri&> TriD;
typedef random_access_iterator_property_map<Iter*,Iter,Iter&> IterD;
return SAW_visitor<TriD, HList, IterD>(t, hl, i);
}
// should also have combo's of pointers, and also const :(
}
#endif /*BOOST_SAW_H*/

View File

@@ -1,117 +0,0 @@
// (C) Copyright Jeremy Siek 2001.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_SET_ADAPTOR_HPP
#define BOOST_SET_ADAPTOR_HPP
#include <set>
namespace boost {
template <class K, class C, class A, class T>
bool set_contains(const std::set<K,C,A>& s, const T& x) {
return s.find(x) != s.end();
}
template <class K, class C, class A>
bool set_equal(const std::set<K,C,A>& x,
const std::set<K,C,A>& y)
{
return x == y;
}
// Not the same as lexicographical_compare_3way applied to std::set.
// this is equivalent semantically to bitset::operator<()
template <class K, class C, class A>
int set_lex_order(const std::set<K,C,A>& x,
const std::set<K,C,A>& y)
{
typename std::set<K,C,A>::iterator
xi = x.begin(), yi = y.begin(), xend = x.end(), yend = y.end();
for (; xi != xend && yi != yend; ++xi, ++yi) {
if (*xi < *yi)
return 1;
else if (*yi < *xi)
return -1;
}
if (xi == xend)
return (yi == yend) ? 0 : -1;
else
return 1;
}
template <class K, class C, class A>
void set_clear(std::set<K,C,A>& x) {
x.clear();
}
template <class K, class C, class A>
bool set_empty(const std::set<K,C,A>& x) {
return x.empty();
}
template <class K, class C, class A, class T>
void set_insert(std::set<K,C,A>& x, const T& a) {
x.insert(a);
}
template <class K, class C, class A, class T>
void set_remove(std::set<K,C,A>& x, const T& a) {
x.erase(a);
}
template <class K, class C, class A>
void set_intersect(const std::set<K,C,A>& x,
const std::set<K,C,A>& y,
std::set<K,C,A>& z)
{
z.clear();
std::set_intersection(x.begin(), x.end(),
y.begin(), y.end(),
std::inserter(z));
}
template <class K, class C, class A>
void set_union(const std::set<K,C,A>& x,
const std::set<K,C,A>& y,
std::set<K,C,A>& z)
{
z.clear();
std::set_union(x.begin(), x.end(),
y.begin(), y.end(),
std::inserter(z));
}
template <class K, class C, class A>
void set_difference(const std::set<K,C,A>& x,
const std::set<K,C,A>& y,
std::set<K,C,A>& z)
{
z.clear();
std::set_difference(x.begin(), x.end(),
y.begin(), y.end(),
std::inserter(z, z.begin()));
}
template <class K, class C, class A>
bool set_subset(const std::set<K,C,A>& x,
const std::set<K,C,A>& y)
{
return std::includes(x.begin(), x.end(), y.begin(), y.end());
}
// Shit, can't implement this without knowing the size of the
// universe.
template <class K, class C, class A>
void set_compliment(const std::set<K,C,A>& x,
std::set<K,C,A>& z)
{
z.clear();
}
} // namespace boost
#endif // BOOST_SET_ADAPTOR_HPP

View File

@@ -1,139 +0,0 @@
// (C) Copyright Jeremy Siek 2001.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_SHADOW_ITERATOR_HPP
#define BOOST_SHADOW_ITERATOR_HPP
#include <boost/iterator_adaptors.hpp>
#include <boost/operators.hpp>
namespace boost {
namespace detail {
template <class A, class B, class D>
class shadow_proxy
: boost::operators< shadow_proxy<A,B,D> >
{
typedef shadow_proxy self;
public:
inline shadow_proxy(A aa, B bb) : a(aa), b(bb) { }
inline shadow_proxy(const self& x) : a(x.a), b(x.b) { }
template <class Self>
inline shadow_proxy(Self x) : a(x.a), b(x.b) { }
inline self& operator=(const self& x) { a = x.a; b = x.b; return *this; }
inline self& operator++() { ++a; return *this; }
inline self& operator--() { --a; return *this; }
inline self& operator+=(const self& x) { a += x.a; return *this; }
inline self& operator-=(const self& x) { a -= x.a; return *this; }
inline self& operator*=(const self& x) { a *= x.a; return *this; }
inline self& operator/=(const self& x) { a /= x.a; return *this; }
inline self& operator%=(const self& x) { return *this; } // JGS
inline self& operator&=(const self& x) { return *this; } // JGS
inline self& operator|=(const self& x) { return *this; } // JGS
inline self& operator^=(const self& x) { return *this; } // JGS
inline friend D operator-(const self& x, const self& y) {
return x.a - y.a;
}
inline bool operator==(const self& x) const { return a == x.a; }
inline bool operator<(const self& x) const { return a < x.a; }
// protected:
A a;
B b;
};
struct shadow_iterator_policies
{
template <typename iter_pair>
void initialize(const iter_pair&) { }
template <typename Iter>
typename Iter::reference dereference(const Iter& i) const {
typedef typename Iter::reference R;
return R(*i.base().first, *i.base().second);
}
template <typename Iter>
bool equal(const Iter& p1, const Iter& p2) const {
return p1.base().first == p2.base().first;
}
template <typename Iter>
void increment(Iter& i) { ++i.base().first; ++i.base().second; }
template <typename Iter>
void decrement(Iter& i) { --i.base().first; --i.base().second; }
template <typename Iter>
bool less(const Iter& x, const Iter& y) const {
return x.base().first < y.base().first;
}
template <typename Iter>
typename Iter::difference_type
distance(const Iter& x, const Iter& y) const {
return y.base().first - x.base().first;
}
template <typename D, typename Iter>
void advance(Iter& p, D n) { p.base().first += n; p.base().second += n; }
};
} // namespace detail
template <typename IterA, typename IterB>
struct shadow_iterator_generator {
// To use the iterator_adaptor we can't derive from
// random_access_iterator because we don't have a real reference.
// However, we want the STL algorithms to treat the shadow
// iterator like a random access iterator.
struct shadow_iterator_tag : public std::input_iterator_tag {
operator std::random_access_iterator_tag() {
return std::random_access_iterator_tag();
};
};
typedef typename std::iterator_traits<IterA>::value_type Aval;
typedef typename std::iterator_traits<IterB>::value_type Bval;
typedef typename std::iterator_traits<IterA>::reference Aref;
typedef typename std::iterator_traits<IterB>::reference Bref;
typedef typename std::iterator_traits<IterA>::difference_type D;
typedef detail::shadow_proxy<Aval,Bval,Aval> V;
typedef detail::shadow_proxy<Aref,Bref,Aval> R;
typedef iterator_adaptor< std::pair<IterA, IterB>,
detail::shadow_iterator_policies,
V, R, V*, shadow_iterator_tag,
D> type;
};
// short cut for creating a shadow iterator
template <class IterA, class IterB>
inline typename shadow_iterator_generator<IterA,IterB>::type
make_shadow_iter(IterA a, IterB b) {
typedef typename shadow_iterator_generator<IterA,IterB>::type Iter;
return Iter(std::make_pair(a,b));
}
template <class Cmp>
struct shadow_cmp {
inline shadow_cmp(const Cmp& c) : cmp(c) { }
template <class ShadowProxy1, class ShadowProxy2>
inline bool operator()(const ShadowProxy1& x, const ShadowProxy2& y) const
{
return cmp(x.a, y.a);
}
Cmp cmp;
};
} // namespace boost
namespace std {
template <class A1, class B1, class D1,
class A2, class B2, class D2>
void swap(boost::detail::shadow_proxy<A1&,B1&,D1> x,
boost::detail::shadow_proxy<A2&,B2&,D2> y)
{
std::swap(x.a, y.a);
std::swap(x.b, y.b);
}
}
#endif // BOOST_SHADOW_ITERATOR_HPP

View File

@@ -1,293 +0,0 @@
//
//=======================================================================
// Copyright 1997, 1998, 1999, 2000 University of Notre Dame.
// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek
//
// This file is part of the Boost Graph Library
//
// You should have received a copy of the License Agreement for the
// Boost Graph Library along with the software; see the file LICENSE.
// If not, contact Office of Research, University of Notre Dame, Notre
// Dame, IN 46556.
//
// Permission to modify the code and to distribute modified code is
// granted, provided the text of this NOTICE is retained, a notice that
// the code was modified is included with the above COPYRIGHT NOTICE and
// with the COPYRIGHT NOTICE in the LICENSE file, and that the LICENSE
// file is distributed with the modified code.
//
// LICENSOR MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED.
// By way of example, but not limitation, Licensor MAKES NO
// REPRESENTATIONS OR WARRANTIES OF MERCHANTABILITY OR FITNESS FOR ANY
// PARTICULAR PURPOSE OR THAT THE USE OF THE LICENSED SOFTWARE COMPONENTS
// OR DOCUMENTATION WILL NOT INFRINGE ANY PATENTS, COPYRIGHTS, TRADEMARKS
// OR OTHER RIGHTS.
//=======================================================================
//
//
// Revision History:
// 04 April 2001: Added named parameter variant. (Jeremy Siek)
// 01 April 2001: Modified to use new <boost/limits.hpp> header. (JMaddock)
//
#ifndef BOOST_GRAPH_DIJKSTRA_HPP
#define BOOST_GRAPH_DIJKSTRA_HPP
#include <functional>
#include <boost/limits.hpp>
#include <boost/graph/named_function_params.hpp>
#include <boost/graph/breadth_first_search.hpp>
#include <boost/pending/mutable_queue.hpp>
#include <boost/graph/relax.hpp>
#include <boost/pending/indirect_cmp.hpp>
#include <boost/graph/exception.hpp>
namespace boost {
template <class Visitor, class Graph>
struct DijkstraVisitorConcept {
void constraints() {
function_requires< CopyConstructibleConcept<Visitor> >();
vis.discover_vertex(u, g);
vis.examine_vertex(u, g);
vis.examine_edge(e, g);
vis.edge_relaxed(e, g);
vis.edge_not_relaxed(e, g);
vis.finish_vertex(u, g);
}
Visitor vis;
Graph g;
typename graph_traits<Graph>::vertex_descriptor u;
typename graph_traits<Graph>::edge_descriptor e;
};
template <class Visitors = null_visitor>
class dijkstra_visitor : public bfs_visitor<Visitors> {
public:
dijkstra_visitor() { }
dijkstra_visitor(Visitors vis)
: bfs_visitor<Visitors>(vis) { }
template <class Edge, class Graph>
void edge_relaxed(Edge e, Graph& g) {
invoke_visitors(this->m_vis, e, g, on_edge_relaxed());
}
template <class Edge, class Graph>
void edge_not_relaxed(Edge e, Graph& g) {
invoke_visitors(this->m_vis, e, g, on_edge_not_relaxed());
}
private:
template <class Edge, class Graph>
void tree_edge(Edge u, Graph& g) { }
};
template <class Visitors>
dijkstra_visitor<Visitors>
make_dijkstra_visitor(Visitors vis) {
return dijkstra_visitor<Visitors>(vis);
}
typedef dijkstra_visitor<> default_dijkstra_visitor;
namespace detail {
template <class UniformCostVisitor, class UpdatableQueue,
class WeightMap, class PredecessorMap, class DistanceMap,
class BinaryFunction, class BinaryPredicate>
struct dijkstra_bfs_visitor
{
typedef typename property_traits<DistanceMap>::value_type D;
dijkstra_bfs_visitor(UniformCostVisitor vis, UpdatableQueue& Q,
WeightMap w, PredecessorMap p, DistanceMap d,
BinaryFunction combine, BinaryPredicate compare,
D zero)
: m_vis(vis), m_Q(Q), m_weight(w), m_predecessor(p), m_distance(d),
m_combine(combine), m_compare(compare), m_zero(zero) { }
template <class Edge, class Graph>
void tree_edge(Edge e, Graph& g) {
m_decreased = relax(e, g, m_weight, m_predecessor, m_distance,
m_combine, m_compare);
if (m_decreased)
m_vis.edge_relaxed(e, g);
else
m_vis.edge_not_relaxed(e, g);
}
template <class Edge, class Graph>
void gray_target(Edge e, Graph& g) {
m_decreased = relax(e, g, m_weight, m_predecessor, m_distance,
m_combine, m_compare);
if (m_decreased) {
m_Q.update(target(e, g));
m_vis.edge_relaxed(e, g);
} else
m_vis.edge_not_relaxed(e, g);
}
template <class Vertex, class Graph>
void initialize_vertex(Vertex u, Graph& g)
{ m_vis.initialize_vertex(u, g); }
template <class Edge, class Graph>
void non_tree_edge(Edge, Graph&) { }
template <class Vertex, class Graph>
void discover_vertex(Vertex u, Graph& g) { m_vis.discover_vertex(u, g); }
template <class Vertex, class Graph>
void examine_vertex(Vertex u, Graph& g) { m_vis.examine_vertex(u, g); }
template <class Edge, class Graph>
void examine_edge(Edge e, Graph& g) {
if (m_compare(get(m_weight, e), m_zero))
throw negative_edge();
m_vis.examine_edge(e, g);
}
template <class Edge, class Graph>
void black_target(Edge, Graph&) { }
template <class Vertex, class Graph>
void finish_vertex(Vertex u, Graph& g) { m_vis.finish_vertex(u, g); }
UniformCostVisitor m_vis;
UpdatableQueue& m_Q;
WeightMap m_weight;
PredecessorMap m_predecessor;
DistanceMap m_distance;
BinaryFunction m_combine;
BinaryPredicate m_compare;
bool m_decreased;
D m_zero;
};
} // namespace detail
// Initalize distances and call breadth first search
template <class VertexListGraph, class DijkstraVisitor,
class PredecessorMap, class DistanceMap,
class WeightMap, class IndexMap, class Compare, class Combine,
class DistZero>
inline void
dijkstra_shortest_paths_no_init
(const VertexListGraph& g,
typename graph_traits<VertexListGraph>::vertex_descriptor s,
PredecessorMap predecessor, DistanceMap distance, WeightMap weight,
IndexMap index_map,
Compare compare, Combine combine, DistZero zero,
DijkstraVisitor vis)
{
typedef indirect_cmp<DistanceMap, Compare> IndirectCmp;
IndirectCmp icmp(distance, compare);
typedef typename graph_traits<VertexListGraph>::vertex_descriptor Vertex;
typedef mutable_queue<Vertex, std::vector<Vertex>, IndirectCmp, IndexMap>
MutableQueue;
MutableQueue Q(num_vertices(g), icmp, index_map);
detail::dijkstra_bfs_visitor<DijkstraVisitor, MutableQueue, WeightMap,
PredecessorMap, DistanceMap, Combine, Compare>
bfs_vis(vis, Q, weight, predecessor, distance, combine, compare, zero);
std::vector<default_color_type> color(num_vertices(g));
default_color_type c = white_color;
breadth_first_visit(g, s, Q, bfs_vis,
make_iterator_property_map(&color[0], index_map, c));
}
// Initalize distances and call breadth first search
template <class VertexListGraph, class DijkstraVisitor,
class PredecessorMap, class DistanceMap,
class WeightMap, class IndexMap, class Compare, class Combine,
class DistInf, class DistZero>
inline void
dijkstra_shortest_paths
(const VertexListGraph& g,
typename graph_traits<VertexListGraph>::vertex_descriptor s,
PredecessorMap predecessor, DistanceMap distance, WeightMap weight,
IndexMap index_map,
Compare compare, Combine combine, DistInf inf, DistZero zero,
DijkstraVisitor vis)
{
typename graph_traits<VertexListGraph>::vertex_iterator ui, ui_end;
for (tie(ui, ui_end) = vertices(g); ui != ui_end; ++ui) {
put(distance, *ui, inf);
put(predecessor, *ui, *ui);
}
put(distance, s, zero);
dijkstra_shortest_paths_no_init(g, s, predecessor, distance, weight,
index_map, compare, combine, zero, vis);
}
namespace detail {
// Handle defaults for PredecessorMap and
// Distance Compare, Combine, Inf and Zero
template <class VertexListGraph, class DistanceMap, class WeightMap,
class IndexMap, class Params>
inline void
dijkstra_dispatch2
(const VertexListGraph& g,
typename graph_traits<VertexListGraph>::vertex_descriptor s,
DistanceMap distance, WeightMap weight, IndexMap index_map,
const Params& params)
{
// Default for predecessor map
dummy_property_map p_map;
typedef typename property_traits<DistanceMap>::value_type D;
dijkstra_shortest_paths
(g, s,
choose_param(get_param(params, vertex_predecessor), p_map),
distance, weight, index_map,
choose_param(get_param(params, distance_compare_t()),
std::less<D>()),
choose_param(get_param(params, distance_combine_t()),
closed_plus<D>()),
choose_param(get_param(params, distance_inf_t()),
(std::numeric_limits<D>::max)()),
choose_param(get_param(params, distance_zero_t()),
D()),
choose_param(get_param(params, graph_visitor),
make_dijkstra_visitor(null_visitor())));
}
template <class VertexListGraph, class DistanceMap, class WeightMap,
class IndexMap, class Params>
inline void
dijkstra_dispatch1
(const VertexListGraph& g,
typename graph_traits<VertexListGraph>::vertex_descriptor s,
DistanceMap distance, WeightMap weight, IndexMap index_map,
const Params& params)
{
// Default for distance map
typedef typename property_traits<WeightMap>::value_type D;
typename std::vector<D>::size_type
n = is_default_param(distance) ? num_vertices(g) : 1;
std::vector<D> distance_map(n);
detail::dijkstra_dispatch2
(g, s, choose_param(distance, make_iterator_property_map
(distance_map.begin(), index_map,
distance_map[0])),
weight, index_map, params);
}
} // namespace detail
// Named Parameter Variant
template <class VertexListGraph, class Param, class Tag, class Rest>
inline void
dijkstra_shortest_paths
(const VertexListGraph& g,
typename graph_traits<VertexListGraph>::vertex_descriptor s,
const bgl_named_params<Param,Tag,Rest>& params)
{
// Default for edge weight and vertex index map is to ask for them
// from the graph. Default for the visitor is null_visitor.
detail::dijkstra_dispatch1
(g, s,
get_param(params, vertex_distance),
choose_const_pmap(get_param(params, edge_weight), g, edge_weight),
choose_const_pmap(get_param(params, vertex_index), g, vertex_index),
params);
}
} // namespace boost
#endif // BOOST_GRAPH_DIJKSTRA_HPP

View File

@@ -1,197 +0,0 @@
//=======================================================================
// Copyright 2000 University of Notre Dame.
// Authors: Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee
//
// This file is part of the Boost Graph Library
//
// You should have received a copy of the License Agreement for the
// Boost Graph Library along with the software; see the file LICENSE.
// If not, contact Office of Research, University of Notre Dame, Notre
// Dame, IN 46556.
//
// Permission to modify the code and to distribute modified code is
// granted, provided the text of this NOTICE is retained, a notice that
// the code was modified is included with the above COPYRIGHT NOTICE and
// with the COPYRIGHT NOTICE in the LICENSE file, and that the LICENSE
// file is distributed with the modified code.
//
// LICENSOR MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED.
// By way of example, but not limitation, Licensor MAKES NO
// REPRESENTATIONS OR WARRANTIES OF MERCHANTABILITY OR FITNESS FOR ANY
// PARTICULAR PURPOSE OR THAT THE USE OF THE LICENSED SOFTWARE COMPONENTS
// OR DOCUMENTATION WILL NOT INFRINGE ANY PATENTS, COPYRIGHTS, TRADEMARKS
// OR OTHER RIGHTS.
//=======================================================================
#ifndef BOOST_EDGE_CONNECTIVITY
#define BOOST_EDGE_CONNECTIVITY
// WARNING: not-yet fully tested!
#include <boost/config.hpp>
#include <vector>
#include <set>
#include <algorithm>
#include <boost/graph/edmunds_karp_max_flow.hpp>
namespace boost {
namespace detail {
template <class Graph>
inline
std::pair<typename graph_traits<Graph>::vertex_descriptor,
typename graph_traits<Graph>::degree_size_type>
min_degree_vertex(Graph& g)
{
typedef graph_traits<Graph> Traits;
typename Traits::vertex_descriptor p;
typedef typename Traits::degree_size_type size_type;
size_type delta = (std::numeric_limits<size_type>::max)();
typename Traits::vertex_iterator i, iend;
for (tie(i, iend) = vertices(g); i != iend; ++i)
if (degree(*i, g) < delta) {
delta = degree(*i, g);
p = *i;
}
return std::make_pair(p, delta);
}
template <class Graph, class OutputIterator>
void neighbors(const Graph& g,
typename graph_traits<Graph>::vertex_descriptor u,
OutputIterator result)
{
typename graph_traits<Graph>::adjacency_iterator ai, aend;
for (tie(ai, aend) = adjacent_vertices(u, g); ai != aend; ++ai)
*result++ = *ai;
}
template <class Graph, class VertexIterator, class OutputIterator>
void neighbors(const Graph& g,
VertexIterator first, VertexIterator last,
OutputIterator result)
{
for (; first != last; ++first)
neighbors(g, *first, result);
}
} // namespace detail
// O(m n)
template <class VertexListGraph, class OutputIterator>
typename graph_traits<VertexListGraph>::degree_size_type
edge_connectivity(VertexListGraph& g, OutputIterator disconnecting_set)
{
//-------------------------------------------------------------------------
// Type Definitions
typedef graph_traits<VertexListGraph> Traits;
typedef typename Traits::vertex_iterator vertex_iterator;
typedef typename Traits::edge_iterator edge_iterator;
typedef typename Traits::out_edge_iterator out_edge_iterator;
typedef typename Traits::vertex_descriptor vertex_descriptor;
typedef typename Traits::degree_size_type degree_size_type;
typedef color_traits<default_color_type> Color;
typedef adjacency_list_traits<vecS, vecS, directedS> Tr;
typedef typename Tr::edge_descriptor Tr_edge_desc;
typedef adjacency_list<vecS, vecS, directedS, no_property,
property<edge_capacity_t, degree_size_type,
property<edge_residual_capacity_t, degree_size_type,
property<edge_reverse_t, Tr_edge_desc> > > >
FlowGraph;
typedef typename graph_traits<FlowGraph>::edge_descriptor edge_descriptor;
//-------------------------------------------------------------------------
// Variable Declarations
vertex_descriptor u, v, p, k;
edge_descriptor e1, e2;
bool inserted;
vertex_iterator vi, vi_end;
edge_iterator ei, ei_end;
degree_size_type delta, alpha_star, alpha_S_k;
std::set<vertex_descriptor> S, neighbor_S;
std::vector<vertex_descriptor> S_star, non_neighbor_S;
std::vector<default_color_type> color(num_vertices(g));
std::vector<edge_descriptor> pred(num_vertices(g));
//-------------------------------------------------------------------------
// Create a network flow graph out of the undirected graph
FlowGraph flow_g(num_vertices(g));
typename property_map<FlowGraph, edge_capacity_t>::type
cap = get(edge_capacity, flow_g);
typename property_map<FlowGraph, edge_residual_capacity_t>::type
res_cap = get(edge_residual_capacity, flow_g);
typename property_map<FlowGraph, edge_reverse_t>::type
rev_edge = get(edge_reverse, flow_g);
for (tie(ei, ei_end) = edges(g); ei != ei_end; ++ei) {
u = source(*ei, g), v = target(*ei, g);
tie(e1, inserted) = add_edge(u, v, flow_g);
cap[e1] = 1;
tie(e2, inserted) = add_edge(v, u, flow_g);
cap[e2] = 1; // not sure about this
rev_edge[e1] = e2;
rev_edge[e2] = e1;
}
//-------------------------------------------------------------------------
// The Algorithm
tie(p, delta) = detail::min_degree_vertex(g);
S_star.push_back(p);
alpha_star = delta;
S.insert(p);
neighbor_S.insert(p);
detail::neighbors(g, S.begin(), S.end(),
std::inserter(neighbor_S, neighbor_S.begin()));
std::set_difference(vertices(g).first, vertices(g).second,
neighbor_S.begin(), neighbor_S.end(),
std::back_inserter(non_neighbor_S));
while (!non_neighbor_S.empty()) { // at most n - 1 times
k = non_neighbor_S.front();
alpha_S_k = edmunds_karp_max_flow
(flow_g, p, k, cap, res_cap, rev_edge, &color[0], &pred[0]);
if (alpha_S_k < alpha_star) {
alpha_star = alpha_S_k;
S_star.clear();
for (tie(vi, vi_end) = vertices(flow_g); vi != vi_end; ++vi)
if (color[*vi] != Color::white())
S_star.push_back(*vi);
}
S.insert(k);
neighbor_S.insert(k);
detail::neighbors(g, k, std::inserter(neighbor_S, neighbor_S.begin()));
non_neighbor_S.clear();
std::set_difference(vertices(g).first, vertices(g).second,
neighbor_S.begin(), neighbor_S.end(),
std::back_inserter(non_neighbor_S));
}
//-------------------------------------------------------------------------
// Compute edges of the cut [S*, ~S*]
std::vector<bool> in_S_star(num_vertices(g), false);
typename std::vector<vertex_descriptor>::iterator si;
for (si = S_star.begin(); si != S_star.end(); ++si)
in_S_star[*si] = true;
degree_size_type c = 0;
for (si = S_star.begin(); si != S_star.end(); ++si) {
out_edge_iterator ei, ei_end;
for (tie(ei, ei_end) = out_edges(*si, g); ei != ei_end; ++ei)
if (!in_S_star[target(*ei, g)]) {
*disconnecting_set++ = *ei;
++c;
}
}
return c;
}
} // namespace boost
#endif // BOOST_EDGE_CONNECTIVITY

View File

@@ -1,319 +0,0 @@
//=======================================================================
// Copyright 1997, 1998, 1999, 2000 University of Notre Dame.
// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek
//
// This file is part of the Boost Graph Library
//
// You should have received a copy of the License Agreement for the
// Boost Graph Library along with the software; see the file LICENSE.
// If not, contact Office of Research, University of Notre Dame, Notre
// Dame, IN 46556.
//
// Permission to modify the code and to distribute modified code is
// granted, provided the text of this NOTICE is retained, a notice that
// the code was modified is included with the above COPYRIGHT NOTICE and
// with the COPYRIGHT NOTICE in the LICENSE file, and that the LICENSE
// file is distributed with the modified code.
//
// LICENSOR MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED.
// By way of example, but not limitation, Licensor MAKES NO
// REPRESENTATIONS OR WARRANTIES OF MERCHANTABILITY OR FITNESS FOR ANY
// PARTICULAR PURPOSE OR THAT THE USE OF THE LICENSED SOFTWARE COMPONENTS
// OR DOCUMENTATION WILL NOT INFRINGE ANY PATENTS, COPYRIGHTS, TRADEMARKS
// OR OTHER RIGHTS.
//=======================================================================
//
#ifndef BOOST_GRAPH_EDGE_LIST_HPP
#define BOOST_GRAPH_EDGE_LIST_HPP
#include <iterator>
#include <boost/config.hpp>
#include <boost/pending/ct_if.hpp>
#include <boost/pending/integer_range.hpp>
#include <boost/graph/graph_traits.hpp>
#include <boost/graph/properties.hpp>
namespace boost {
//
// The edge_list class is an EdgeListGraph module that is constructed
// from a pair of iterators whose value type is a pair of vertex
// descriptors.
//
// For example:
//
// typedef std::pair<int,int> E;
// list<E> elist;
// ...
// typedef edge_list<list<E>::iterator> Graph;
// Graph g(elist.begin(), elist.end());
//
// If the iterators are random access, then Graph::edge_descriptor
// is of Integral type, otherwise it is a struct, though it is
// convertible to an Integral type.
//
struct edge_list_tag { };
// The implementation class for edge_list.
template <class G, class EdgeIter, class T, class D>
class edge_list_impl
{
public:
typedef D edge_id;
typedef T Vpair;
typedef typename Vpair::first_type V;
typedef V vertex_descriptor;
typedef edge_list_tag graph_tag;
typedef void edge_property_type;
struct edge_descriptor
{
edge_descriptor() { }
edge_descriptor(EdgeIter p, edge_id id) : _ptr(p), _id(id) { }
operator edge_id() { return _id; }
EdgeIter _ptr;
edge_id _id;
};
typedef edge_descriptor E;
struct edge_iterator
{
typedef edge_iterator self;
typedef E value_type;
typedef E& reference;
typedef E* pointer;
typedef std::ptrdiff_t difference_type;
typedef std::input_iterator_tag iterator_category;
edge_iterator() { }
edge_iterator(EdgeIter iter) : _iter(iter), _i(0) { }
E operator*() { return E(_iter, _i); }
self& operator++() { ++_iter; ++_i; return *this; }
self operator++(int) { self t = *this; ++(*this); return t; }
bool operator==(const self& x) { return _iter == x._iter; }
bool operator!=(const self& x) { return _iter != x._iter; }
EdgeIter _iter;
edge_id _i;
};
typedef void out_edge_iterator;
typedef void in_edge_iterator;
typedef void adjacency_iterator;
typedef void vertex_iterator;
};
template <class G, class EI, class T, class D>
std::pair<typename edge_list_impl<G,EI,T,D>::edge_iterator,
typename edge_list_impl<G,EI,T,D>::edge_iterator>
edges(const edge_list_impl<G,EI,T,D>& g_) {
const G& g = static_cast<const G&>(g_);
typedef typename edge_list_impl<G,EI,T,D>::edge_iterator edge_iterator;
return std::make_pair(edge_iterator(g._first), edge_iterator(g._last));
}
template <class G, class EI, class T, class D>
typename edge_list_impl<G,EI,T,D>::vertex_descriptor
source(typename edge_list_impl<G,EI,T,D>::edge_descriptor e,
const edge_list_impl<G,EI,T,D>&) {
return (*e._ptr).first;
}
template <class G, class EI, class T, class D>
typename edge_list_impl<G,EI,T,D>::vertex_descriptor
target(typename edge_list_impl<G,EI,T,D>::edge_descriptor e,
const edge_list_impl<G,EI,T,D>&) {
return (*e._ptr).second;
}
template <class D, class E>
class el_edge_property_map
: public put_get_helper<D, el_edge_property_map<D,E> >{
public:
typedef E key_type;
typedef D value_type;
typedef D reference;
typedef readable_property_map_tag category;
value_type operator[](key_type e) const {
return e._i;
}
};
struct edge_list_edge_property_selector {
template <class Graph, class Property, class Tag>
struct bind_ {
typedef el_edge_property_map<typename Graph::edge_id,
typename Graph::edge_descriptor> type;
typedef type const_type;
};
};
template <>
struct edge_property_selector<edge_list_tag> {
typedef edge_list_edge_property_selector type;
};
template <class G, class EI, class T, class D>
typename property_map< edge_list_impl<G,EI,T,D>, edge_index_t>::type
get(edge_index_t, const edge_list_impl<G,EI,T,D>&) {
typedef typename property_map< edge_list_impl<G,EI,T,D>,
edge_index_t>::type EdgeIndexMap;
return EdgeIndexMap();
}
template <class G, class EI, class T, class D>
inline D
get(edge_index_t, const edge_list_impl<G,EI,T,D>&,
typename edge_list_impl<G,EI,T,D>::edge_descriptor e) {
return e._i;
}
// A specialized implementation for when the iterators are random access.
struct edge_list_ra_tag { };
template <class G, class EdgeIter, class T, class D>
class edge_list_impl_ra
{
public:
typedef D edge_id;
typedef T Vpair;
typedef typename Vpair::first_type V;
typedef edge_list_ra_tag graph_tag;
typedef void edge_property_type;
typedef edge_id edge_descriptor;
typedef V vertex_descriptor;
typedef typename boost::integer_range<edge_id>::iterator edge_iterator;
typedef void out_edge_iterator;
typedef void in_edge_iterator;
typedef void adjacency_iterator;
typedef void vertex_iterator;
};
template <class G, class EI, class T, class D>
std::pair<typename edge_list_impl_ra<G,EI,T,D>::edge_iterator,
typename edge_list_impl_ra<G,EI,T,D>::edge_iterator>
edges(const edge_list_impl_ra<G,EI,T,D>& g_)
{
const G& g = static_cast<const G&>(g_);
typedef typename edge_list_impl_ra<G,EI,T,D>::edge_iterator edge_iterator;
return std::make_pair(edge_iterator(0), edge_iterator(g._last - g._first));
}
template <class G, class EI, class T, class D>
typename edge_list_impl_ra<G,EI,T,D>::vertex_descriptor
source(typename edge_list_impl_ra<G,EI,T,D>::edge_descriptor e,
const edge_list_impl_ra<G,EI,T,D>& g_)
{
const G& g = static_cast<const G&>(g_);
return g._first[e].first;
}
template <class G, class EI, class T, class D>
typename edge_list_impl_ra<G,EI,T,D>::vertex_descriptor
target(typename edge_list_impl_ra<G,EI,T,D>::edge_descriptor e,
const edge_list_impl_ra<G,EI,T,D>& g_)
{
const G& g = static_cast<const G&>(g_);
return g._first[e].second;
}
template <class E>
class el_ra_edge_property_map
: public put_get_helper<E, el_ra_edge_property_map<E> >{
public:
typedef E key_type;
typedef E value_type;
typedef E reference;
typedef readable_property_map_tag category;
value_type operator[](key_type e) const {
return e;
}
};
struct edge_list_ra_edge_property_selector {
template <class Graph, class Property, class Tag>
struct bind_ {
typedef el_ra_edge_property_map<typename Graph::edge_descriptor> type;
typedef type const_type;
};
};
template <>
struct edge_property_selector<edge_list_ra_tag> {
typedef edge_list_ra_edge_property_selector type;
};
template <class G, class EI, class T, class D>
inline
typename property_map< edge_list_impl_ra<G,EI,T,D>, edge_index_t>::type
get(edge_index_t, const edge_list_impl_ra<G,EI,T,D>&) {
typedef typename property_map< edge_list_impl_ra<G,EI,T,D>,
edge_index_t>::type EdgeIndexMap;
return EdgeIndexMap();
}
template <class G, class EI, class T, class D>
inline D
get(edge_index_t, const edge_list_impl_ra<G,EI,T,D>&,
typename edge_list_impl_ra<G,EI,T,D>::edge_descriptor e) {
return e;
}
// Some helper classes for determining if the iterators are random access
template <class Cat>
struct is_random {
enum { RET = false };
typedef false_type type;
};
template <>
struct is_random<std::random_access_iterator_tag> {
enum { RET = true }; typedef true_type type;
};
// The edge_list class conditionally inherits from one of the
// above two classes.
template <class EdgeIter,
#if !defined BOOST_NO_STD_ITERATOR_TRAITS
class T = typename std::iterator_traits<EdgeIter>::value_type,
class D = typename std::iterator_traits<EdgeIter>::difference_type,
class Cat = typename std::iterator_traits<EdgeIter>::iterator_category>
#else
class T,
class D,
class Cat>
#endif
class edge_list
: public ct_if_t< typename is_random<Cat>::type,
edge_list_impl_ra< edge_list<EdgeIter,T,D,Cat>, EdgeIter,T,D>,
edge_list_impl< edge_list<EdgeIter,T,D,Cat>, EdgeIter,T,D>
>::type
{
public:
typedef directed_tag directed_category;
typedef allow_parallel_edge_tag edge_parallel_category;
typedef edge_list_graph_tag traversal_category;
typedef std::size_t edges_size_type;
typedef std::size_t vertices_size_type;
typedef std::size_t degree_size_type;
edge_list(EdgeIter first, EdgeIter last) : _first(first), _last(last) {
m_num_edges = std::distance(first, last);
}
edge_list(EdgeIter first, EdgeIter last, edges_size_type E)
: _first(first), _last(last), m_num_edges(E) { }
EdgeIter _first, _last;
edges_size_type m_num_edges;
};
template <class EdgeIter, class T, class D, class Cat>
std::size_t num_edges(const edge_list<EdgeIter, T, D, Cat>& el) {
return el.m_num_edges;
}
#ifndef BOOST_NO_STD_ITERATOR_TRAITS
template <class EdgeIter>
inline edge_list<EdgeIter>
make_edge_list(EdgeIter first, EdgeIter last)
{
return edge_list<EdgeIter>(first, last);
}
#endif
} /* namespace boost */
#endif /* BOOST_GRAPH_EDGE_LIST_HPP */

View File

@@ -1,266 +0,0 @@
//=======================================================================
// Copyright 2000 University of Notre Dame.
// Authors: Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee
//
// This file is part of the Boost Graph Library
//
// You should have received a copy of the License Agreement for the
// Boost Graph Library along with the software; see the file LICENSE.
// If not, contact Office of Research, University of Notre Dame, Notre
// Dame, IN 46556.
//
// Permission to modify the code and to distribute modified code is
// granted, provided the text of this NOTICE is retained, a notice that
// the code was modified is included with the above COPYRIGHT NOTICE and
// with the COPYRIGHT NOTICE in the LICENSE file, and that the LICENSE
// file is distributed with the modified code.
//
// LICENSOR MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED.
// By way of example, but not limitation, Licensor MAKES NO
// REPRESENTATIONS OR WARRANTIES OF MERCHANTABILITY OR FITNESS FOR ANY
// PARTICULAR PURPOSE OR THAT THE USE OF THE LICENSED SOFTWARE COMPONENTS
// OR DOCUMENTATION WILL NOT INFRINGE ANY PATENTS, COPYRIGHTS, TRADEMARKS
// OR OTHER RIGHTS.
//=======================================================================
#ifndef EDMUNDS_KARP_MAX_FLOW_HPP
#define EDMUNDS_KARP_MAX_FLOW_HPP
#include <boost/config.hpp>
#include <vector>
#include <algorithm> // for std::min and std::max
#include <boost/config.hpp>
#include <boost/pending/queue.hpp>
#include <boost/property_map.hpp>
#include <boost/graph/graph_traits.hpp>
#include <boost/graph/properties.hpp>
#include <boost/graph/filtered_graph.hpp>
#include <boost/graph/breadth_first_search.hpp>
namespace boost {
// The "labeling" algorithm from "Network Flows" by Ahuja, Magnanti,
// Orlin. I think this is the same as or very similar to the original
// Edmunds-Karp algorithm. This solves the maximum flow problem.
namespace detail {
template <class Graph, class ResCapMap>
filtered_graph<Graph, is_residual_edge<ResCapMap> >
residual_graph(Graph& g, ResCapMap residual_capacity) {
return filtered_graph<Graph, is_residual_edge<ResCapMap> >
(g, is_residual_edge<ResCapMap>(residual_capacity));
}
template <class Graph, class PredEdgeMap, class ResCapMap,
class RevEdgeMap>
inline void
augment(Graph& g,
typename graph_traits<Graph>::vertex_descriptor src,
typename graph_traits<Graph>::vertex_descriptor sink,
PredEdgeMap p,
ResCapMap residual_capacity,
RevEdgeMap reverse_edge)
{
typename graph_traits<Graph>::edge_descriptor e;
typename graph_traits<Graph>::vertex_descriptor u;
typedef typename property_traits<ResCapMap>::value_type FlowValue;
// find minimum residual capacity along the augmenting path
FlowValue delta = (std::numeric_limits<FlowValue>::max)();
e = p[sink];
do {
BOOST_USING_STD_MIN();
delta = min BOOST_PREVENT_MACRO_SUBSTITUTION(delta, residual_capacity[e]);
u = source(e, g);
e = p[u];
} while (u != src);
// push delta units of flow along the augmenting path
e = p[sink];
do {
residual_capacity[e] -= delta;
residual_capacity[reverse_edge[e]] += delta;
u = source(e, g);
e = p[u];
} while (u != src);
}
} // namespace detail
template <class Graph,
class CapacityEdgeMap, class ResidualCapacityEdgeMap,
class ReverseEdgeMap, class ColorMap, class PredEdgeMap>
typename property_traits<CapacityEdgeMap>::value_type
edmunds_karp_max_flow
(Graph& g,
typename graph_traits<Graph>::vertex_descriptor src,
typename graph_traits<Graph>::vertex_descriptor sink,
CapacityEdgeMap cap,
ResidualCapacityEdgeMap res,
ReverseEdgeMap rev,
ColorMap color,
PredEdgeMap pred)
{
typedef typename graph_traits<Graph>::vertex_descriptor vertex_t;
typedef typename property_traits<ColorMap>::value_type ColorValue;
typedef color_traits<ColorValue> Color;
typename graph_traits<Graph>::vertex_iterator u_iter, u_end;
typename graph_traits<Graph>::out_edge_iterator ei, e_end;
for (tie(u_iter, u_end) = vertices(g); u_iter != u_end; ++u_iter)
for (tie(ei, e_end) = out_edges(*u_iter, g); ei != e_end; ++ei)
res[*ei] = cap[*ei];
color[sink] = Color::gray();
while (color[sink] != Color::white()) {
boost::queue<vertex_t> Q;
breadth_first_search
(detail::residual_graph(g, res), src, Q,
make_bfs_visitor(record_edge_predecessors(pred, on_tree_edge())),
color);
if (color[sink] != Color::white())
detail::augment(g, src, sink, pred, res, rev);
} // while
typename property_traits<CapacityEdgeMap>::value_type flow = 0;
for (tie(ei, e_end) = out_edges(src, g); ei != e_end; ++ei)
flow += (cap[*ei] - res[*ei]);
return flow;
} // edmunds_karp_max_flow()
namespace detail {
//-------------------------------------------------------------------------
// Handle default for color property map
// use of class here is a VC++ workaround
template <class ColorMap>
struct edmunds_karp_dispatch2 {
template <class Graph, class PredMap, class P, class T, class R>
static typename edge_capacity_value<Graph, P, T, R>::type
apply
(Graph& g,
typename graph_traits<Graph>::vertex_descriptor src,
typename graph_traits<Graph>::vertex_descriptor sink,
PredMap pred,
const bgl_named_params<P, T, R>& params,
ColorMap color)
{
return edmunds_karp_max_flow
(g, src, sink,
choose_const_pmap(get_param(params, edge_capacity), g, edge_capacity),
choose_pmap(get_param(params, edge_residual_capacity),
g, edge_residual_capacity),
choose_const_pmap(get_param(params, edge_reverse), g, edge_reverse),
color, pred);
}
};
template<>
struct edmunds_karp_dispatch2<detail::error_property_not_found> {
template <class Graph, class PredMap, class P, class T, class R>
static typename edge_capacity_value<Graph, P, T, R>::type
apply
(Graph& g,
typename graph_traits<Graph>::vertex_descriptor src,
typename graph_traits<Graph>::vertex_descriptor sink,
PredMap pred,
const bgl_named_params<P, T, R>& params,
detail::error_property_not_found)
{
typedef typename graph_traits<Graph>::edge_descriptor edge_descriptor;
typedef typename graph_traits<Graph>::vertices_size_type size_type;
size_type n = is_default_param(get_param(params, vertex_color)) ?
num_vertices(g) : 1;
std::vector<default_color_type> color_vec(n);
return edmunds_karp_max_flow
(g, src, sink,
choose_const_pmap(get_param(params, edge_capacity), g, edge_capacity),
choose_pmap(get_param(params, edge_residual_capacity),
g, edge_residual_capacity),
choose_const_pmap(get_param(params, edge_reverse), g, edge_reverse),
make_iterator_property_map(color_vec.begin(), choose_const_pmap
(get_param(params, vertex_index),
g, vertex_index), color_vec[0]),
pred);
}
};
//-------------------------------------------------------------------------
// Handle default for predecessor property map
// use of class here is a VC++ workaround
template <class PredMap>
struct edmunds_karp_dispatch1 {
template <class Graph, class P, class T, class R>
static typename edge_capacity_value<Graph, P, T, R>::type
apply(Graph& g,
typename graph_traits<Graph>::vertex_descriptor src,
typename graph_traits<Graph>::vertex_descriptor sink,
const bgl_named_params<P, T, R>& params,
PredMap pred)
{
typedef typename property_value< bgl_named_params<P,T,R>, vertex_color_t>::type C;
return edmunds_karp_dispatch2<C>::apply
(g, src, sink, pred, params, get_param(params, vertex_color));
}
};
template<>
struct edmunds_karp_dispatch1<detail::error_property_not_found> {
template <class Graph, class P, class T, class R>
static typename edge_capacity_value<Graph, P, T, R>::type
apply
(Graph& g,
typename graph_traits<Graph>::vertex_descriptor src,
typename graph_traits<Graph>::vertex_descriptor sink,
const bgl_named_params<P, T, R>& params,
detail::error_property_not_found)
{
typedef typename graph_traits<Graph>::edge_descriptor edge_descriptor;
typedef typename graph_traits<Graph>::vertices_size_type size_type;
size_type n = is_default_param(get_param(params, vertex_predecessor)) ?
num_vertices(g) : 1;
std::vector<edge_descriptor> pred_vec(n);
typedef typename property_value< bgl_named_params<P,T,R>, vertex_color_t>::type C;
return edmunds_karp_dispatch2<C>::apply
(g, src, sink,
make_iterator_property_map(pred_vec.begin(), choose_const_pmap
(get_param(params, vertex_index),
g, vertex_index), pred_vec[0]),
params,
get_param(params, vertex_color));
}
};
} // namespace detail
template <class Graph, class P, class T, class R>
typename detail::edge_capacity_value<Graph, P, T, R>::type
edmunds_karp_max_flow
(Graph& g,
typename graph_traits<Graph>::vertex_descriptor src,
typename graph_traits<Graph>::vertex_descriptor sink,
const bgl_named_params<P, T, R>& params)
{
typedef typename property_value< bgl_named_params<P,T,R>, vertex_predecessor_t>::type Pred;
return detail::edmunds_karp_dispatch1<Pred>::apply
(g, src, sink, params, get_param(params, vertex_predecessor));
}
template <class Graph>
typename property_traits<
typename property_map<Graph, edge_capacity_t>::const_type
>::value_type
edmunds_karp_max_flow
(Graph& g,
typename graph_traits<Graph>::vertex_descriptor src,
typename graph_traits<Graph>::vertex_descriptor sink)
{
bgl_named_params<int, buffer_param_t> params(0);
return edmunds_karp_max_flow(g, src, sink, params);
}
} // namespace boost
#endif // EDMUNDS_KARP_MAX_FLOW_HPP

View File

@@ -1,58 +0,0 @@
//=======================================================================
// Copyright 2002 Indiana University.
// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek
//
// This file is part of the Boost Graph Library
//
// You should have received a copy of the License Agreement for the
// Boost Graph Library along with the software; see the file LICENSE.
//
// Permission to modify the code and to distribute modified code is
// granted, provided the text of this NOTICE is retained, a notice that
// the code was modified is included with the above COPYRIGHT NOTICE and
// with the COPYRIGHT NOTICE in the LICENSE file, and that the LICENSE
// file is distributed with the modified code.
//
// LICENSOR MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED.
// By way of example, but not limitation, Licensor MAKES NO
// REPRESENTATIONS OR WARRANTIES OF MERCHANTABILITY OR FITNESS FOR ANY
// PARTICULAR PURPOSE OR THAT THE USE OF THE LICENSED SOFTWARE COMPONENTS
// OR DOCUMENTATION WILL NOT INFRINGE ANY PATENTS, COPYRIGHTS, TRADEMARKS
// OR OTHER RIGHTS.
//=======================================================================
#ifndef BOOST_GRAPH_EXCEPTION_HPP
#define BOOST_GRAPH_EXCEPTION_HPP
#include <stdexcept>
#include <string>
namespace boost {
struct bad_graph : public std::invalid_argument {
bad_graph(const std::string& what_arg)
: std::invalid_argument(what_arg) { }
};
struct not_a_dag : public bad_graph {
not_a_dag()
: bad_graph("The graph must be a DAG.") { }
};
struct negative_edge : public bad_graph {
negative_edge()
: bad_graph("The graph may not contain an edge with negative weight."){ }
};
struct negative_cycle : public bad_graph {
negative_cycle()
: bad_graph("The graph may not contain negative cycles.") { }
};
struct not_connected : public bad_graph {
not_connected()
: bad_graph("The graph must be connected.") { }
};
} // namespace boost
#endif // BOOST_GRAPH_EXCEPTION_HPP

View File

@@ -1,482 +0,0 @@
//=======================================================================
// Copyright 1997, 1998, 1999, 2000 University of Notre Dame.
// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek
//
// This file is part of the Boost Graph Library
//
// You should have received a copy of the License Agreement for the
// Boost Graph Library along with the software; see the file LICENSE.
// If not, contact Office of Research, University of Notre Dame, Notre
// Dame, IN 46556.
//
// Permission to modify the code and to distribute modified code is
// granted, provided the text of this NOTICE is retained, a notice that
// the code was modified is included with the above COPYRIGHT NOTICE and
// with the COPYRIGHT NOTICE in the LICENSE file, and that the LICENSE
// file is distributed with the modified code.
//
// LICENSOR MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED.
// By way of example, but not limitation, Licensor MAKES NO
// REPRESENTATIONS OR WARRANTIES OF MERCHANTABILITY OR FITNESS FOR ANY
// PARTICULAR PURPOSE OR THAT THE USE OF THE LICENSED SOFTWARE COMPONENTS
// OR DOCUMENTATION WILL NOT INFRINGE ANY PATENTS, COPYRIGHTS, TRADEMARKS
// OR OTHER RIGHTS.
//=======================================================================
#ifndef BOOST_FILTERED_GRAPH_HPP
#define BOOST_FILTERED_GRAPH_HPP
#include <boost/graph/graph_traits.hpp>
#include <boost/graph/properties.hpp>
#include <boost/graph/adjacency_iterator.hpp>
#include <boost/iterator/filter_iterator.hpp>
namespace boost {
//=========================================================================
// Some predicate classes.
struct keep_all {
template <typename T>
bool operator()(const T&) const { return true; }
};
// Keep residual edges (used in maximum-flow algorithms).
template <typename ResidualCapacityEdgeMap>
struct is_residual_edge {
is_residual_edge() { }
is_residual_edge(ResidualCapacityEdgeMap rcap) : m_rcap(rcap) { }
template <typename Edge>
bool operator()(const Edge& e) const {
return 0 < get(m_rcap, e);
}
ResidualCapacityEdgeMap m_rcap;
};
template <typename Set>
struct is_in_subset {
is_in_subset() : m_s(0) { }
is_in_subset(const Set& s) : m_s(&s) { }
template <typename Elt>
bool operator()(const Elt& x) const {
return set_contains(*m_s, x);
}
const Set* m_s;
};
template <typename Set>
struct is_not_in_subset {
is_not_in_subset() : m_s(0) { }
is_not_in_subset(const Set& s) : m_s(&s) { }
template <typename Elt>
bool operator()(const Elt& x) const {
return !set_contains(*m_s, x);
}
const Set* m_s;
};
namespace detail {
template <typename EdgePredicate, typename VertexPredicate, typename Graph>
struct out_edge_predicate {
out_edge_predicate() { }
out_edge_predicate(EdgePredicate ep, VertexPredicate vp,
const Graph& g)
: m_edge_pred(ep), m_vertex_pred(vp), m_g(&g) { }
template <typename Edge>
bool operator()(const Edge& e) const {
return m_edge_pred(e) && m_vertex_pred(target(e, *m_g));
}
EdgePredicate m_edge_pred;
VertexPredicate m_vertex_pred;
const Graph* m_g;
};
template <typename EdgePredicate, typename VertexPredicate, typename Graph>
struct in_edge_predicate {
in_edge_predicate() { }
in_edge_predicate(EdgePredicate ep, VertexPredicate vp,
const Graph& g)
: m_edge_pred(ep), m_vertex_pred(vp), m_g(&g) { }
template <typename Edge>
bool operator()(const Edge& e) const {
return m_edge_pred(e) && m_vertex_pred(source(e, *m_g));
}
EdgePredicate m_edge_pred;
VertexPredicate m_vertex_pred;
const Graph* m_g;
};
template <typename EdgePredicate, typename VertexPredicate, typename Graph>
struct edge_predicate {
edge_predicate() { }
edge_predicate(EdgePredicate ep, VertexPredicate vp,
const Graph& g)
: m_edge_pred(ep), m_vertex_pred(vp), m_g(&g) { }
template <typename Edge>
bool operator()(const Edge& e) const {
return m_edge_pred(e)
&& m_vertex_pred(source(e, *m_g)) && m_vertex_pred(target(e, *m_g));
}
EdgePredicate m_edge_pred;
VertexPredicate m_vertex_pred;
const Graph* m_g;
};
} // namespace detail
//===========================================================================
// Filtered Graph
struct filtered_graph_tag { };
// This base class is a stupid hack to change overload resolution
// rules for the source and target functions so that they are a
// worse match than the source and target functions defined for
// pairs in graph_traits.hpp. I feel dirty. -JGS
template <class G>
struct filtered_graph_base {
typedef graph_traits<G> Traits;
typedef typename Traits::vertex_descriptor vertex_descriptor;
typedef typename Traits::edge_descriptor edge_descriptor;
filtered_graph_base(const G& g) : m_g(g) { }
//protected:
const G& m_g;
};
template <typename Graph,
typename EdgePredicate,
typename VertexPredicate = keep_all>
class filtered_graph : public filtered_graph_base<Graph> {
typedef filtered_graph_base<Graph> Base;
typedef graph_traits<Graph> Traits;
typedef filtered_graph self;
public:
typedef Graph graph_type;
typedef detail::out_edge_predicate<EdgePredicate,
VertexPredicate, self> OutEdgePred;
typedef detail::in_edge_predicate<EdgePredicate,
VertexPredicate, self> InEdgePred;
typedef detail::edge_predicate<EdgePredicate,
VertexPredicate, self> EdgePred;
// Constructors
filtered_graph(const Graph& g, EdgePredicate ep)
: Base(g), m_edge_pred(ep) { }
filtered_graph(const Graph& g, EdgePredicate ep, VertexPredicate vp)
: Base(g), m_edge_pred(ep), m_vertex_pred(vp) { }
// Graph requirements
typedef typename Traits::vertex_descriptor vertex_descriptor;
typedef typename Traits::edge_descriptor edge_descriptor;
typedef typename Traits::directed_category directed_category;
typedef typename Traits::edge_parallel_category edge_parallel_category;
typedef typename Traits::traversal_category traversal_category;
// IncidenceGraph requirements
typedef filter_iterator<
OutEdgePred, typename Traits::out_edge_iterator
> out_edge_iterator;
typedef typename Traits::degree_size_type degree_size_type;
// AdjacencyGraph requirements
typedef typename adjacency_iterator_generator<self,
vertex_descriptor, out_edge_iterator>::type adjacency_iterator;
// BidirectionalGraph requirements
typedef filter_iterator<
InEdgePred, typename Traits::in_edge_iterator
> in_edge_iterator;
// VertexListGraph requirements
typedef filter_iterator<
VertexPredicate, typename Traits::vertex_iterator
> vertex_iterator;
typedef typename Traits::vertices_size_type vertices_size_type;
// EdgeListGraph requirements
typedef filter_iterator<
EdgePred, typename Traits::edge_iterator
> edge_iterator;
typedef typename Traits::edges_size_type edges_size_type;
typedef typename ::boost::edge_property_type<Graph>::type edge_property_type;
typedef typename ::boost::vertex_property_type<Graph>::type vertex_property_type;
typedef filtered_graph_tag graph_tag;
//private:
EdgePredicate m_edge_pred;
VertexPredicate m_vertex_pred;
};
//===========================================================================
// Non-member functions for the Filtered Edge Graph
// Helper functions
template <typename Graph, typename EdgePredicate>
inline filtered_graph<Graph, EdgePredicate>
make_filtered_graph(Graph& g, EdgePredicate ep) {
return filtered_graph<Graph, EdgePredicate>(g, ep);
}
template <typename Graph, typename EdgePredicate, typename VertexPredicate>
inline filtered_graph<Graph, EdgePredicate, VertexPredicate>
make_filtered_graph(Graph& g, EdgePredicate ep, VertexPredicate vp) {
return filtered_graph<Graph, EdgePredicate, VertexPredicate>(g, ep, vp);
}
template <typename G, typename EP, typename VP>
std::pair<typename filtered_graph<G, EP, VP>::vertex_iterator,
typename filtered_graph<G, EP, VP>::vertex_iterator>
vertices(const filtered_graph<G, EP, VP>& g)
{
typedef filtered_graph<G, EP, VP> Graph;
typename graph_traits<G>::vertex_iterator f, l;
tie(f, l) = vertices(g.m_g);
typedef typename Graph::vertex_iterator iter;
return std::make_pair(iter(g.m_vertex_pred, f, l),
iter(g.m_vertex_pred, l, l));
}
template <typename G, typename EP, typename VP>
std::pair<typename filtered_graph<G, EP, VP>::edge_iterator,
typename filtered_graph<G, EP, VP>::edge_iterator>
edges(const filtered_graph<G, EP, VP>& g)
{
typedef filtered_graph<G, EP, VP> Graph;
typename Graph::EdgePred pred(g.m_edge_pred, g.m_vertex_pred, g);
typename graph_traits<G>::edge_iterator f, l;
tie(f, l) = edges(g.m_g);
typedef typename Graph::edge_iterator iter;
return std::make_pair(iter(pred, f, l), iter(pred, l, l));
}
// An alternative for num_vertices() and num_edges() would be to
// count the number in the filtered graph. This is problematic
// because of the interaction with the vertex indices... they would
// no longer go from 0 to num_vertices(), which would cause trouble
// for algorithms allocating property storage in an array. We could
// try to create a mapping to new recalibrated indices, but I don't
// see an efficient way to do this.
//
// However, the current solution is still unsatisfactory because
// the following semantic constraints no longer hold:
// tie(vi, viend) = vertices(g);
// assert(std::distance(vi, viend) == num_vertices(g));
template <typename G, typename EP, typename VP>
typename filtered_graph<G, EP, VP>::vertices_size_type
num_vertices(const filtered_graph<G, EP, VP>& g) {
return num_vertices(g.m_g);
}
template <typename G, typename EP, typename VP>
typename filtered_graph<G, EP, VP>::edges_size_type
num_edges(const filtered_graph<G, EP, VP>& g) {
return num_edges(g.m_g);
}
template <typename G>
typename filtered_graph_base<G>::vertex_descriptor
source(typename filtered_graph_base<G>::edge_descriptor e,
const filtered_graph_base<G>& g)
{
return source(e, g.m_g);
}
template <typename G>
typename filtered_graph_base<G>::vertex_descriptor
target(typename filtered_graph_base<G>::edge_descriptor e,
const filtered_graph_base<G>& g)
{
return target(e, g.m_g);
}
template <typename G, typename EP, typename VP>
std::pair<typename filtered_graph<G, EP, VP>::out_edge_iterator,
typename filtered_graph<G, EP, VP>::out_edge_iterator>
out_edges(typename filtered_graph<G, EP, VP>::vertex_descriptor u,
const filtered_graph<G, EP, VP>& g)
{
typedef filtered_graph<G, EP, VP> Graph;
typename Graph::OutEdgePred pred(g.m_edge_pred, g.m_vertex_pred, g);
typedef typename Graph::out_edge_iterator iter;
typename graph_traits<G>::out_edge_iterator f, l;
tie(f, l) = out_edges(u, g.m_g);
return std::make_pair(iter(pred, f, l), iter(pred, l, l));
}
template <typename G, typename EP, typename VP>
typename filtered_graph<G, EP, VP>::degree_size_type
out_degree(typename filtered_graph<G, EP, VP>::vertex_descriptor u,
const filtered_graph<G, EP, VP>& g)
{
typename filtered_graph<G, EP, VP>::degree_size_type n = 0;
typename filtered_graph<G, EP, VP>::out_edge_iterator f, l;
for (tie(f, l) = out_edges(u, g); f != l; ++f)
++n;
return n;
}
template <typename G, typename EP, typename VP>
std::pair<typename filtered_graph<G, EP, VP>::adjacency_iterator,
typename filtered_graph<G, EP, VP>::adjacency_iterator>
adjacent_vertices(typename filtered_graph<G, EP, VP>::vertex_descriptor u,
const filtered_graph<G, EP, VP>& g)
{
typedef filtered_graph<G, EP, VP> Graph;
typedef typename Graph::adjacency_iterator adjacency_iterator;
typename Graph::out_edge_iterator f, l;
tie(f, l) = out_edges(u, g);
return std::make_pair(adjacency_iterator(f, const_cast<Graph*>(&g)),
adjacency_iterator(l, const_cast<Graph*>(&g)));
}
template <typename G, typename EP, typename VP>
std::pair<typename filtered_graph<G, EP, VP>::in_edge_iterator,
typename filtered_graph<G, EP, VP>::in_edge_iterator>
in_edges(typename filtered_graph<G, EP, VP>::vertex_descriptor u,
const filtered_graph<G, EP, VP>& g)
{
typedef filtered_graph<G, EP, VP> Graph;
typename Graph::InEdgePred pred(g.m_edge_pred, g.m_vertex_pred, g);
typedef typename Graph::in_edge_iterator iter;
typename graph_traits<G>::in_edge_iterator f, l;
tie(f, l) = in_edges(u, g.m_g);
return std::make_pair(iter(pred, f, l), iter(pred, l, l));
}
template <typename G, typename EP, typename VP>
typename filtered_graph<G, EP, VP>::degree_size_type
in_degree(typename filtered_graph<G, EP, VP>::vertex_descriptor u,
const filtered_graph<G, EP, VP>& g)
{
typename filtered_graph<G, EP, VP>::degree_size_type n = 0;
typename filtered_graph<G, EP, VP>::in_edge_iterator f, l;
for (tie(f, l) = in_edges(u, g); f != l; ++f)
++n;
return n;
}
template <typename G, typename EP, typename VP>
std::pair<typename filtered_graph<G, EP, VP>::edge_descriptor, bool>
edge(typename filtered_graph<G, EP, VP>::vertex_descriptor u,
typename filtered_graph<G, EP, VP>::vertex_descriptor v,
const filtered_graph<G, EP, VP>& g)
{
typename graph_traits<G>::edge_descriptor e;
bool exists;
tie(e, exists) = edge(u, v, g.m_g);
return std::make_pair(e, exists && g.m_edge_pred(e));
}
template <typename G, typename EP, typename VP>
std::pair<typename filtered_graph<G, EP, VP>::out_edge_iterator,
typename filtered_graph<G, EP, VP>::out_edge_iterator>
edge_range(typename filtered_graph<G, EP, VP>::vertex_descriptor u,
typename filtered_graph<G, EP, VP>::vertex_descriptor v,
const filtered_graph<G, EP, VP>& g)
{
typedef filtered_graph<G, EP, VP> Graph;
typename Graph::OutEdgePred pred(g.m_edge_pred, g.m_vertex_pred, g);
typedef typename Graph::out_edge_iterator iter;
typename graph_traits<G>::out_edge_iterator f, l;
tie(f, l) = edge_range(u, v, g.m_g);
return std::make_pair(iter(pred, f, l), iter(pred, l, l));
}
//===========================================================================
// Property map
namespace detail {
struct filtered_graph_property_selector {
template <class FilteredGraph, class Property, class Tag>
struct bind_ {
typedef typename FilteredGraph::graph_type Graph;
typedef property_map<Graph, Tag> Map;
typedef typename Map::type type;
typedef typename Map::const_type const_type;
};
};
} // namespace detail
template <>
struct vertex_property_selector<filtered_graph_tag> {
typedef detail::filtered_graph_property_selector type;
};
template <>
struct edge_property_selector<filtered_graph_tag> {
typedef detail::filtered_graph_property_selector type;
};
template <typename G, typename EP, typename VP, typename Property>
typename property_map<G, Property>::type
get(Property p, filtered_graph<G, EP, VP>& g)
{
return get(p, const_cast<G&>(g.m_g));
}
template <typename G, typename EP, typename VP,typename Property>
typename property_map<G, Property>::const_type
get(Property p, const filtered_graph<G, EP, VP>& g)
{
return get(p, (const G&)g.m_g);
}
template <typename G, typename EP, typename VP, typename Property,
typename Key>
typename property_map_value<G, Property>::type
get(Property p, const filtered_graph<G, EP, VP>& g, const Key& k)
{
return get(p, (const G&)g.m_g, k);
}
template <typename G, typename EP, typename VP, typename Property,
typename Key, typename Value>
void
put(Property p, const filtered_graph<G, EP, VP>& g, const Key& k,
const Value& val)
{
put(p, const_cast<G&>(g.m_g), k, val);
}
//===========================================================================
// Some filtered subgraph specializations
template <typename Graph, typename Set>
struct vertex_subset_filter {
typedef filtered_graph<Graph, keep_all, is_in_subset<Set> > type;
};
template <typename Graph, typename Set>
inline typename vertex_subset_filter<Graph, Set>::type
make_vertex_subset_filter(Graph& g, const Set& s) {
typedef typename vertex_subset_filter<Graph, Set>::type Filter;
is_in_subset<Set> p(s);
return Filter(g, keep_all(), p);
}
template <typename Graph, typename Set>
struct vertex_subset_compliment_filter {
typedef filtered_graph<Graph, keep_all, is_not_in_subset<Set> > type;
};
template <typename Graph, typename Set>
inline typename vertex_subset_compliment_filter<Graph, Set>::type
make_vertex_subset_compliment_filter(Graph& g, const Set& s) {
typedef typename vertex_subset_compliment_filter<Graph, Set>::type Filter;
is_not_in_subset<Set> p(s);
return Filter(g, keep_all(), p);
}
} // namespace boost
#endif // BOOST_FILTERED_GRAPH_HPP

View File

@@ -1,304 +0,0 @@
//=======================================================================
// Copyright 2002 Indiana University.
// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek
//
// This file is part of the Boost Graph Library
//
// You should have received a copy of the License Agreement for the
// Boost Graph Library along with the software; see the file LICENSE.
//
// Permission to modify the code and to distribute modified code is
// granted, provided the text of this NOTICE is retained, a notice that
// the code was modified is included with the above COPYRIGHT NOTICE and
// with the COPYRIGHT NOTICE in the LICENSE file, and that the LICENSE
// file is distributed with the modified code.
//
// LICENSOR MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED.
// By way of example, but not limitation, Licensor MAKES NO
// REPRESENTATIONS OR WARRANTIES OF MERCHANTABILITY OR FITNESS FOR ANY
// PARTICULAR PURPOSE OR THAT THE USE OF THE LICENSED SOFTWARE COMPONENTS
// OR DOCUMENTATION WILL NOT INFRINGE ANY PATENTS, COPYRIGHTS, TRADEMARKS
// OR OTHER RIGHTS.
//=======================================================================
#ifndef BOOST_GRAPH_ARCHETYPES_HPP
#define BOOST_GRAPH_ARCHETYPES_HPP
#include <boost/property_map.hpp>
#include <boost/concept_archetype.hpp>
namespace boost { // should use a different namespace for this
namespace detail {
struct null_graph_archetype : public null_archetype<> {
struct traversal_category { };
};
}
//===========================================================================
template <typename Vertex, typename Directed, typename ParallelCategory,
typename Base = detail::null_graph_archetype >
struct incidence_graph_archetype : public Base
{
typedef typename Base::traversal_category base_trav_cat;
struct traversal_category
: public incidence_graph_tag, public base_trav_cat { };
#if 0
typedef immutable_graph_tag mutability_category;
#endif
typedef Vertex vertex_descriptor;
typedef unsigned int degree_size_type;
typedef unsigned int vertices_size_type;
typedef unsigned int edges_size_type;
struct edge_descriptor {
edge_descriptor() { }
edge_descriptor(const detail::dummy_constructor&) { }
bool operator==(const edge_descriptor&) const { return false; }
bool operator!=(const edge_descriptor&) const { return false; }
};
typedef input_iterator_archetype<edge_descriptor> out_edge_iterator;
typedef Directed directed_category;
typedef ParallelCategory edge_parallel_category;
typedef void adjacency_iterator;
typedef void in_edge_iterator;
typedef void vertex_iterator;
typedef void edge_iterator;
};
template <typename V, typename D, typename P, typename B>
V source(const typename incidence_graph_archetype<V,D,P,B>::edge_descriptor&,
const incidence_graph_archetype<V,D,P,B>& )
{
return V(static_object<detail::dummy_constructor>::get());
}
template <typename V, typename D, typename P, typename B>
V target(const typename incidence_graph_archetype<V,D,P,B>::edge_descriptor&,
const incidence_graph_archetype<V,D,P,B>& )
{
return V(static_object<detail::dummy_constructor>::get());
}
template <typename V, typename D, typename P, typename B>
std::pair<typename incidence_graph_archetype<V,D,P,B>::out_edge_iterator,
typename incidence_graph_archetype<V,D,P,B>::out_edge_iterator>
out_edges(const V&, const incidence_graph_archetype<V,D,P,B>& )
{
typedef typename incidence_graph_archetype<V,D,P,B>::out_edge_iterator Iter;
return std::make_pair(Iter(), Iter());
}
template <typename V, typename D, typename P, typename B>
typename incidence_graph_archetype<V,D,P,B>::degree_size_type
out_degree(const V&, const incidence_graph_archetype<V,D,P,B>& )
{
return 0;
}
//===========================================================================
template <typename Vertex, typename Directed, typename ParallelCategory,
typename Base = detail::null_graph_archetype >
struct adjacency_graph_archetype : public Base
{
typedef typename Base::traversal_category base_trav_cat;
struct traversal_category
: public adjacency_graph_tag, public base_trav_cat { };
typedef Vertex vertex_descriptor;
typedef unsigned int degree_size_type;
typedef unsigned int vertices_size_type;
typedef unsigned int edges_size_type;
typedef void edge_descriptor;
typedef input_iterator_archetype<Vertex> adjacency_iterator;
typedef Directed directed_category;
typedef ParallelCategory edge_parallel_category;
typedef void in_edge_iterator;
typedef void out_edge_iterator;
typedef void vertex_iterator;
typedef void edge_iterator;
};
template <typename V, typename D, typename P, typename B>
std::pair<typename adjacency_graph_archetype<V,D,P,B>::adjacency_iterator,
typename adjacency_graph_archetype<V,D,P,B>::adjacency_iterator>
adjacent_vertices(const V&, const adjacency_graph_archetype<V,D,P,B>& )
{
typedef typename adjacency_graph_archetype<V,D,P,B>::adjacency_iterator Iter;
return std::make_pair(Iter(), Iter());
}
template <typename V, typename D, typename P, typename B>
typename adjacency_graph_archetype<V,D,P,B>::degree_size_type
out_degree(const V&, const adjacency_graph_archetype<V,D,P,B>& )
{
return 0;
}
//===========================================================================
template <typename Vertex, typename Directed, typename ParallelCategory,
typename Base = detail::null_graph_archetype >
struct vertex_list_graph_archetype : public Base
{
typedef incidence_graph_archetype<Vertex, Directed, ParallelCategory>
Incidence;
typedef adjacency_graph_archetype<Vertex, Directed, ParallelCategory>
Adjacency;
typedef typename Base::traversal_category base_trav_cat;
struct traversal_category
: public vertex_list_graph_tag, public base_trav_cat { };
#if 0
typedef immutable_graph_tag mutability_category;
#endif
typedef Vertex vertex_descriptor;
typedef unsigned int degree_size_type;
typedef typename Incidence::edge_descriptor edge_descriptor;
typedef typename Incidence::out_edge_iterator out_edge_iterator;
typedef typename Adjacency::adjacency_iterator adjacency_iterator;
typedef input_iterator_archetype<Vertex> vertex_iterator;
typedef unsigned int vertices_size_type;
typedef unsigned int edges_size_type;
typedef Directed directed_category;
typedef ParallelCategory edge_parallel_category;
typedef void in_edge_iterator;
typedef void edge_iterator;
};
template <typename V, typename D, typename P, typename B>
std::pair<typename vertex_list_graph_archetype<V,D,P,B>::vertex_iterator,
typename vertex_list_graph_archetype<V,D,P,B>::vertex_iterator>
vertices(const vertex_list_graph_archetype<V,D,P,B>& )
{
typedef typename vertex_list_graph_archetype<V,D,P,B>::vertex_iterator Iter;
return std::make_pair(Iter(), Iter());
}
template <typename V, typename D, typename P, typename B>
typename vertex_list_graph_archetype<V,D,P,B>::vertices_size_type
num_vertices(const vertex_list_graph_archetype<V,D,P,B>& )
{
return 0;
}
// ambiguously inherited from incidence graph and adjacency graph
template <typename V, typename D, typename P, typename B>
typename vertex_list_graph_archetype<V,D,P,B>::degree_size_type
out_degree(const V&, const vertex_list_graph_archetype<V,D,P,B>& )
{
return 0;
}
//===========================================================================
struct property_graph_archetype_tag { };
template <typename GraphArchetype, typename Property, typename ValueArch>
struct property_graph_archetype : public GraphArchetype
{
typedef property_graph_archetype_tag graph_tag;
typedef ValueArch vertex_property_type;
typedef ValueArch edge_property_type;
};
struct choose_edge_property_map_archetype {
template <typename Graph, typename Property, typename Tag>
struct bind_ {
typedef mutable_lvalue_property_map_archetype
<typename Graph::edge_descriptor, Property> type;
typedef lvalue_property_map_archetype
<typename Graph::edge_descriptor, Property> const_type;
};
};
template <>
struct edge_property_selector<property_graph_archetype_tag> {
typedef choose_edge_property_map_archetype type;
};
struct choose_vertex_property_map_archetype {
template <typename Graph, typename Property, typename Tag>
struct bind_ {
typedef mutable_lvalue_property_map_archetype
<typename Graph::vertex_descriptor, Property> type;
typedef lvalue_property_map_archetype
<typename Graph::vertex_descriptor, Property> const_type;
};
};
template <>
struct vertex_property_selector<property_graph_archetype_tag> {
typedef choose_vertex_property_map_archetype type;
};
template <typename G, typename P, typename V>
typename property_map<property_graph_archetype<G, P, V>, P>::type
get(P, property_graph_archetype<G, P, V>&) {
typename property_map<property_graph_archetype<G, P, V>, P>::type pmap;
return pmap;
}
template <typename G, typename P, typename V>
typename property_map<property_graph_archetype<G, P, V>, P>::const_type
get(P, const property_graph_archetype<G, P, V>&) {
typename property_map<property_graph_archetype<G, P, V>, P>::const_type pmap;
return pmap;
}
template <typename G, typename P, typename K, typename V>
typename property_traits<typename property_map<property_graph_archetype<G, P, V>, P>::const_type>::value_type
get(P p, const property_graph_archetype<G, P, V>& g, K k) {
return get( get(p, g), k);
}
template <typename G, typename P, typename V, typename Key>
void
put(P p, property_graph_archetype<G, P, V>& g,
const Key& key, const V& value)
{
typedef typename boost::property_map<property_graph_archetype<G, P, V>, P>::type Map;
Map pmap = get(p, g);
put(pmap, key, value);
}
struct color_value_archetype {
color_value_archetype() { }
color_value_archetype(detail::dummy_constructor) { }
bool operator==(const color_value_archetype& ) const { return true; }
bool operator!=(const color_value_archetype& ) const { return true; }
};
template <>
struct color_traits<color_value_archetype> {
static color_value_archetype white()
{
return color_value_archetype
(static_object<detail::dummy_constructor>::get());
}
static color_value_archetype gray()
{
return color_value_archetype
(static_object<detail::dummy_constructor>::get());
}
static color_value_archetype black()
{
return color_value_archetype
(static_object<detail::dummy_constructor>::get());
}
};
template <typename T>
class buffer_archetype {
public:
void push(const T&) {}
void pop() {}
T& top() { return static_object<T>::get(); }
const T& top() const { return static_object<T>::get(); }
bool empty() const { return true; }
};
} // namespace boost
#endif // BOOST_GRAPH_ARCHETYPES_HPP

View File

@@ -1,170 +0,0 @@
//
//=======================================================================
// Copyright 1997, 1998, 1999, 2000 University of Notre Dame.
// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek
//
// This file is part of the Boost Graph Library
//
// You should have received a copy of the License Agreement for the
// Boost Graph Library along with the software; see the file LICENSE.
// If not, contact Office of Research, University of Notre Dame, Notre
// Dame, IN 46556.
//
// Permission to modify the code and to distribute modified code is
// granted, provided the text of this NOTICE is retained, a notice that
// the code was modified is included with the above COPYRIGHT NOTICE and
// with the COPYRIGHT NOTICE in the LICENSE file, and that the LICENSE
// file is distributed with the modified code.
//
// LICENSOR MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED.
// By way of example, but not limitation, Licensor MAKES NO
// REPRESENTATIONS OR WARRANTIES OF MERCHANTABILITY OR FITNESS FOR ANY
// PARTICULAR PURPOSE OR THAT THE USE OF THE LICENSED SOFTWARE COMPONENTS
// OR DOCUMENTATION WILL NOT INFRINGE ANY PATENTS, COPYRIGHTS, TRADEMARKS
// OR OTHER RIGHTS.
//=======================================================================
//
#ifndef BOOST_GRAPH_GRAPH_AS_TREE_HPP
#define BOOST_GRAPH_GRAPH_AS_TREE_HPP
#include <vector>
#include <boost/config.hpp>
#include <boost/property_map.hpp>
#include <boost/graph/tree_traits.hpp>
#include <boost/graph/graph_traits.hpp>
#include <boost/graph/breadth_first_search.hpp>
#include <boost/graph/visitors.hpp>
namespace boost {
template <class Graph, class Node, class ChIt, class Derived>
class graph_as_tree_base
{
typedef Derived Tree;
public:
typedef Node node_descriptor;
typedef ChIt children_iterator;
graph_as_tree_base(Graph& g, Node root) : _g(g), _root(root) { }
friend Node root(const Tree& t) { return t._root; }
template <class N>
friend std::pair<ChIt,ChIt>
children(N n, const Tree& t) { return adjacent_vertices(n, t._g); }
template<class N>
friend Node parent(N n, const Tree& t) {
return boost::get(t.parent_pa(), n);
}
Graph& _g;
Node _root;
};
struct graph_as_tree_tag { };
template <class Graph, class ParentMap
, class Node
#if !defined BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
= typename graph_traits<Graph>::vertex_descriptor
#endif
, class ChIt
#if !defined BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
= typename graph_traits<Graph>::adjacency_iterator
#endif
>
class graph_as_tree
: public graph_as_tree_base<Graph, Node, ChIt,
graph_as_tree<Graph,ParentMap,Node,ChIt> >
{
typedef graph_as_tree self;
typedef graph_as_tree_base<Graph, Node, ChIt, self> super;
public:
graph_as_tree(Graph& g, Node root) : super(g, root) { }
graph_as_tree(Graph& g, Node root, ParentMap p) : super(g, root), _p(p) {
breadth_first_search(g, root,
visitor(make_bfs_visitor
(record_predecessors(p, boost::on_tree_edge()))));
}
ParentMap parent_pa() const { return _p; }
typedef graph_as_tree_tag graph_tag; // for property_map
protected:
ParentMap _p;
};
namespace detail {
struct graph_as_tree_vertex_property_selector {
template <typename GraphAsTree, typename Property, typename Tag>
struct bind_ {
typedef typename GraphAsTree::base_type Graph;
typedef property_map<Graph, Tag> PMap;
typedef typename PMap::type type;
typedef typename PMap::const_type const_type;
};
};
struct graph_as_tree_edge_property_selector {
template <typename GraphAsTree, typename Property, typename Tag>
struct bind_ {
typedef typename GraphAsTree::base_type Graph;
typedef property_map<Graph, Tag> PMap;
typedef typename PMap::type type;
typedef typename PMap::const_type const_type;
};
};
} // namespace detail
template <>
struct vertex_property_selector<graph_as_tree_tag> {
typedef detail::graph_as_tree_vertex_property_selector type;
};
template <>
struct edge_property_selector<graph_as_tree_tag> {
typedef detail::graph_as_tree_edge_property_selector type;
};
template <typename Graph, typename P, typename N, typename C,
typename Property>
typename property_map<Graph, Property>::type
get(Property p, graph_as_tree<Graph,P,N,C>& g)
{
return get(p, g._g);
}
template <typename Graph, typename P, typename N, typename C,
typename Property>
typename property_map<Graph, Property>::const_type
get(Property p, const graph_as_tree<Graph,P,N,C>& g)
{
const Graph& gref = g._g; // in case GRef is non-const
return get(p, gref);
}
template <typename Graph, typename P, typename N, typename C,
typename Property, typename Key>
typename property_traits<
typename property_map<Graph, Property>::const_type
>::value_type
get(Property p, const graph_as_tree<Graph,P,N,C>& g, const Key& k)
{
return get(p, g._g, k);
}
template <typename Graph, typename P, typename N, typename C,
typename Property, typename Key, typename Value>
void
put(Property p, const graph_as_tree<Graph,P,N,C>& g, const Key& k,
const Value& val)
{
put(p, g._g, k, val);
}
} // namespace boost
#endif // BOOST_GRAPH_GRAPH_AS_TREE_HPP

View File

@@ -1,508 +0,0 @@
//
//=======================================================================
// Copyright 1997, 1998, 1999, 2000 University of Notre Dame.
// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek
//
// This file is part of the Boost Graph Library
//
// You should have received a copy of the License Agreement for the
// Boost Graph Library along with the software; see the file LICENSE.
// If not, contact Office of Research, University of Notre Dame, Notre
// Dame, IN 46556.
//
// Permission to modify the code and to distribute modified code is
// granted, provided the text of this NOTICE is retained, a notice that
// the code was modified is included with the above COPYRIGHT NOTICE and
// with the COPYRIGHT NOTICE in the LICENSE file, and that the LICENSE
// file is distributed with the modified code.
//
// LICENSOR MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED.
// By way of example, but not limitation, Licensor MAKES NO
// REPRESENTATIONS OR WARRANTIES OF MERCHANTABILITY OR FITNESS FOR ANY
// PARTICULAR PURPOSE OR THAT THE USE OF THE LICENSED SOFTWARE COMPONENTS
// OR DOCUMENTATION WILL NOT INFRINGE ANY PATENTS, COPYRIGHTS, TRADEMARKS
// OR OTHER RIGHTS.
//=======================================================================
//
#ifndef BOOST_GRAPH_CONCEPTS_HPP
#define BOOST_GRAPH_CONCEPTS_HPP
#include <boost/config.hpp>
#include <boost/graph/graph_traits.hpp>
#include <boost/property_map.hpp>
#include <boost/graph/properties.hpp>
#include <boost/concept_check.hpp>
#include <boost/detail/workaround.hpp>
namespace boost {
template <class T>
struct MultiPassInputIteratorConcept {
void constraints() {
function_requires< InputIteratorConcept<T> >();
}
};
template <class G>
struct GraphConcept
{
typedef typename graph_traits<G>::vertex_descriptor vertex_descriptor;
typedef typename graph_traits<G>::directed_category directed_category;
typedef typename graph_traits<G>::edge_parallel_category
edge_parallel_category;
typedef typename graph_traits<G>::traversal_category
traversal_category;
void constraints() {
function_requires< DefaultConstructibleConcept<vertex_descriptor> >();
function_requires< EqualityComparableConcept<vertex_descriptor> >();
function_requires< AssignableConcept<vertex_descriptor> >();
}
G g;
};
template <class G>
struct IncidenceGraphConcept
{
typedef typename graph_traits<G>::edge_descriptor edge_descriptor;
typedef typename graph_traits<G>::out_edge_iterator
out_edge_iterator;
typedef typename graph_traits<G>::traversal_category
traversal_category;
void constraints() {
function_requires< GraphConcept<G> >();
function_requires< MultiPassInputIteratorConcept<out_edge_iterator> >();
function_requires< DefaultConstructibleConcept<edge_descriptor> >();
function_requires< EqualityComparableConcept<edge_descriptor> >();
function_requires< AssignableConcept<edge_descriptor> >();
function_requires< ConvertibleConcept<traversal_category,
incidence_graph_tag> >();
p = out_edges(v, g);
n = out_degree(v, g);
e = *p.first;
u = source(e, g);
v = target(e, g);
const_constraints(g);
}
void const_constraints(const G& g) {
p = out_edges(v, g);
n = out_degree(v, g);
e = *p.first;
u = source(e, g);
v = target(e, g);
}
std::pair<out_edge_iterator, out_edge_iterator> p;
typename graph_traits<G>::vertex_descriptor u, v;
typename graph_traits<G>::edge_descriptor e;
typename graph_traits<G>::degree_size_type n;
G g;
};
template <class G>
struct BidirectionalGraphConcept
{
typedef typename graph_traits<G>::in_edge_iterator
in_edge_iterator;
typedef typename graph_traits<G>::traversal_category
traversal_category;
void constraints() {
function_requires< IncidenceGraphConcept<G> >();
function_requires< MultiPassInputIteratorConcept<in_edge_iterator> >();
function_requires< ConvertibleConcept<traversal_category,
bidirectional_graph_tag> >();
p = in_edges(v, g);
n = in_degree(v, g);
e = *p.first;
const_constraints(g);
}
void const_constraints(const G& g) {
p = in_edges(v, g);
n = in_degree(v, g);
e = *p.first;
}
std::pair<in_edge_iterator, in_edge_iterator> p;
typename graph_traits<G>::vertex_descriptor v;
typename graph_traits<G>::edge_descriptor e;
typename graph_traits<G>::degree_size_type n;
G g;
};
template <class G>
struct AdjacencyGraphConcept
{
typedef typename graph_traits<G>::adjacency_iterator
adjacency_iterator;
typedef typename graph_traits<G>::traversal_category
traversal_category;
void constraints() {
function_requires< GraphConcept<G> >();
function_requires< MultiPassInputIteratorConcept<adjacency_iterator> >();
function_requires< ConvertibleConcept<traversal_category,
adjacency_graph_tag> >();
p = adjacent_vertices(v, g);
v = *p.first;
const_constraints(g);
}
void const_constraints(const G& g) {
p = adjacent_vertices(v, g);
}
std::pair<adjacency_iterator,adjacency_iterator> p;
typename graph_traits<G>::vertex_descriptor v;
G g;
};
// dwa 2003/7/11 -- This clearly shouldn't be neccessary, but if
// you want to use vector_as_graph, it is! I'm sure the graph
// library leaves these out all over the place. Probably a
// redesign involving specializing a template with a static
// member function is in order :(
//
// It is needed in order to allow us to write using boost::vertices as
// needed for ADL when using vector_as_graph below.
#if !defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP) \
&& !BOOST_WORKAROUND(__GNUC__, <= 2) \
&& !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
# define BOOST_VECTOR_AS_GRAPH_GRAPH_ADL_HACK
#endif
#ifdef BOOST_VECTOR_AS_GRAPH_GRAPH_ADL_HACK
template <class T>
typename T::ThereReallyIsNoMemberByThisNameInT vertices(T const&);
#endif
template <class G>
struct VertexListGraphConcept
{
typedef typename graph_traits<G>::vertex_iterator vertex_iterator;
typedef typename graph_traits<G>::vertices_size_type vertices_size_type;
typedef typename graph_traits<G>::traversal_category
traversal_category;
void constraints() {
function_requires< GraphConcept<G> >();
function_requires< MultiPassInputIteratorConcept<vertex_iterator> >();
function_requires< ConvertibleConcept<traversal_category,
vertex_list_graph_tag> >();
#ifdef BOOST_VECTOR_AS_GRAPH_GRAPH_ADL_HACK
// dwa 2003/7/11 -- This clearly shouldn't be neccessary, but if
// you want to use vector_as_graph, it is! I'm sure the graph
// library leaves these out all over the place. Probably a
// redesign involving specializing a template with a static
// member function is in order :(
using boost::vertices;
#endif
p = vertices(g);
v = *p.first;
const_constraints(g);
}
void const_constraints(const G& g) {
#ifdef BOOST_VECTOR_AS_GRAPH_GRAPH_ADL_HACK
// dwa 2003/7/11 -- This clearly shouldn't be neccessary, but if
// you want to use vector_as_graph, it is! I'm sure the graph
// library leaves these out all over the place. Probably a
// redesign involving specializing a template with a static
// member function is in order :(
using boost::vertices;
#endif
p = vertices(g);
v = *p.first;
V = num_vertices(g);
}
std::pair<vertex_iterator,vertex_iterator> p;
typename graph_traits<G>::vertex_descriptor v;
G g;
vertices_size_type V;
};
template <class G>
struct EdgeListGraphConcept
{
typedef typename graph_traits<G>::edge_descriptor edge_descriptor;
typedef typename graph_traits<G>::edge_iterator edge_iterator;
typedef typename graph_traits<G>::edges_size_type edges_size_type;
typedef typename graph_traits<G>::traversal_category
traversal_category;
void constraints() {
function_requires< GraphConcept<G> >();
function_requires< MultiPassInputIteratorConcept<edge_iterator> >();
function_requires< DefaultConstructibleConcept<edge_descriptor> >();
function_requires< EqualityComparableConcept<edge_descriptor> >();
function_requires< AssignableConcept<edge_descriptor> >();
function_requires< ConvertibleConcept<traversal_category,
edge_list_graph_tag> >();
p = edges(g);
e = *p.first;
u = source(e, g);
v = target(e, g);
const_constraints(g);
}
void const_constraints(const G& g) {
p = edges(g);
E = num_edges(g);
e = *p.first;
u = source(e, g);
v = target(e, g);
}
std::pair<edge_iterator,edge_iterator> p;
typename graph_traits<G>::vertex_descriptor u, v;
typename graph_traits<G>::edge_descriptor e;
edges_size_type E;
G g;
};
template <class G>
struct VertexAndEdgeListGraphConcept
{
void constraints() {
function_requires< VertexListGraphConcept<G> >();
function_requires< EdgeListGraphConcept<G> >();
}
};
// Where to put the requirement for this constructor?
// G g(n_vertices);
// Not in mutable graph, then LEDA graph's can't be models of
// MutableGraph.
template <class G>
struct EdgeMutableGraphConcept
{
typedef typename graph_traits<G>::edge_descriptor edge_descriptor;
void constraints() {
p = add_edge(u, v, g);
remove_edge(u, v, g);
remove_edge(e, g);
clear_vertex(v, g);
}
G g;
edge_descriptor e;
std::pair<edge_descriptor, bool> p;
typename graph_traits<G>::vertex_descriptor u, v;
};
template <class G>
struct VertexMutableGraphConcept
{
void constraints() {
v = add_vertex(g);
remove_vertex(v, g);
}
G g;
typename graph_traits<G>::vertex_descriptor u, v;
};
template <class G>
struct MutableGraphConcept
{
void constraints() {
function_requires< EdgeMutableGraphConcept<G> >();
function_requires< VertexMutableGraphConcept<G> >();
}
};
template <class edge_descriptor>
struct dummy_edge_predicate {
bool operator()(const edge_descriptor&) const {
return false;
}
};
template <class G>
struct MutableIncidenceGraphConcept
{
void constraints() {
function_requires< MutableGraphConcept<G> >();
remove_edge(iter, g);
remove_out_edge_if(u, p, g);
}
G g;
typedef typename graph_traits<G>::edge_descriptor edge_descriptor;
dummy_edge_predicate<edge_descriptor> p;
typename boost::graph_traits<G>::vertex_descriptor u;
typename boost::graph_traits<G>::out_edge_iterator iter;
};
template <class G>
struct MutableBidirectionalGraphConcept
{
void constraints() {
function_requires< MutableIncidenceGraphConcept<G> >();
remove_in_edge_if(u, p, g);
}
G g;
typedef typename graph_traits<G>::edge_descriptor edge_descriptor;
dummy_edge_predicate<edge_descriptor> p;
typename boost::graph_traits<G>::vertex_descriptor u;
};
template <class G>
struct MutableEdgeListGraphConcept
{
void constraints() {
function_requires< EdgeMutableGraphConcept<G> >();
remove_edge_if(p, g);
}
G g;
typedef typename graph_traits<G>::edge_descriptor edge_descriptor;
dummy_edge_predicate<edge_descriptor> p;
};
template <class G>
struct VertexMutablePropertyGraphConcept
{
void constraints() {
function_requires< VertexMutableGraphConcept<G> >();
v = add_vertex(vp, g);
}
G g;
typename graph_traits<G>::vertex_descriptor v;
typename vertex_property<G>::type vp;
};
template <class G>
struct EdgeMutablePropertyGraphConcept
{
typedef typename graph_traits<G>::edge_descriptor edge_descriptor;
void constraints() {
function_requires< EdgeMutableGraphConcept<G> >();
p = add_edge(u, v, ep, g);
}
G g;
std::pair<edge_descriptor, bool> p;
typename graph_traits<G>::vertex_descriptor u, v;
typename edge_property<G>::type ep;
};
template <class G>
struct AdjacencyMatrixConcept
{
typedef typename graph_traits<G>::edge_descriptor edge_descriptor;
void constraints() {
function_requires< GraphConcept<G> >();
p = edge(u, v, g);
const_constraints(g);
}
void const_constraints(const G& g) {
p = edge(u, v, g);
}
typename graph_traits<G>::vertex_descriptor u, v;
std::pair<edge_descriptor, bool> p;
G g;
};
template <class G, class X, class Property>
struct ReadablePropertyGraphConcept
{
typedef typename property_map<G, Property>::const_type const_Map;
void constraints() {
function_requires< GraphConcept<G> >();
function_requires< ReadablePropertyMapConcept<const_Map, X> >();
const_constraints(g);
}
void const_constraints(const G& g) {
const_Map pmap = get(Property(), g);
pval = get(Property(), g, x);
ignore_unused_variable_warning(pmap);
}
G g;
X x;
typename property_traits<const_Map>::value_type pval;
};
template <class G, class X, class Property>
struct PropertyGraphConcept
{
typedef typename property_map<G, Property>::type Map;
void constraints() {
function_requires< ReadablePropertyGraphConcept<G, X, Property> >();
function_requires< ReadWritePropertyMapConcept<Map, X> >();
Map pmap = get(Property(), g);
pval = get(Property(), g, x);
put(Property(), g, x, pval);
ignore_unused_variable_warning(pmap);
}
G g;
X x;
typename property_traits<Map>::value_type pval;
};
template <class G, class X, class Property>
struct LvaluePropertyGraphConcept
{
typedef typename property_map<G, Property>::type Map;
typedef typename property_map<G, Property>::const_type const_Map;
void constraints() {
function_requires< ReadablePropertyGraphConcept<G, X, Property> >();
function_requires< LvaluePropertyMapConcept<const_Map, X> >();
pval = get(Property(), g, x);
put(Property(), g, x, pval);
}
G g;
X x;
typename property_traits<Map>::value_type pval;
};
// This needs to move out of the graph library
template <class B>
struct BufferConcept
{
void constraints() {
b.push(t);
b.pop();
typename B::value_type& v = b.top();
const_constraints(b);
ignore_unused_variable_warning(v);
}
void const_constraints(const B& b) {
const typename B::value_type& v = b.top();
n = b.size();
bool e = b.empty();
ignore_unused_variable_warning(v);
ignore_unused_variable_warning(e);
}
typename B::size_type n;
typename B::value_type t;
B b;
};
template <class C>
struct ColorValueConcept
{
void constraints() {
function_requires< EqualityComparableConcept<C> >();
function_requires< DefaultConstructibleConcept<C> >();
c = color_traits<C>::white();
c = color_traits<C>::gray();
c = color_traits<C>::black();
}
C c;
};
template <class M, class I, class V>
struct BasicMatrixConcept
{
void constraints() {
V& elt = A[i][j];
const_constraints(A);
ignore_unused_variable_warning(elt);
}
void const_constraints(const M& A) {
const V& elt = A[i][j];
ignore_unused_variable_warning(elt);
}
M A;
I i, j;
};
} // namespace boost
#endif /* BOOST_GRAPH_CONCEPTS_H */

View File

@@ -1,50 +0,0 @@
//=======================================================================
// Copyright 2002 Indiana University.
// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek
//
// This file is part of the Boost Graph Library
//
// You should have received a copy of the License Agreement for the
// Boost Graph Library along with the software; see the file LICENSE.
//
// Permission to modify the code and to distribute modified code is
// granted, provided the text of this NOTICE is retained, a notice that
// the code was modified is included with the above COPYRIGHT NOTICE and
// with the COPYRIGHT NOTICE in the LICENSE file, and that the LICENSE
// file is distributed with the modified code.
//
// LICENSOR MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED.
// By way of example, but not limitation, Licensor MAKES NO
// REPRESENTATIONS OR WARRANTIES OF MERCHANTABILITY OR FITNESS FOR ANY
// PARTICULAR PURPOSE OR THAT THE USE OF THE LICENSED SOFTWARE COMPONENTS
// OR DOCUMENTATION WILL NOT INFRINGE ANY PATENTS, COPYRIGHTS, TRADEMARKS
// OR OTHER RIGHTS.
//=======================================================================
#ifndef BOOST_GRAPH_SELECTORS_HPP
#define BOOST_GRAPH_SELECTORS_HPP
namespace boost {
//===========================================================================
// Selectors for the Directed template parameter of adjacency_list
// and adjacency_matrix.
struct directedS { enum { is_directed = true, is_bidir = false };
typedef true_type is_directed_t;
typedef false_type is_bidir_t;
};
struct undirectedS {
enum { is_directed = false, is_bidir = false };
typedef false_type is_directed_t;
typedef false_type is_bidir_t;
};
struct bidirectionalS {
enum { is_directed = true, is_bidir = true };
typedef true_type is_directed_t;
typedef true_type is_bidir_t;
};
} // namespace boost
#endif // BOOST_GRAPH_SELECTORS_HPP

View File

@@ -1,396 +0,0 @@
//=======================================================================
// Copyright 2002 Indiana University.
// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek
//
// This file is part of the Boost Graph Library
//
// You should have received a copy of the License Agreement for the
// Boost Graph Library along with the software; see the file LICENSE.
//
// Permission to modify the code and to distribute modified code is
// granted, provided the text of this NOTICE is retained, a notice that
// the code was modified is included with the above COPYRIGHT NOTICE and
// with the COPYRIGHT NOTICE in the LICENSE file, and that the LICENSE
// file is distributed with the modified code.
//
// LICENSOR MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED.
// By way of example, but not limitation, Licensor MAKES NO
// REPRESENTATIONS OR WARRANTIES OF MERCHANTABILITY OR FITNESS FOR ANY
// PARTICULAR PURPOSE OR THAT THE USE OF THE LICENSED SOFTWARE COMPONENTS
// OR DOCUMENTATION WILL NOT INFRINGE ANY PATENTS, COPYRIGHTS, TRADEMARKS
// OR OTHER RIGHTS.
//=======================================================================
#ifndef BOOST_GRAPH_TEST_HPP
#define BOOST_GRAPH_TEST_HPP
#include <vector>
#include <boost/test/test_tools.hpp>
#include <boost/graph/filtered_graph.hpp>
#include <boost/graph/iteration_macros.hpp>
#include <boost/graph/isomorphism.hpp>
#include <boost/graph/copy.hpp>
#include <boost/graph/graph_utility.hpp> // for connects
// UNDER CONSTRUCTION
namespace boost {
template <typename Graph>
struct graph_test
{
typedef typename graph_traits<Graph>::vertex_descriptor vertex_t;
typedef typename graph_traits<Graph>::edge_descriptor edge_t;
typedef typename graph_traits<Graph>::vertices_size_type v_size_t;
typedef typename graph_traits<Graph>::degree_size_type deg_size_t;
typedef typename graph_traits<Graph>::edges_size_type e_size_t;
typedef typename graph_traits<Graph>::out_edge_iterator out_edge_iter;
typedef typename property_map<Graph, vertex_index_t>::type index_map_t;
typedef iterator_property_map<typename std::vector<vertex_t>::iterator,
index_map_t,vertex_t,vertex_t&> IsoMap;
struct ignore_vertex {
ignore_vertex() { }
ignore_vertex(vertex_t v) : v(v) { }
bool operator()(vertex_t x) const { return x != v; }
vertex_t v;
};
struct ignore_edge {
ignore_edge() { }
ignore_edge(edge_t e) : e(e) { }
bool operator()(edge_t x) const { return x != e; }
edge_t e;
};
struct ignore_edges {
ignore_edges(vertex_t s, vertex_t t, const Graph& g)
: s(s), t(t), g(g) { }
bool operator()(edge_t x) const {
return !(source(x, g) == s && target(x, g) == t);
}
vertex_t s; vertex_t t; const Graph& g;
};
//=========================================================================
// Traversal Operations
void test_incidence_graph
(const std::vector<vertex_t>& vertex_set,
const std::vector< std::pair<vertex_t, vertex_t> >& edge_set,
const Graph& g)
{
typedef typename std::vector<vertex_t>::const_iterator vertex_iter;
typedef typename std::vector< std::pair<vertex_t, vertex_t> >
::const_iterator edge_iter;
typedef typename graph_traits<Graph>::out_edge_iterator out_edge_iter;
for (vertex_iter ui = vertex_set.begin(); ui != vertex_set.end(); ++ui) {
vertex_t u = *ui;
std::vector<vertex_t> adj;
for (edge_iter e = edge_set.begin(); e != edge_set.end(); ++e)
if (e->first == u)
adj.push_back(e->second);
std::pair<out_edge_iter, out_edge_iter> p = out_edges(u, g);
BOOST_TEST(out_degree(u, g) == adj.size());
BOOST_TEST(deg_size_t(std::distance(p.first, p.second))
== out_degree(u, g));
for (; p.first != p.second; ++p.first) {
edge_t e = *p.first;
BOOST_TEST(source(e, g) == u);
BOOST_TEST(contains(adj, target(e, g)) == true);
}
}
}
void test_bidirectional_graph
(const std::vector<vertex_t>& vertex_set,
const std::vector< std::pair<vertex_t, vertex_t> >& edge_set,
const Graph& g)
{
typedef typename std::vector<vertex_t>::const_iterator vertex_iter;
typedef typename std::vector< std::pair<vertex_t, vertex_t> >
::const_iterator edge_iter;
typedef typename graph_traits<Graph>::in_edge_iterator in_edge_iter;
for (vertex_iter vi = vertex_set.begin(); vi != vertex_set.end(); ++vi) {
vertex_t v = *vi;
std::vector<vertex_t> inv_adj;
for (edge_iter e = edge_set.begin(); e != edge_set.end(); ++e)
if (e->second == v)
inv_adj.push_back(e->first);
std::pair<in_edge_iter, in_edge_iter> p = in_edges(v, g);
BOOST_TEST(in_degree(v, g) == inv_adj.size());
BOOST_TEST(deg_size_t(std::distance(p.first, p.second))
== in_degree(v, g));
for (; p.first != p.second; ++p.first) {
edge_t e = *p.first;
BOOST_TEST(target(e, g) == v);
BOOST_TEST(contains(inv_adj, source(e, g)) == true);
}
}
}
void test_adjacency_graph
(const std::vector<vertex_t>& vertex_set,
const std::vector< std::pair<vertex_t,vertex_t> >& edge_set,
const Graph& g)
{
typedef typename std::vector<vertex_t>::const_iterator vertex_iter;
typedef typename std::vector<std::pair<vertex_t,vertex_t> >
::const_iterator edge_iter;
typedef typename graph_traits<Graph>::adjacency_iterator adj_iter;
for (vertex_iter ui = vertex_set.begin(); ui != vertex_set.end(); ++ui) {
vertex_t u = *ui;
std::vector<vertex_t> adj;
for (edge_iter e = edge_set.begin(); e != edge_set.end(); ++e)
if (e->first == u)
adj.push_back(e->second);
std::pair<adj_iter, adj_iter> p = adjacent_vertices(u, g);
BOOST_TEST(deg_size_t(std::distance(p.first, p.second)) == adj.size());
for (; p.first != p.second; ++p.first) {
vertex_t v = *p.first;
BOOST_TEST(contains(adj, v) == true);
}
}
}
void test_vertex_list_graph
(const std::vector<vertex_t>& vertex_set, const Graph& g)
{
typedef typename graph_traits<Graph>::vertex_iterator v_iter;
std::pair<v_iter, v_iter> p = vertices(g);
BOOST_TEST(num_vertices(g) == vertex_set.size());
v_size_t n = std::distance(p.first, p.second);
BOOST_TEST(n == num_vertices(g));
for (; p.first != p.second; ++p.first) {
vertex_t v = *p.first;
BOOST_TEST(contains(vertex_set, v) == true);
}
}
void test_edge_list_graph
(const std::vector<vertex_t>& vertex_set,
const std::vector< std::pair<vertex_t, vertex_t> >& edge_set,
const Graph& g)
{
typedef typename graph_traits<Graph>::edge_iterator e_iter;
std::pair<e_iter, e_iter> p = edges(g);
BOOST_TEST(num_edges(g) == edge_set.size());
e_size_t m = std::distance(p.first, p.second);
BOOST_TEST(m == num_edges(g));
for (; p.first != p.second; ++p.first) {
edge_t e = *p.first;
BOOST_TEST(any_if(edge_set, connects(source(e, g), target(e, g), g)));
BOOST_TEST(contains(vertex_set, source(e, g)) == true);
BOOST_TEST(contains(vertex_set, target(e, g)) == true);
}
}
void test_adjacency_matrix
(const std::vector<vertex_t>& vertex_set,
const std::vector< std::pair<vertex_t, vertex_t> >& edge_set,
const Graph& g)
{
std::pair<edge_t, bool> p;
for (typename std::vector<std::pair<vertex_t, vertex_t> >
::const_iterator i = edge_set.begin();
i != edge_set.end(); ++i) {
p = edge(i->first, i->second, g);
BOOST_TEST(p.second == true);
BOOST_TEST(source(p.first, g) == i->first);
BOOST_TEST(target(p.first, g) == i->second);
}
typename std::vector<vertex_t>::const_iterator j, k;
for (j = vertex_set.begin(); j != vertex_set.end(); ++j)
for (k = vertex_set.begin(); k != vertex_set.end(); ++k) {
p = edge(*j, *k, g);
if (p.second == true)
BOOST_TEST(any_if(edge_set,
connects(source(p.first, g), target(p.first, g), g)) == true);
}
}
//=========================================================================
// Mutating Operations
void test_add_vertex(Graph& g)
{
Graph cpy;
std::vector<vertex_t> iso_vec(num_vertices(g));
IsoMap iso_map(iso_vec.begin(), get(vertex_index, g));
copy_graph(g, cpy, orig_to_copy(iso_map));
assert((verify_isomorphism(g, cpy, iso_map)));
vertex_t v = add_vertex(g);
BOOST_TEST(num_vertices(g) == num_vertices(cpy) + 1);
BOOST_TEST(out_degree(v, g) == 0);
// Make sure the rest of the graph stayed the same
BOOST_TEST((verify_isomorphism
(make_filtered_graph(g, keep_all(), ignore_vertex(v)), cpy,
iso_map)));
}
void test_add_edge(vertex_t u, vertex_t v, Graph& g)
{
Graph cpy;
std::vector<vertex_t> iso_vec(num_vertices(g));
IsoMap iso_map(iso_vec.begin(), get(vertex_index, g));
copy_graph(g, cpy, orig_to_copy(iso_map));
bool parallel_edge_exists = contains(adjacent_vertices(u, g), v);
std::pair<edge_t, bool> p = add_edge(u, v, g);
edge_t e = p.first;
bool added = p.second;
if (is_undirected(g) && u == v) // self edge
BOOST_TEST(added == false);
else if (parallel_edge_exists)
BOOST_TEST(allows_parallel_edges(g) && added == true
|| !allows_parallel_edges(g) && added == false);
else
BOOST_TEST(added == true);
if (p.second == true) { // edge added
BOOST_TEST(num_edges(g) == num_edges(cpy) + 1);
BOOST_TEST(contains(out_edges(u, g), e) == true);
BOOST_TEST((verify_isomorphism
(make_filtered_graph(g, ignore_edge(e)), cpy, iso_map)));
}
else { // edge not added
if (! (is_undirected(g) && u == v)) {
// e should be a parallel edge
BOOST_TEST(source(e, g) == u);
BOOST_TEST(target(e, g) == v);
}
// The graph should not be changed.
BOOST_TEST((verify_isomorphism(g, cpy, iso_map)));
}
} // test_add_edge()
void test_remove_edge(vertex_t u, vertex_t v, Graph& g)
{
Graph cpy;
std::vector<vertex_t> iso_vec(num_vertices(g));
IsoMap iso_map(iso_vec.begin(), get(vertex_index, g));
copy_graph(g, cpy, orig_to_copy(iso_map));
deg_size_t occurances = count(adjacent_vertices(u, g), v);
remove_edge(u, v, g);
BOOST_TEST(num_edges(g) + occurances == num_edges(cpy));
BOOST_TEST((verify_isomorphism
(g, make_filtered_graph(cpy, ignore_edges(u,v,cpy)),
iso_map)));
}
void test_remove_edge(edge_t e, Graph& g)
{
Graph cpy;
std::vector<vertex_t> iso_vec(num_vertices(g));
IsoMap iso_map(iso_vec.begin(), get(vertex_index, g));
copy_graph(g, cpy, orig_to_copy(iso_map));
vertex_t u = source(e, g), v = target(e, g);
deg_size_t occurances = count(adjacent_vertices(u, g), v);
remove_edge(e, g);
BOOST_TEST(num_edges(g) + 1 == num_edges(cpy));
BOOST_TEST(count(adjacent_vertices(u, g), v) + 1 == occurances);
BOOST_TEST((verify_isomorphism
(g, make_filtered_graph(cpy, ignore_edge(e)),
iso_map)));
}
void test_clear_vertex(vertex_t v, Graph& g)
{
Graph cpy;
std::vector<vertex_t> iso_vec(num_vertices(g));
IsoMap iso_map(iso_vec.begin(), get(vertex_index, g));
copy_graph(g, cpy, orig_to_copy(iso_map));
clear_vertex(v, g);
BOOST_TEST(out_degree(v, g) == 0);
BOOST_TEST(num_vertices(g) == num_vertices(cpy));
BOOST_TEST((verify_isomorphism
(g, make_filtered_graph(cpy, keep_all(), ignore_vertex(v)),
iso_map)));
}
//=========================================================================
// Property Map
template <typename PropVal, typename PropertyTag>
void test_readable_vertex_property_graph
(const std::vector<PropVal>& vertex_prop, PropertyTag, const Graph& g)
{
typedef typename property_map<Graph, PropertyTag>::const_type const_Map;
const_Map pmap = get(PropertyTag(), g);
typename std::vector<PropVal>::const_iterator i = vertex_prop.begin();
for (typename boost::graph_traits<Graph>::vertex_iterator
bgl_first_9 = vertices(g).first, bgl_last_9 = vertices(g).second;
bgl_first_9 != bgl_last_9; bgl_first_9 = bgl_last_9)
for (typename boost::graph_traits<Graph>::vertex_descriptor v;
bgl_first_9 != bgl_last_9 ? (v = *bgl_first_9, true) : false;
++bgl_first_9) {
//BGL_FORALL_VERTICES_T(v, g, Graph) {
typename property_traits<const_Map>::value_type
pval1 = get(pmap, v), pval2 = get(PropertyTag(), g, v);
BOOST_TEST(pval1 == pval2);
BOOST_TEST(pval1 == *i++);
}
}
template <typename PropVal, typename PropertyTag>
void test_vertex_property_graph
(const std::vector<PropVal>& vertex_prop, PropertyTag tag, Graph& g)
{
typedef typename property_map<Graph, PropertyTag>::type PMap;
PMap pmap = get(PropertyTag(), g);
typename std::vector<PropVal>::const_iterator i = vertex_prop.begin();
for (typename boost::graph_traits<Graph>::vertex_iterator
bgl_first_9 = vertices(g).first, bgl_last_9 = vertices(g).second;
bgl_first_9 != bgl_last_9; bgl_first_9 = bgl_last_9)
for (typename boost::graph_traits<Graph>::vertex_descriptor v;
bgl_first_9 != bgl_last_9 ? (v = *bgl_first_9, true) : false;
++bgl_first_9)
// BGL_FORALL_VERTICES_T(v, g, Graph)
put(pmap, v, *i++);
test_readable_vertex_property_graph(vertex_prop, tag, g);
BGL_FORALL_VERTICES_T(v, g, Graph)
put(pmap, v, vertex_prop[0]);
typename std::vector<PropVal>::const_iterator j = vertex_prop.begin();
BGL_FORALL_VERTICES_T(v, g, Graph)
put(PropertyTag(), g, v, *j++);
test_readable_vertex_property_graph(vertex_prop, tag, g);
}
};
} // namespace boost
#include <boost/graph/iteration_macros_undef.hpp>
#endif // BOOST_GRAPH_TEST_HPP

View File

@@ -1,155 +0,0 @@
//=======================================================================
// Copyright 1997, 1998, 1999, 2000 University of Notre Dame.
// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek
//
// This file is part of the Boost Graph Library
//
// You should have received a copy of the License Agreement for the
// Boost Graph Library along with the software; see the file LICENSE.
// If not, contact Office of Research, University of Notre Dame, Notre
// Dame, IN 46556.
//
// Permission to modify the code and to distribute modified code is
// granted, provided the text of this NOTICE is retained, a notice that
// the code was modified is included with the above COPYRIGHT NOTICE and
// with the COPYRIGHT NOTICE in the LICENSE file, and that the LICENSE
// file is distributed with the modified code.
//
// LICENSOR MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED.
// By way of example, but not limitation, Licensor MAKES NO
// REPRESENTATIONS OR WARRANTIES OF MERCHANTABILITY OR FITNESS FOR ANY
// PARTICULAR PURPOSE OR THAT THE USE OF THE LICENSED SOFTWARE COMPONENTS
// OR DOCUMENTATION WILL NOT INFRINGE ANY PATENTS, COPYRIGHTS, TRADEMARKS
// OR OTHER RIGHTS.
//=======================================================================
#ifndef BOOST_GRAPH_TRAITS_HPP
#define BOOST_GRAPH_TRAITS_HPP
#include <boost/config.hpp>
#include <iterator>
#include <boost/tuple/tuple.hpp>
#include <boost/pending/ct_if.hpp>
#include <boost/iterator/iterator_categories.hpp>
#include <boost/iterator/iterator_adaptor.hpp>
#include <boost/detail/workaround.hpp>
namespace boost {
template <typename G>
struct graph_traits {
typedef typename G::vertex_descriptor vertex_descriptor;
typedef typename G::edge_descriptor edge_descriptor;
typedef typename G::adjacency_iterator adjacency_iterator;
typedef typename G::out_edge_iterator out_edge_iterator;
typedef typename G::in_edge_iterator in_edge_iterator;
typedef typename G::vertex_iterator vertex_iterator;
typedef typename G::edge_iterator edge_iterator;
typedef typename G::directed_category directed_category;
typedef typename G::edge_parallel_category edge_parallel_category;
typedef typename G::traversal_category traversal_category;
typedef typename G::vertices_size_type vertices_size_type;
typedef typename G::edges_size_type edges_size_type;
typedef typename G::degree_size_type degree_size_type;
static inline vertex_descriptor null_vertex();
};
template <typename G>
inline typename graph_traits<G>::vertex_descriptor
graph_traits<G>::null_vertex()
{
return G::null_vertex();
}
// directed_category tags
struct directed_tag { };
struct undirected_tag { };
struct bidirectional_tag : public directed_tag { };
namespace detail {
inline bool is_directed(directed_tag) { return true; }
inline bool is_directed(undirected_tag) { return false; }
}
template <typename Graph>
bool is_directed(const Graph&) {
typedef typename graph_traits<Graph>::directed_category Cat;
return detail::is_directed(Cat());
}
template <typename Graph>
bool is_undirected(const Graph& g) {
return ! is_directed(g);
}
// edge_parallel_category tags
struct allow_parallel_edge_tag {};
struct disallow_parallel_edge_tag {};
namespace detail {
inline bool allows_parallel(allow_parallel_edge_tag) { return true; }
inline bool allows_parallel(disallow_parallel_edge_tag) { return false; }
}
template <typename Graph>
bool allows_parallel_edges(const Graph&) {
typedef typename graph_traits<Graph>::edge_parallel_category Cat;
return detail::allows_parallel(Cat());
}
// traversal_category tags
struct incidence_graph_tag { };
struct adjacency_graph_tag { };
struct bidirectional_graph_tag :
public virtual incidence_graph_tag { };
struct vertex_list_graph_tag { };
struct edge_list_graph_tag { };
struct adjacency_matrix_tag { };
//?? not the right place ?? Lee
typedef boost::forward_traversal_tag multi_pass_input_iterator_tag;
template <typename G>
struct edge_property_type {
typedef typename G::edge_property_type type;
};
template <typename G>
struct vertex_property_type {
typedef typename G::vertex_property_type type;
};
template <typename G>
struct graph_property_type {
typedef typename G::graph_property_type type;
};
} // namespace boost
// Since pair is in namespace std, Koenig lookup will find source and
// target if they are also defined in namespace std. This is illegal,
// but the alternative is to put source and target in the global
// namespace which causes name conflicts with other libraries (like
// SUIF).
namespace std {
/* Some helper functions for dealing with pairs as edges */
template <class T, class G>
T source(pair<T,T> p, const G&) { return p.first; }
template <class T, class G>
T target(pair<T,T> p, const G&) { return p.second; }
}
#if defined(__GNUC__) && defined(__SGI_STL_PORT)
// For some reason g++ with STLport does not see the above definition
// of source() and target() unless we bring them into the boost
// namespace.
namespace boost {
using std::source;
using std::target;
}
#endif
#endif // BOOST_GRAPH_TRAITS_HPP

View File

@@ -1,435 +0,0 @@
//
//=======================================================================
// Copyright 1997, 1998, 1999, 2000 University of Notre Dame.
// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek
//
// This file is part of the Boost Graph Library
//
// You should have received a copy of the License Agreement for the
// Boost Graph Library along with the software; see the file LICENSE.
// If not, contact Office of Research, University of Notre Dame, Notre
// Dame, IN 46556.
//
// Permission to modify the code and to distribute modified code is
// granted, provided the text of this NOTICE is retained, a notice that
// the code was modified is included with the above COPYRIGHT NOTICE and
// with the COPYRIGHT NOTICE in the LICENSE file, and that the LICENSE
// file is distributed with the modified code.
//
// LICENSOR MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED.
// By way of example, but not limitation, Licensor MAKES NO
// REPRESENTATIONS OR WARRANTIES OF MERCHANTABILITY OR FITNESS FOR ANY
// PARTICULAR PURPOSE OR THAT THE USE OF THE LICENSED SOFTWARE COMPONENTS
// OR DOCUMENTATION WILL NOT INFRINGE ANY PATENTS, COPYRIGHTS, TRADEMARKS
// OR OTHER RIGHTS.
//=======================================================================
//
#ifndef BOOST_GRAPH_UTILITY_HPP
#define BOOST_GRAPH_UTILITY_HPP
#include <stdlib.h>
#include <iostream>
#include <algorithm>
#include <assert.h>
#include <boost/config.hpp>
#include <boost/tuple/tuple.hpp>
#ifndef BOOST_NO_SLIST
# include <slist> // shouldn't have to include this... -JGS
#endif
#include <boost/graph/graph_traits.hpp>
#include <boost/graph/properties.hpp>
#include <boost/pending/container_traits.hpp>
#include <boost/graph/depth_first_search.hpp>
// iota moved to detail/algorithm.hpp
#include <boost/detail/algorithm.hpp>
namespace boost {
// Provide an undirected graph interface alternative to the
// the source() and target() edge functions.
template <class UndirectedGraph>
inline
std::pair<typename graph_traits<UndirectedGraph>::vertex_descriptor,
typename graph_traits<UndirectedGraph>::vertex_descriptor>
incident(typename graph_traits<UndirectedGraph>::edge_descriptor e,
UndirectedGraph& g)
{
return std::make_pair(source(e,g), target(e,g));
}
// Provide an undirected graph interface alternative
// to the out_edges() function.
template <class Graph>
inline
std::pair<typename graph_traits<Graph>::out_edge_iterator,
typename graph_traits<Graph>::out_edge_iterator>
incident_edges(typename graph_traits<Graph>::vertex_descriptor u,
Graph& g)
{
return out_edges(u, g);
}
template <class Graph>
inline typename graph_traits<Graph>::vertex_descriptor
opposite(typename graph_traits<Graph>::edge_descriptor e,
typename graph_traits<Graph>::vertex_descriptor v,
const Graph& g)
{
typedef typename graph_traits<Graph>::vertex_descriptor vertex_descriptor;
if (v == source(e, g))
return target(e, g);
else if (v == target(e, g))
return source(e, g);
else
return vertex_descriptor();
}
//===========================================================================
// Some handy predicates
template <typename Vertex, typename Graph>
struct incident_from_predicate {
incident_from_predicate(Vertex u, const Graph& g)
: m_u(u), m_g(g) { }
template <class Edge>
bool operator()(const Edge& e) const {
return source(e, m_g) == m_u;
}
Vertex m_u;
const Graph& m_g;
};
template <typename Vertex, typename Graph>
inline incident_from_predicate<Vertex, Graph>
incident_from(Vertex u, const Graph& g) {
return incident_from_predicate<Vertex, Graph>(u, g);
}
template <typename Vertex, typename Graph>
struct incident_to_predicate {
incident_to_predicate(Vertex u, const Graph& g)
: m_u(u), m_g(g) { }
template <class Edge>
bool operator()(const Edge& e) const {
return target(e, m_g) == m_u;
}
Vertex m_u;
const Graph& m_g;
};
template <typename Vertex, typename Graph>
inline incident_to_predicate<Vertex, Graph>
incident_to(Vertex u, const Graph& g) {
return incident_to_predicate<Vertex, Graph>(u, g);
}
template <typename Vertex, typename Graph>
struct incident_on_predicate {
incident_on_predicate(Vertex u, const Graph& g)
: m_u(u), m_g(g) { }
template <class Edge>
bool operator()(const Edge& e) const {
return source(e, m_g) == m_u || target(e, m_g) == m_u;
}
Vertex m_u;
const Graph& m_g;
};
template <typename Vertex, typename Graph>
inline incident_on_predicate<Vertex, Graph>
incident_on(Vertex u, const Graph& g) {
return incident_on_predicate<Vertex, Graph>(u, g);
}
template <typename Vertex, typename Graph>
struct connects_predicate {
connects_predicate(Vertex u, Vertex v, const Graph& g)
: m_u(u), m_v(v), m_g(g) { }
template <class Edge>
bool operator()(const Edge& e) const {
if (is_directed(m_g))
return source(e, m_g) == m_u && target(e, m_g) == m_v;
else
return (source(e, m_g) == m_u && target(e, m_g) == m_v)
|| (source(e, m_g) == m_v && target(e, m_g) == m_u);
}
Vertex m_u, m_v;
const Graph& m_g;
};
template <typename Vertex, typename Graph>
inline connects_predicate<Vertex, Graph>
connects(Vertex u, Vertex v, const Graph& g) {
return connects_predicate<Vertex, Graph>(u, v, g);
}
// Need to convert all of these printing functions to take an ostream object
// -JGS
template <class IncidenceGraph, class Name>
void print_in_edges(const IncidenceGraph& G, Name name)
{
typename graph_traits<IncidenceGraph>::vertex_iterator ui,ui_end;
for (tie(ui,ui_end) = vertices(G); ui != ui_end; ++ui) {
std::cout << get(name,*ui) << " <-- ";
typename graph_traits<IncidenceGraph>
::in_edge_iterator ei, ei_end;
for(tie(ei,ei_end) = in_edges(*ui,G); ei != ei_end; ++ei)
std::cout << get(name,source(*ei,G)) << " ";
std::cout << std::endl;
}
}
template <class IncidenceGraph, class Name>
void print_graph_dispatch(const IncidenceGraph& G, Name name, directed_tag)
{
typename graph_traits<IncidenceGraph>::vertex_iterator ui,ui_end;
for (tie(ui,ui_end) = vertices(G); ui != ui_end; ++ui) {
std::cout << get(name,*ui) << " --> ";
typename graph_traits<IncidenceGraph>
::out_edge_iterator ei, ei_end;
for(tie(ei,ei_end) = out_edges(*ui,G); ei != ei_end; ++ei)
std::cout << get(name,target(*ei,G)) << " ";
std::cout << std::endl;
}
}
template <class IncidenceGraph, class Name>
void print_graph_dispatch(const IncidenceGraph& G, Name name, undirected_tag)
{
typename graph_traits<IncidenceGraph>::vertex_iterator ui,ui_end;
for (tie(ui,ui_end) = vertices(G); ui != ui_end; ++ui) {
std::cout << get(name,*ui) << " <--> ";
typename graph_traits<IncidenceGraph>
::out_edge_iterator ei, ei_end;
for(tie(ei,ei_end) = out_edges(*ui,G); ei != ei_end; ++ei)
std::cout << get(name,target(*ei,G)) << " ";
std::cout << std::endl;
}
}
template <class IncidenceGraph, class Name>
void print_graph(const IncidenceGraph& G, Name name)
{
typedef typename graph_traits<IncidenceGraph>
::directed_category Cat;
print_graph_dispatch(G, name, Cat());
}
template <class IncidenceGraph>
void print_graph(const IncidenceGraph& G) {
print_graph(G, get(vertex_index, G));
}
template <class EdgeListGraph, class Name>
void print_edges(const EdgeListGraph& G, Name name)
{
typename graph_traits<EdgeListGraph>::edge_iterator ei, ei_end;
for (tie(ei, ei_end) = edges(G); ei != ei_end; ++ei)
std::cout << "(" << get(name, source(*ei, G))
<< "," << get(name, target(*ei, G)) << ") ";
std::cout << std::endl;
}
template <class EdgeListGraph, class VertexName, class EdgeName>
void print_edges2(const EdgeListGraph& G, VertexName vname, EdgeName ename)
{
typename graph_traits<EdgeListGraph>::edge_iterator ei, ei_end;
for (tie(ei, ei_end) = edges(G); ei != ei_end; ++ei)
std::cout << get(ename, *ei) << "(" << get(vname, source(*ei, G))
<< "," << get(vname, target(*ei, G)) << ") ";
std::cout << std::endl;
}
template <class VertexListGraph, class Name>
void print_vertices(const VertexListGraph& G, Name name)
{
typename graph_traits<VertexListGraph>::vertex_iterator vi,vi_end;
for (tie(vi,vi_end) = vertices(G); vi != vi_end; ++vi)
std::cout << get(name,*vi) << " ";
std::cout << std::endl;
}
template <class Graph, class Vertex>
bool is_adj_dispatch(Graph& g, Vertex a, Vertex b, bidirectional_tag)
{
typedef typename graph_traits<Graph>::edge_descriptor
edge_descriptor;
typename graph_traits<Graph>::adjacency_iterator vi, viend,
adj_found;
tie(vi, viend) = adjacent_vertices(a, g);
adj_found = std::find(vi, viend, b);
if (adj_found == viend)
return false;
typename graph_traits<Graph>::out_edge_iterator oi, oiend,
out_found;
tie(oi, oiend) = out_edges(a, g);
out_found = std::find_if(oi, oiend, incident_to(b, g));
if (out_found == oiend)
return false;
typename graph_traits<Graph>::in_edge_iterator ii, iiend,
in_found;
tie(ii, iiend) = in_edges(b, g);
in_found = std::find_if(ii, iiend, incident_from(a, g));
if (in_found == iiend)
return false;
return true;
}
template <class Graph, class Vertex>
bool is_adj_dispatch(Graph& g, Vertex a, Vertex b, directed_tag)
{
typedef typename graph_traits<Graph>::edge_descriptor
edge_descriptor;
typename graph_traits<Graph>::adjacency_iterator vi, viend, found;
tie(vi, viend) = adjacent_vertices(a, g);
#if defined(BOOST_MSVC) && BOOST_MSVC <= 1300 && defined(__SGI_STL_PORT)
// Getting internal compiler error with std::find()
found = viend;
for (; vi != viend; ++vi)
if (*vi == b) {
found = vi;
break;
}
#else
found = std::find(vi, viend, b);
#endif
if ( found == viend )
return false;
typename graph_traits<Graph>::out_edge_iterator oi, oiend,
out_found;
tie(oi, oiend) = out_edges(a, g);
#if defined(BOOST_MSVC) && BOOST_MSVC <= 1300 && defined(__SGI_STL_PORT)
// Getting internal compiler error with std::find()
out_found = oiend;
for (; oi != oiend; ++oi)
if (target(*oi, g) == b) {
out_found = oi;
break;
}
#else
out_found = std::find_if(oi, oiend, incident_to(b, g));
#endif
if (out_found == oiend)
return false;
return true;
}
template <class Graph, class Vertex>
bool is_adj_dispatch(Graph& g, Vertex a, Vertex b, undirected_tag)
{
return is_adj_dispatch(g, a, b, directed_tag());
}
template <class Graph, class Vertex>
bool is_adjacent(Graph& g, Vertex a, Vertex b) {
typedef typename graph_traits<Graph>::directed_category Cat;
return is_adj_dispatch(g, a, b, Cat());
}
template <class Graph, class Edge>
bool in_edge_set(Graph& g, Edge e)
{
typename Graph::edge_iterator ei, ei_end, found;
tie(ei, ei_end) = edges(g);
found = std::find(ei, ei_end, e);
return found != ei_end;
}
template <class Graph, class Vertex>
bool in_vertex_set(Graph& g, Vertex v)
{
typename Graph::vertex_iterator vi, vi_end, found;
tie(vi, vi_end) = vertices(g);
found = std::find(vi, vi_end, v);
return found != vi_end;
}
template <class Graph, class Vertex>
bool in_edge_set(Graph& g, Vertex u, Vertex v)
{
typename Graph::edge_iterator ei, ei_end;
for (tie(ei,ei_end) = edges(g); ei != ei_end; ++ei)
if (source(*ei,g) == u && target(*ei,g) == v)
return true;
return false;
}
// is x a descendant of y?
template <typename ParentMap>
inline bool is_descendant
(typename property_traits<ParentMap>::value_type x,
typename property_traits<ParentMap>::value_type y,
ParentMap parent)
{
if (get(parent, x) == x) // x is the root of the tree
return false;
else if (get(parent, x) == y)
return true;
else
return is_descendant(get(parent, x), y, parent);
}
// is y reachable from x?
template <typename IncidenceGraph, typename VertexColorMap>
inline bool is_reachable
(typename graph_traits<IncidenceGraph>::vertex_descriptor x,
typename graph_traits<IncidenceGraph>::vertex_descriptor y,
const IncidenceGraph& g,
VertexColorMap color) // should start out white for every vertex
{
typedef typename property_traits<VertexColorMap>::value_type ColorValue;
dfs_visitor<> vis;
depth_first_visit(g, x, vis, color);
return get(color, y) != color_traits<ColorValue>::white();
}
// Is the undirected graph connected?
// Is the directed graph strongly connected?
template <typename VertexListGraph, typename VertexColorMap>
inline bool is_connected(const VertexListGraph& g, VertexColorMap color)
{
typedef typename property_traits<VertexColorMap>::value_type ColorValue;
typedef color_traits<ColorValue> Color;
typename graph_traits<VertexListGraph>::vertex_iterator
ui, ui_end, vi, vi_end, ci, ci_end;
for (tie(ui, ui_end) = vertices(g); ui != ui_end; ++ui)
for (tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi)
if (*ui != *vi) {
for (tie(ci, ci_end) = vertices(g); ci != ci_end; ++ci)
put(color, *ci, Color::white());
if (! is_reachable(*ui, *vi, color))
return false;
}
return true;
}
template <typename Graph>
bool is_self_loop
(typename graph_traits<Graph>::edge_descriptor e,
const Graph& g)
{
return source(e, g) == target(e, g);
}
template <class T1, class T2>
std::pair<T1,T2>
make_list(const T1& t1, const T2& t2)
{ return std::make_pair(t1, t2); }
template <class T1, class T2, class T3>
std::pair<T1,std::pair<T2,T3> >
make_list(const T1& t1, const T2& t2, const T3& t3)
{ return std::make_pair(t1, std::make_pair(t2, t3)); }
template <class T1, class T2, class T3, class T4>
std::pair<T1,std::pair<T2,std::pair<T3,T4> > >
make_list(const T1& t1, const T2& t2, const T3& t3, const T4& t4)
{ return std::make_pair(t1, std::make_pair(t2, std::make_pair(t3, t4))); }
template <class T1, class T2, class T3, class T4, class T5>
std::pair<T1,std::pair<T2,std::pair<T3,std::pair<T4,T5> > > >
make_list(const T1& t1, const T2& t2, const T3& t3, const T4& t4, const T5& t5)
{ return std::make_pair(t1, std::make_pair(t2, std::make_pair(t3, std::make_pair(t4, t5)))); }
} /* namespace boost */
#endif /* BOOST_GRAPH_UTILITY_HPP*/

View File

@@ -1,462 +0,0 @@
//=======================================================================
// (C) Copyright Jeremy Siek 2003.
// Permission to copy, use, modify,
// sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
//=======================================================================
// Copyright 2001 University of Notre Dame.
// Author: Lie-Quan Lee
//
// This file is part of the Boost Graph Library
//
// You should have received a copy of the License Agreement for the
// Boost Graph Library along with the software; see the file LICENSE.
// If not, contact Office of Research, University of Notre Dame, Notre
// Dame, IN 46556.
//
// Permission to modify the code and to distribute modified code is
// granted, provided the text of this NOTICE is retained, a notice that
// the code was modified is included with the above COPYRIGHT NOTICE and
// with the COPYRIGHT NOTICE in the LICENSE file, and that the LICENSE
// file is distributed with the modified code.
//
// LICENSOR MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED.
// By way of example, but not limitation, Licensor MAKES NO
// REPRESENTATIONS OR WARRANTIES OF MERCHANTABILITY OR FITNESS FOR ANY
// PARTICULAR PURPOSE OR THAT THE USE OF THE LICENSED SOFTWARE COMPONENTS
// OR DOCUMENTATION WILL NOT INFRINGE ANY PATENTS, COPYRIGHTS, TRADEMARKS
// OR OTHER RIGHTS.
//=======================================================================
#ifndef BOOST_GRAPHVIZ_HPP
#define BOOST_GRAPHVIZ_HPP
#include <boost/config.hpp>
#include <string>
#include <map>
#include <iostream>
#include <fstream>
#include <stdio.h> // for FILE
#include <boost/property_map.hpp>
#include <boost/tuple/tuple.hpp>
#include <boost/graph/graph_traits.hpp>
#include <boost/graph/properties.hpp>
#include <boost/graph/subgraph.hpp>
#include <boost/graph/adjacency_list.hpp>
namespace boost {
template <typename directed_category>
struct graphviz_io_traits {
static std::string name() {
return "digraph";
}
static std::string delimiter() {
return "->";
} };
template <>
struct graphviz_io_traits <undirected_tag> {
static std::string name() {
return "graph";
}
static std::string delimiter() {
return "--";
}
};
struct default_writer {
void operator()(std::ostream&) const {
}
template <class VorE>
void operator()(std::ostream&, const VorE&) const {
}
};
template <class Name>
class label_writer {
public:
label_writer(Name _name) : name(_name) {}
template <class VertexOrEdge>
void operator()(std::ostream& out, const VertexOrEdge& v) const {
out << "[label=\"" << name[v] << "\"]";
}
private:
Name name;
};
template <class Name>
inline label_writer<Name>
make_label_writer(Name n) {
return label_writer<Name>(n);
}
enum edge_attribute_t { edge_attribute = 1111 };
enum vertex_attribute_t { vertex_attribute = 2222 };
enum graph_graph_attribute_t { graph_graph_attribute = 3333 };
enum graph_vertex_attribute_t { graph_vertex_attribute = 4444 };
enum graph_edge_attribute_t { graph_edge_attribute = 5555 };
BOOST_INSTALL_PROPERTY(edge, attribute);
BOOST_INSTALL_PROPERTY(vertex, attribute);
BOOST_INSTALL_PROPERTY(graph, graph_attribute);
BOOST_INSTALL_PROPERTY(graph, vertex_attribute);
BOOST_INSTALL_PROPERTY(graph, edge_attribute);
template <class Attribute>
inline void write_attributes(const Attribute& attr, std::ostream& out) {
typename Attribute::const_iterator i, iend;
i = attr.begin();
iend = attr.end();
while ( i != iend ) {
out << i->first << "=\"" << i->second << "\"";
++i;
if ( i != iend )
out << ", ";
}
}
template<typename Attributes>
inline void write_all_attributes(Attributes attributes,
const std::string& name,
std::ostream& out)
{
typename Attributes::const_iterator i = attributes.begin(),
end = attributes.end();
if (i != end) {
out << name << " [\n";
write_attributes(attributes, out);
out << "];\n";
}
}
inline void write_all_attributes(detail::error_property_not_found,
const std::string&,
std::ostream&)
{
// Do nothing - no attributes exist
}
template <typename GraphGraphAttributes,
typename GraphNodeAttributes,
typename GraphEdgeAttributes>
struct graph_attributes_writer
{
graph_attributes_writer(GraphGraphAttributes gg,
GraphNodeAttributes gn,
GraphEdgeAttributes ge)
: g_attributes(gg), n_attributes(gn), e_attributes(ge) { }
void operator()(std::ostream& out) const {
write_all_attributes(g_attributes, "graph", out);
write_all_attributes(n_attributes, "node", out);
write_all_attributes(e_attributes, "edge", out);
}
GraphGraphAttributes g_attributes;
GraphNodeAttributes n_attributes;
GraphEdgeAttributes e_attributes;
};
template <typename GAttrMap, typename NAttrMap, typename EAttrMap>
graph_attributes_writer<GAttrMap, NAttrMap, EAttrMap>
make_graph_attributes_writer(const GAttrMap& g_attr, const NAttrMap& n_attr,
const EAttrMap& e_attr) {
return graph_attributes_writer<GAttrMap, NAttrMap, EAttrMap>
(g_attr, n_attr, e_attr);
}
template <typename Graph>
graph_attributes_writer
<typename graph_property<Graph, graph_graph_attribute_t>::type,
typename graph_property<Graph, graph_vertex_attribute_t>::type,
typename graph_property<Graph, graph_edge_attribute_t>::type>
make_graph_attributes_writer(const Graph& g)
{
typedef typename graph_property<Graph, graph_graph_attribute_t>::type
GAttrMap;
typedef typename graph_property<Graph, graph_vertex_attribute_t>::type
NAttrMap;
typedef typename graph_property<Graph, graph_edge_attribute_t>::type
EAttrMap;
GAttrMap gam = get_property(g, graph_graph_attribute);
NAttrMap nam = get_property(g, graph_vertex_attribute);
EAttrMap eam = get_property(g, graph_edge_attribute);
graph_attributes_writer<GAttrMap, NAttrMap, EAttrMap> writer(gam, nam, eam);
return writer;
}
template <typename AttributeMap>
struct attributes_writer {
attributes_writer(AttributeMap attr)
: attributes(attr) { }
template <class VorE>
void operator()(std::ostream& out, const VorE& e) const {
this->write_attribute(out, attributes[e]);
}
private:
template<typename AttributeSequence>
void write_attribute(std::ostream& out,
const AttributeSequence& seq) const
{
if (!seq.empty()) {
out << "[";
write_attributes(seq, out);
out << "]";
}
}
void write_attribute(std::ostream&,
detail::error_property_not_found) const
{
}
AttributeMap attributes;
};
template <typename Graph>
attributes_writer
<typename property_map<Graph, edge_attribute_t>::const_type>
make_edge_attributes_writer(const Graph& g)
{
typedef typename property_map<Graph, edge_attribute_t>::const_type
EdgeAttributeMap;
return attributes_writer<EdgeAttributeMap>(get(edge_attribute, g));
}
template <typename Graph>
attributes_writer
<typename property_map<Graph, vertex_attribute_t>::const_type>
make_vertex_attributes_writer(const Graph& g)
{
typedef typename property_map<Graph, vertex_attribute_t>::const_type
VertexAttributeMap;
return attributes_writer<VertexAttributeMap>(get(vertex_attribute, g));
}
template <typename Graph, typename VertexPropertiesWriter,
typename EdgePropertiesWriter, typename GraphPropertiesWriter>
inline void write_graphviz(std::ostream& out, const Graph& g,
VertexPropertiesWriter vpw,
EdgePropertiesWriter epw,
GraphPropertiesWriter gpw)
{
typedef typename property_map<Graph, vertex_index_t>::const_type vimap_t;
vimap_t vertex_index = get(vertex_index_t(), g);
typedef typename graph_traits<Graph>::directed_category cat_type;
typedef graphviz_io_traits<cat_type> Traits;
std::string name = "G";
out << Traits::name() << " " << name << " {" << std::endl;
gpw(out); //print graph properties
typename graph_traits<Graph>::vertex_iterator i, end;
for(tie(i,end) = vertices(g); i != end; ++i) {
out << get(vertex_index, *i);
vpw(out, *i); //print vertex attributes
out << ";" << std::endl;
}
typename graph_traits<Graph>::edge_iterator ei, edge_end;
for(tie(ei, edge_end) = edges(g); ei != edge_end; ++ei) {
out << get(vertex_index, source(*ei, g)) << Traits::delimiter() << get(vertex_index, target(*ei, g)) << " ";
epw(out, *ei); //print edge attributes
out << ";" << std::endl;
}
out << "}" << std::endl;
}
#if !defined(BOOST_MSVC) || BOOST_MSVC > 1300
// ambiguous overload problem with VC++
template <typename Graph>
inline void
write_graphviz(std::ostream& out, const Graph& g) {
default_writer dw;
default_writer gw;
write_graphviz(out, g, dw, dw, gw);
}
#endif
template <typename Graph, typename VertexWriter>
inline void
write_graphviz(std::ostream& out, const Graph& g, VertexWriter vw) {
default_writer dw;
default_writer gw;
write_graphviz(out, g, vw, dw, gw);
}
template <typename Graph, typename VertexWriter, typename EdgeWriter>
inline void
write_graphviz(std::ostream& out, const Graph& g,
VertexWriter vw, EdgeWriter ew) {
default_writer gw;
write_graphviz(out, g, vw, ew, gw);
}
namespace detail {
template <class Graph_, class RandomAccessIterator>
void write_graphviz_subgraph (std::ostream& out,
const subgraph<Graph_>& g,
RandomAccessIterator vertex_marker,
RandomAccessIterator edge_marker)
{
typedef subgraph<Graph_> Graph;
typedef typename graph_traits<Graph>::vertex_descriptor Vertex;
typedef typename graph_traits<Graph>::directed_category cat_type;
typedef graphviz_io_traits<cat_type> Traits;
typedef typename graph_property<Graph, graph_name_t>::type NameType;
const NameType& g_name = get_property(g, graph_name);
if ( g.is_root() )
out << Traits::name() ;
else
out << "subgraph";
out << " " << g_name << " {" << std::endl;
typename Graph::const_children_iterator i_child, j_child;
//print graph/node/edge attributes
#if defined(BOOST_MSVC) && BOOST_MSVC <= 1300
typedef typename graph_property<Graph, graph_graph_attribute_t>::type
GAttrMap;
typedef typename graph_property<Graph, graph_vertex_attribute_t>::type
NAttrMap;
typedef typename graph_property<Graph, graph_edge_attribute_t>::type
EAttrMap;
GAttrMap gam = get_property(g, graph_graph_attribute);
NAttrMap nam = get_property(g, graph_vertex_attribute);
EAttrMap eam = get_property(g, graph_edge_attribute);
graph_attributes_writer<GAttrMap, NAttrMap, EAttrMap> writer(gam, nam, eam);
writer(out);
#else
make_graph_attributes_writer(g)(out);
#endif
//print subgraph
for ( tie(i_child,j_child) = g.children();
i_child != j_child; ++i_child )
write_graphviz_subgraph(out, *i_child, vertex_marker, edge_marker);
// Print out vertices and edges not in the subgraphs.
typename graph_traits<Graph>::vertex_iterator i, end;
typename graph_traits<Graph>::edge_iterator ei, edge_end;
typename property_map<Graph, vertex_index_t>::const_type
indexmap = get(vertex_index, g.root());
for(tie(i,end) = vertices(g); i != end; ++i) {
Vertex v = g.local_to_global(*i);
int pos = get(indexmap, v);
if ( vertex_marker[pos] ) {
vertex_marker[pos] = false;
out << pos;
#if defined(BOOST_MSVC) && BOOST_MSVC <= 1300
typedef typename property_map<Graph, vertex_attribute_t>::const_type
VertexAttributeMap;
attributes_writer<VertexAttributeMap> vawriter(get(vertex_attribute,
g.root()));
vawriter(out, v);
#else
make_vertex_attributes_writer(g.root())(out, v);
#endif
out << ";" << std::endl;
}
}
for (tie(ei, edge_end) = edges(g); ei != edge_end; ++ei) {
Vertex u = g.local_to_global(source(*ei,g)),
v = g.local_to_global(target(*ei, g));
int pos = get(get(edge_index, g.root()), g.local_to_global(*ei));
if ( edge_marker[pos] ) {
edge_marker[pos] = false;
out << get(indexmap, u) << " " << Traits::delimiter()
<< " " << get(indexmap, v);
#if defined(BOOST_MSVC) && BOOST_MSVC <= 1300
typedef typename property_map<Graph, edge_attribute_t>::const_type
EdgeAttributeMap;
attributes_writer<EdgeAttributeMap> eawriter(get(edge_attribute, g));
eawriter(out, *ei);
#else
make_edge_attributes_writer(g)(out, *ei); //print edge properties
#endif
out << ";" << std::endl;
}
}
out << "}" << std::endl;
}
} // namespace detail
// requires graph_name graph property
template <typename Graph>
void write_graphviz(std::ostream& out, const subgraph<Graph>& g) {
std::vector<bool> edge_marker(num_edges(g), true);
std::vector<bool> vertex_marker(num_vertices(g), true);
detail::write_graphviz_subgraph(out, g,
vertex_marker.begin(),
edge_marker.begin());
}
template <typename Graph>
void write_graphviz(const std::string& filename, const subgraph<Graph>& g) {
std::ofstream out(filename.c_str());
std::vector<bool> edge_marker(num_edges(g), true);
std::vector<bool> vertex_marker(num_vertices(g), true);
detail::write_graphviz_subgraph(out, g,
vertex_marker.begin(),
edge_marker.begin());
}
typedef std::map<std::string, std::string> GraphvizAttrList;
typedef property<vertex_attribute_t, GraphvizAttrList>
GraphvizVertexProperty;
typedef property<edge_attribute_t, GraphvizAttrList,
property<edge_index_t, int> >
GraphvizEdgeProperty;
typedef property<graph_graph_attribute_t, GraphvizAttrList,
property<graph_vertex_attribute_t, GraphvizAttrList,
property<graph_edge_attribute_t, GraphvizAttrList,
property<graph_name_t, std::string> > > >
GraphvizGraphProperty;
typedef subgraph<adjacency_list<vecS,
vecS, directedS,
GraphvizVertexProperty,
GraphvizEdgeProperty,
GraphvizGraphProperty> >
GraphvizDigraph;
typedef subgraph<adjacency_list<vecS,
vecS, undirectedS,
GraphvizVertexProperty,
GraphvizEdgeProperty,
GraphvizGraphProperty> >
GraphvizGraph;
// These four require linking the BGL-Graphviz library: libbgl-viz.a
// from the /src directory.
extern void read_graphviz(const std::string& file, GraphvizDigraph& g);
extern void read_graphviz(FILE* file, GraphvizDigraph& g);
extern void read_graphviz(const std::string& file, GraphvizGraph& g);
extern void read_graphviz(FILE* file, GraphvizGraph& g);
} // namespace boost
#endif // BOOST_GRAPHVIZ_HPP

View File

@@ -1,186 +0,0 @@
//
//=======================================================================
// Copyright 1997-2001 University of Notre Dame.
// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek
//
// This file is part of the Boost Graph Library
//
// You should have received a copy of the License Agreement for the
// Boost Graph Library along with the software; see the file LICENSE.
// If not, contact Office of Research, University of Notre Dame, Notre
// Dame, IN 46556.
//
// Permission to modify the code and to distribute modified code is
// granted, provided the text of this NOTICE is retained, a notice that
// the code was modified is included with the above COPYRIGHT NOTICE and
// with the COPYRIGHT NOTICE in the LICENSE file, and that the LICENSE
// file is distributed with the modified code.
//
// LICENSOR MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED.
// By way of example, but not limitation, Licensor MAKES NO
// REPRESENTATIONS OR WARRANTIES OF MERCHANTABILITY OR FITNESS FOR ANY
// PARTICULAR PURPOSE OR THAT THE USE OF THE LICENSED SOFTWARE COMPONENTS
// OR DOCUMENTATION WILL NOT INFRINGE ANY PATENTS, COPYRIGHTS, TRADEMARKS
// OR OTHER RIGHTS.
//=======================================================================
//
#ifndef BOOST_INCREMENTAL_COMPONENTS_HPP
#define BOOST_INCREMENTAL_COMPONENTS_HPP
#include <boost/detail/iterator.hpp>
#include <boost/graph/detail/incremental_components.hpp>
namespace boost {
// A connected component algorithm for the case when dynamically
// adding (but not removing) edges is common. The
// incremental_components() function is a preparing operation. Call
// same_component to check whether two vertices are in the same
// component, or use disjoint_set::find_set to determine the
// representative for a vertex.
// This version of connected components does not require a full
// Graph. Instead, it just needs an edge list, where the vertices of
// each edge need to be of integer type. The edges are assumed to
// be undirected. The other difference is that the result is stored in
// a container, instead of just a decorator. The container should be
// empty before the algorithm is called. It will grow during the
// course of the algorithm. The container must be a model of
// BackInsertionSequence and RandomAccessContainer
// (std::vector is a good choice). After running the algorithm the
// index container will map each vertex to the representative
// vertex of the component to which it belongs.
//
// Adapted from an implementation by Alex Stepanov. The disjoint
// sets data structure is from Tarjan's "Data Structures and Network
// Algorithms", and the application to connected components is
// similar to the algorithm described in Ch. 22 of "Intro to
// Algorithms" by Cormen, et. all.
//
// RankContainer is a random accessable container (operator[] is
// defined) with a value type that can represent an integer part of
// a binary log of the value type of the corresponding
// ParentContainer (char is always enough) its size_type is no less
// than the size_type of the corresponding ParentContainer
// An implementation of disjoint sets can be found in
// boost/pending/disjoint_sets.hpp
template <class EdgeListGraph, class DisjointSets>
void incremental_components(EdgeListGraph& g, DisjointSets& ds)
{
typename graph_traits<EdgeListGraph>::edge_iterator e, end;
for (tie(e,end) = edges(g); e != end; ++e)
ds.link(source(*e,g),target(*e,g));
}
template <class ParentIterator>
void compress_components(ParentIterator first, ParentIterator last)
{
for (ParentIterator current = first; current != last; ++current)
detail::find_representative_with_full_compression(first, current-first);
}
template <class ParentIterator>
typename boost::detail::iterator_traits<ParentIterator>::difference_type
component_count(ParentIterator first, ParentIterator last)
{
std::ptrdiff_t count = 0;
for (ParentIterator current = first; current != last; ++current)
if (*current == current - first) ++count;
return count;
}
// This algorithm can be applied to the result container of the
// connected_components algorithm to normalize
// the components.
template <class ParentIterator>
void normalize_components(ParentIterator first, ParentIterator last)
{
for (ParentIterator current = first; current != last; ++current)
detail::normalize_node(first, current - first);
}
template <class VertexListGraph, class DisjointSets>
void initialize_incremental_components(VertexListGraph& G, DisjointSets& ds)
{
typename graph_traits<VertexListGraph>
::vertex_iterator v, vend;
for (tie(v, vend) = vertices(G); v != vend; ++v)
ds.make_set(*v);
}
template <class Vertex, class DisjointSet>
inline bool same_component(Vertex u, Vertex v, DisjointSet& ds)
{
return ds.find_set(u) == ds.find_set(v);
}
// considering changing the so that it initializes with a pair of
// vertex iterators and a parent PA.
template <class IndexT>
class component_index
{
public://protected: (avoid friends for now)
typedef std::vector<IndexT> MyIndexContainer;
MyIndexContainer header;
MyIndexContainer index;
typedef typename MyIndexContainer::size_type SizeT;
typedef typename MyIndexContainer::const_iterator IndexIter;
public:
typedef detail::component_iterator<IndexIter, IndexT, SizeT>
component_iterator;
class component {
friend class component_index;
protected:
IndexT number;
const component_index<IndexT>* comp_ind_ptr;
component(IndexT i, const component_index<IndexT>* p)
: number(i), comp_ind_ptr(p) {}
public:
typedef component_iterator iterator;
typedef component_iterator const_iterator;
typedef IndexT value_type;
iterator begin() const {
return iterator( comp_ind_ptr->index.begin(),
(comp_ind_ptr->header)[number] );
}
iterator end() const {
return iterator( comp_ind_ptr->index.begin(),
comp_ind_ptr->index.size() );
}
};
typedef SizeT size_type;
typedef component value_type;
#if defined(BOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS)
template <class Iterator>
component_index(Iterator first, Iterator last)
: index(std::distance(first, last))
{
std::copy(first, last, index.begin());
detail::construct_component_index(index, header);
}
#else
template <class Iterator>
component_index(Iterator first, Iterator last)
: index(first, last)
{
detail::construct_component_index(index, header);
}
#endif
component operator[](IndexT i) const {
return component(i, this);
}
SizeT size() const {
return header.size();
}
};
} // namespace boost
#endif // BOOST_INCREMENTAL_COMPONENTS_HPP

View File

@@ -1,472 +0,0 @@
// Copyright (C) 2001 Jeremy Siek, Douglas Gregor, Brian Osman
//
// Permission to copy, use, sell and distribute this software is granted
// provided this copyright notice appears in all copies.
// Permission to modify the code and to distribute modified code is granted
// provided this copyright notice appears in all copies, and a notice
// that the code was modified is included with the copyright notice.
//
// This software is provided "as is" without express or implied warranty,
// and with no claim as to its suitability for any purpose.
#ifndef BOOST_GRAPH_ISOMORPHISM_HPP
#define BOOST_GRAPH_ISOMORPHISM_HPP
#include <utility>
#include <vector>
#include <iterator>
#include <algorithm>
#include <boost/config.hpp>
#include <boost/graph/depth_first_search.hpp>
#include <boost/utility.hpp>
#include <boost/detail/algorithm.hpp>
#include <boost/pending/indirect_cmp.hpp> // for make_indirect_pmap
#ifndef BOOST_GRAPH_ITERATION_MACROS_HPP
#define BOOST_ISO_INCLUDED_ITER_MACROS // local macro, see bottom of file
#include <boost/graph/iteration_macros.hpp>
#endif
namespace boost {
namespace detail {
template <typename Graph1, typename Graph2, typename IsoMapping,
typename Invariant1, typename Invariant2,
typename IndexMap1, typename IndexMap2>
class isomorphism_algo
{
typedef typename graph_traits<Graph1>::vertex_descriptor vertex1_t;
typedef typename graph_traits<Graph2>::vertex_descriptor vertex2_t;
typedef typename graph_traits<Graph1>::edge_descriptor edge1_t;
typedef typename graph_traits<Graph1>::vertices_size_type size_type;
typedef typename Invariant1::result_type invar1_value;
typedef typename Invariant2::result_type invar2_value;
const Graph1& G1;
const Graph2& G2;
IsoMapping f;
Invariant1 invariant1;
Invariant2 invariant2;
std::size_t max_invariant;
IndexMap1 index_map1;
IndexMap2 index_map2;
std::vector<vertex1_t> dfs_vertices;
typedef typename std::vector<vertex1_t>::iterator vertex_iter;
std::vector<int> dfs_num_vec;
typedef safe_iterator_property_map<typename std::vector<int>::iterator,
IndexMap1
#ifdef BOOST_NO_STD_ITERATOR_TRAITS
, int, int&
#endif /* BOOST_NO_STD_ITERATOR_TRAITS */
> DFSNumMap;
DFSNumMap dfs_num;
std::vector<edge1_t> ordered_edges;
typedef typename std::vector<edge1_t>::iterator edge_iter;
std::vector<char> in_S_vec;
typedef safe_iterator_property_map<typename std::vector<char>::iterator,
IndexMap2
#ifdef BOOST_NO_STD_ITERATOR_TRAITS
, char, char&
#endif /* BOOST_NO_STD_ITERATOR_TRAITS */
> InSMap;
InSMap in_S;
int num_edges_on_k;
friend struct compare_multiplicity;
struct compare_multiplicity
{
compare_multiplicity(Invariant1 invariant1, size_type* multiplicity)
: invariant1(invariant1), multiplicity(multiplicity) { }
bool operator()(const vertex1_t& x, const vertex1_t& y) const {
return multiplicity[invariant1(x)] < multiplicity[invariant1(y)];
}
Invariant1 invariant1;
size_type* multiplicity;
};
struct record_dfs_order : default_dfs_visitor
{
record_dfs_order(std::vector<vertex1_t>& v, std::vector<edge1_t>& e)
: vertices(v), edges(e) { }
void discover_vertex(vertex1_t v, const Graph1&) const {
vertices.push_back(v);
}
void examine_edge(edge1_t e, const Graph1& G1) const {
edges.push_back(e);
}
std::vector<vertex1_t>& vertices;
std::vector<edge1_t>& edges;
};
struct edge_cmp {
edge_cmp(const Graph1& G1, DFSNumMap dfs_num)
: G1(G1), dfs_num(dfs_num) { }
bool operator()(const edge1_t& e1, const edge1_t& e2) const {
using namespace std;
int u1 = dfs_num[source(e1,G1)], v1 = dfs_num[target(e1,G1)];
int u2 = dfs_num[source(e2,G1)], v2 = dfs_num[target(e2,G1)];
int m1 = (max)(u1, v1);
int m2 = (max)(u2, v2);
// lexicographical comparison
return make_pair(m1, make_pair(u1, v1))
< make_pair(m2, make_pair(u2, v2));
}
const Graph1& G1;
DFSNumMap dfs_num;
};
public:
isomorphism_algo(const Graph1& G1, const Graph2& G2, IsoMapping f,
Invariant1 invariant1, Invariant2 invariant2, std::size_t max_invariant,
IndexMap1 index_map1, IndexMap2 index_map2)
: G1(G1), G2(G2), f(f), invariant1(invariant1), invariant2(invariant2),
max_invariant(max_invariant),
index_map1(index_map1), index_map2(index_map2)
{
in_S_vec.resize(num_vertices(G1));
in_S = make_safe_iterator_property_map
(in_S_vec.begin(), in_S_vec.size(), index_map2
#ifdef BOOST_NO_STD_ITERATOR_TRAITS
, in_S_vec.front()
#endif /* BOOST_NO_STD_ITERATOR_TRAITS */
);
}
bool test_isomorphism()
{
{
std::vector<invar1_value> invar1_array;
BGL_FORALL_VERTICES_T(v, G1, Graph1)
invar1_array.push_back(invariant1(v));
sort(invar1_array);
std::vector<invar2_value> invar2_array;
BGL_FORALL_VERTICES_T(v, G2, Graph2)
invar2_array.push_back(invariant2(v));
sort(invar2_array);
if (! equal(invar1_array, invar2_array))
return false;
}
std::vector<vertex1_t> V_mult;
BGL_FORALL_VERTICES_T(v, G1, Graph1)
V_mult.push_back(v);
{
std::vector<size_type> multiplicity(max_invariant, 0);
BGL_FORALL_VERTICES_T(v, G1, Graph1)
++multiplicity[invariant1(v)];
sort(V_mult, compare_multiplicity(invariant1, &multiplicity[0]));
}
std::vector<default_color_type> color_vec(num_vertices(G1));
safe_iterator_property_map<std::vector<default_color_type>::iterator,
IndexMap1
#ifdef BOOST_NO_STD_ITERATOR_TRAITS
, default_color_type, default_color_type&
#endif /* BOOST_NO_STD_ITERATOR_TRAITS */
>
color_map(color_vec.begin(), color_vec.size(), index_map1);
record_dfs_order dfs_visitor(dfs_vertices, ordered_edges);
typedef color_traits<default_color_type> Color;
for (vertex_iter u = V_mult.begin(); u != V_mult.end(); ++u) {
if (color_map[*u] == Color::white()) {
dfs_visitor.start_vertex(*u, G1);
depth_first_visit(G1, *u, dfs_visitor, color_map);
}
}
// Create the dfs_num array and dfs_num_map
dfs_num_vec.resize(num_vertices(G1));
dfs_num = make_safe_iterator_property_map(dfs_num_vec.begin(),
dfs_num_vec.size(),
index_map1
#ifdef BOOST_NO_STD_ITERATOR_TRAITS
, dfs_num_vec.front()
#endif /* BOOST_NO_STD_ITERATOR_TRAITS */
);
size_type n = 0;
for (vertex_iter v = dfs_vertices.begin(); v != dfs_vertices.end(); ++v)
dfs_num[*v] = n++;
sort(ordered_edges, edge_cmp(G1, dfs_num));
int dfs_num_k = -1;
return this->match(ordered_edges.begin(), dfs_num_k);
}
private:
bool match(edge_iter iter, int dfs_num_k)
{
if (iter != ordered_edges.end()) {
vertex1_t i = source(*iter, G1), j = target(*iter, G2);
if (dfs_num[i] > dfs_num_k) {
vertex1_t kp1 = dfs_vertices[dfs_num_k + 1];
BGL_FORALL_VERTICES_T(u, G2, Graph2) {
if (invariant1(kp1) == invariant2(u) && in_S[u] == false) {
f[kp1] = u;
in_S[u] = true;
num_edges_on_k = 0;
if (match(iter, dfs_num_k + 1))
#if 0
// dwa 2003/7/11 -- this *HAS* to be a bug!
;
#endif
return true;
in_S[u] = false;
}
}
}
else if (dfs_num[j] > dfs_num_k) {
vertex1_t k = dfs_vertices[dfs_num_k];
num_edges_on_k -=
count_if(adjacent_vertices(f[k], G2), make_indirect_pmap(in_S));
for (int jj = 0; jj < dfs_num_k; ++jj) {
vertex1_t j = dfs_vertices[jj];
num_edges_on_k -= count(adjacent_vertices(f[j], G2), f[k]);
}
if (num_edges_on_k != 0)
return false;
BGL_FORALL_ADJ_T(f[i], v, G2, Graph2)
if (invariant2(v) == invariant1(j) && in_S[v] == false) {
f[j] = v;
in_S[v] = true;
num_edges_on_k = 1;
BOOST_USING_STD_MAX();
int next_k = max BOOST_PREVENT_MACRO_SUBSTITUTION(dfs_num_k, max BOOST_PREVENT_MACRO_SUBSTITUTION(dfs_num[i], dfs_num[j]));
if (match(next(iter), next_k))
return true;
in_S[v] = false;
}
}
else {
if (contains(adjacent_vertices(f[i], G2), f[j])) {
++num_edges_on_k;
if (match(next(iter), dfs_num_k))
return true;
}
}
} else
return true;
return false;
}
};
template <typename Graph, typename InDegreeMap>
void compute_in_degree(const Graph& g, InDegreeMap in_degree_map)
{
BGL_FORALL_VERTICES_T(v, g, Graph)
put(in_degree_map, v, 0);
BGL_FORALL_VERTICES_T(u, g, Graph)
BGL_FORALL_ADJ_T(u, v, g, Graph)
put(in_degree_map, v, get(in_degree_map, v) + 1);
}
} // namespace detail
template <typename InDegreeMap, typename Graph>
class degree_vertex_invariant
{
typedef typename graph_traits<Graph>::vertex_descriptor vertex_t;
typedef typename graph_traits<Graph>::degree_size_type size_type;
public:
typedef vertex_t argument_type;
typedef size_type result_type;
degree_vertex_invariant(const InDegreeMap& in_degree_map, const Graph& g)
: m_in_degree_map(in_degree_map), m_g(g) { }
size_type operator()(vertex_t v) const {
return (num_vertices(m_g) + 1) * out_degree(v, m_g)
+ get(m_in_degree_map, v);
}
// The largest possible vertex invariant number
size_type max BOOST_PREVENT_MACRO_SUBSTITUTION () const {
return num_vertices(m_g) * num_vertices(m_g) + num_vertices(m_g);
}
private:
InDegreeMap m_in_degree_map;
const Graph& m_g;
};
template <typename Graph1, typename Graph2, typename IsoMapping,
typename Invariant1, typename Invariant2,
typename IndexMap1, typename IndexMap2>
bool isomorphism(const Graph1& G1, const Graph2& G2, IsoMapping f,
Invariant1 invariant1, Invariant2 invariant2,
std::size_t max_invariant,
IndexMap1 index_map1, IndexMap2 index_map2)
{
// Graph requirements
function_requires< VertexListGraphConcept<Graph1> >();
function_requires< EdgeListGraphConcept<Graph1> >();
function_requires< VertexListGraphConcept<Graph2> >();
function_requires< BidirectionalGraphConcept<Graph2> >();
typedef typename graph_traits<Graph1>::vertex_descriptor vertex1_t;
typedef typename graph_traits<Graph2>::vertex_descriptor vertex2_t;
typedef typename graph_traits<Graph1>::vertices_size_type size_type;
// Vertex invariant requirement
function_requires< AdaptableUnaryFunctionConcept<Invariant1,
size_type, vertex1_t> >();
function_requires< AdaptableUnaryFunctionConcept<Invariant2,
size_type, vertex2_t> >();
// Property map requirements
function_requires< ReadWritePropertyMapConcept<IsoMapping, vertex1_t> >();
typedef typename property_traits<IsoMapping>::value_type IsoMappingValue;
BOOST_STATIC_ASSERT((is_same<IsoMappingValue, vertex2_t>::value));
function_requires< ReadablePropertyMapConcept<IndexMap1, vertex1_t> >();
typedef typename property_traits<IndexMap1>::value_type IndexMap1Value;
BOOST_STATIC_ASSERT((is_convertible<IndexMap1Value, size_type>::value));
function_requires< ReadablePropertyMapConcept<IndexMap2, vertex2_t> >();
typedef typename property_traits<IndexMap2>::value_type IndexMap2Value;
BOOST_STATIC_ASSERT((is_convertible<IndexMap2Value, size_type>::value));
if (num_vertices(G1) != num_vertices(G2))
return false;
if (num_vertices(G1) == 0 && num_vertices(G2) == 0)
return true;
detail::isomorphism_algo<Graph1, Graph2, IsoMapping, Invariant1,
Invariant2, IndexMap1, IndexMap2>
algo(G1, G2, f, invariant1, invariant2, max_invariant,
index_map1, index_map2);
return algo.test_isomorphism();
}
namespace detail {
template <typename Graph1, typename Graph2,
typename IsoMapping,
typename IndexMap1, typename IndexMap2,
typename P, typename T, typename R>
bool isomorphism_impl(const Graph1& G1, const Graph2& G2,
IsoMapping f, IndexMap1 index_map1, IndexMap2 index_map2,
const bgl_named_params<P,T,R>& params)
{
std::vector<std::size_t> in_degree1_vec(num_vertices(G1));
typedef safe_iterator_property_map<std::vector<std::size_t>::iterator,
IndexMap1
#ifdef BOOST_NO_STD_ITERATOR_TRAITS
, std::size_t, std::size_t&
#endif /* BOOST_NO_STD_ITERATOR_TRAITS */
> InDeg1;
InDeg1 in_degree1(in_degree1_vec.begin(), in_degree1_vec.size(), index_map1);
compute_in_degree(G1, in_degree1);
std::vector<std::size_t> in_degree2_vec(num_vertices(G2));
typedef safe_iterator_property_map<std::vector<std::size_t>::iterator,
IndexMap2
#ifdef BOOST_NO_STD_ITERATOR_TRAITS
, std::size_t, std::size_t&
#endif /* BOOST_NO_STD_ITERATOR_TRAITS */
> InDeg2;
InDeg2 in_degree2(in_degree2_vec.begin(), in_degree2_vec.size(), index_map2);
compute_in_degree(G2, in_degree2);
degree_vertex_invariant<InDeg1, Graph1> invariant1(in_degree1, G1);
degree_vertex_invariant<InDeg2, Graph2> invariant2(in_degree2, G2);
return isomorphism(G1, G2, f,
choose_param(get_param(params, vertex_invariant1_t()), invariant1),
choose_param(get_param(params, vertex_invariant2_t()), invariant2),
choose_param(get_param(params, vertex_max_invariant_t()), (invariant2.max)()),
index_map1, index_map2
);
}
} // namespace detail
// Named parameter interface
template <typename Graph1, typename Graph2, class P, class T, class R>
bool isomorphism(const Graph1& g1,
const Graph2& g2,
const bgl_named_params<P,T,R>& params)
{
typedef typename graph_traits<Graph2>::vertex_descriptor vertex2_t;
typename std::vector<vertex2_t>::size_type n = num_vertices(g1);
std::vector<vertex2_t> f(n);
return detail::isomorphism_impl
(g1, g2,
choose_param(get_param(params, vertex_isomorphism_t()),
make_safe_iterator_property_map(f.begin(), f.size(),
choose_const_pmap(get_param(params, vertex_index1),
g1, vertex_index), vertex2_t())),
choose_const_pmap(get_param(params, vertex_index1), g1, vertex_index),
choose_const_pmap(get_param(params, vertex_index2), g2, vertex_index),
params
);
}
// All defaults interface
template <typename Graph1, typename Graph2>
bool isomorphism(const Graph1& g1, const Graph2& g2)
{
return isomorphism(g1, g2,
bgl_named_params<int, buffer_param_t>(0));// bogus named param
}
// Verify that the given mapping iso_map from the vertices of g1 to the
// vertices of g2 describes an isomorphism.
// Note: this could be made much faster by specializing based on the graph
// concepts modeled, but since we're verifying an O(n^(lg n)) algorithm,
// O(n^4) won't hurt us.
template<typename Graph1, typename Graph2, typename IsoMap>
inline bool verify_isomorphism(const Graph1& g1, const Graph2& g2, IsoMap iso_map)
{
#if 0
// problematic for filtered_graph!
if (num_vertices(g1) != num_vertices(g2) || num_edges(g1) != num_edges(g2))
return false;
#endif
for (typename graph_traits<Graph1>::edge_iterator e1 = edges(g1).first;
e1 != edges(g1).second; ++e1) {
bool found_edge = false;
for (typename graph_traits<Graph2>::edge_iterator e2 = edges(g2).first;
e2 != edges(g2).second && !found_edge; ++e2) {
if (source(*e2, g2) == get(iso_map, source(*e1, g1)) &&
target(*e2, g2) == get(iso_map, target(*e1, g1))) {
found_edge = true;
}
}
if (!found_edge)
return false;
}
return true;
}
} // namespace boost
#ifdef BOOST_ISO_INCLUDED_ITER_MACROS
#undef BOOST_ISO_INCLUDED_ITER_MACROS
#include <boost/graph/iteration_macros_undef.hpp>
#endif
#endif // BOOST_GRAPH_ISOMORPHISM_HPP

View File

@@ -1,143 +0,0 @@
//=======================================================================
// Copyright 2001 Indiana University
// Author: Jeremy G. Siek
//
// This file is part of the Boost Graph Library
//
// You should have received a copy of the License Agreement for the
// Boost Graph Library along with the software; see the file LICENSE.
//
// Permission to modify the code and to distribute modified code is
// granted, provided the text of this NOTICE is retained, a notice that
// the code was modified is included with the above COPYRIGHT NOTICE and
// with the COPYRIGHT NOTICE in the LICENSE file, and that the LICENSE
// file is distributed with the modified code.
//
// LICENSOR MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED.
// By way of example, but not limitation, Licensor MAKES NO
// REPRESENTATIONS OR WARRANTIES OF MERCHANTABILITY OR FITNESS FOR ANY
// PARTICULAR PURPOSE OR THAT THE USE OF THE LICENSED SOFTWARE COMPONENTS
// OR DOCUMENTATION WILL NOT INFRINGE ANY PATENTS, COPYRIGHTS, TRADEMARKS
// OR OTHER RIGHTS.
//=======================================================================
#ifndef BOOST_GRAPH_ITERATION_MACROS_HPP
#define BOOST_GRAPH_ITERATION_MACROS_HPP
#define BGL_CAT(x,y) x ## y
#define BGL_FIRST(linenum) BGL_CAT(bgl_first_,linenum)
#define BGL_LAST(linenum) BGL_CAT(bgl_last_,linenum)
/*
BGL_FORALL_VERTICES_T(v, g, graph_t) // This is on line 9
expands to the following, but all on the same line
for (typename boost::graph_traits<graph_t>::vertex_iterator
bgl_first_9 = vertices(g).first, bgl_last_9 = vertices(g).second;
bgl_first_9 != bgl_last_9; bgl_first_9 = bgl_last_9)
for (typename boost::graph_traits<graph_t>::vertex_descriptor v;
bgl_first_9 != bgl_last ? (v = *bgl_first_9, true) : false;
++bgl_first_9)
The purpose of having two for-loops is just to provide a place to
declare both the iterator and value variables. There is really only
one loop. The stopping condition gets executed two more times than it
usually would be, oh well. The reason for the bgl_first_9 = bgl_last_9
in the outer for-loop is in case the user puts a break statement
in the inner for-loop.
The other macros work in a similar fashion.
Use the _T versions when the graph type is a template parameter or
dependent on a template parameter. Otherwise use the non _T versions.
*/
#define BGL_FORALL_VERTICES_T(VNAME, GNAME, GraphType) \
for (typename boost::graph_traits<GraphType>::vertex_iterator \
BGL_FIRST(__LINE__) = vertices(GNAME).first, BGL_LAST(__LINE__) = vertices(GNAME).second; \
BGL_FIRST(__LINE__) != BGL_LAST(__LINE__); BGL_FIRST(__LINE__) = BGL_LAST(__LINE__)) \
for (typename boost::graph_traits<GraphType>::vertex_descriptor VNAME; \
BGL_FIRST(__LINE__) != BGL_LAST(__LINE__) ? (VNAME = *BGL_FIRST(__LINE__), true):false; \
++BGL_FIRST(__LINE__))
#define BGL_FORALL_VERTICES(VNAME, GNAME, GraphType) \
for (boost::graph_traits<GraphType>::vertex_iterator \
BGL_FIRST(__LINE__) = vertices(GNAME).first, BGL_LAST(__LINE__) = vertices(GNAME).second; \
BGL_FIRST(__LINE__) != BGL_LAST(__LINE__); BGL_FIRST(__LINE__) = BGL_LAST(__LINE__)) \
for (boost::graph_traits<GraphType>::vertex_descriptor VNAME; \
BGL_FIRST(__LINE__) != BGL_LAST(__LINE__) ? (VNAME = *BGL_FIRST(__LINE__), true):false; \
++BGL_FIRST(__LINE__))
#define BGL_FORALL_EDGES_T(ENAME, GNAME, GraphType) \
for (typename boost::graph_traits<GraphType>::edge_iterator \
BGL_FIRST(__LINE__) = edges(GNAME).first, BGL_LAST(__LINE__) = edges(GNAME).second; \
BGL_FIRST(__LINE__) != BGL_LAST(__LINE__); BGL_FIRST(__LINE__) = BGL_LAST(__LINE__)) \
for (typename boost::graph_traits<GraphType>::edge_descriptor ENAME; \
BGL_FIRST(__LINE__) != BGL_LAST(__LINE__) ? (ENAME = *BGL_FIRST(__LINE__), true):false; \
++BGL_FIRST(__LINE__))
#define BGL_FORALL_EDGES(ENAME, GNAME, GraphType) \
for (boost::graph_traits<GraphType>::edge_iterator \
BGL_FIRST(__LINE__) = edges(GNAME).first, BGL_LAST(__LINE__) = edges(GNAME).second; \
BGL_FIRST(__LINE__) != BGL_LAST(__LINE__); BGL_FIRST(__LINE__) = BGL_LAST(__LINE__)) \
for (boost::graph_traits<GraphType>::edge_descriptor ENAME; \
BGL_FIRST(__LINE__) != BGL_LAST(__LINE__) ? (ENAME = *BGL_FIRST(__LINE__), true):false; \
++BGL_FIRST(__LINE__))
#define BGL_FORALL_ADJ_T(UNAME, VNAME, GNAME, GraphType) \
for (typename boost::graph_traits<GraphType>::adjacency_iterator \
BGL_FIRST(__LINE__) = adjacent_vertices(UNAME, GNAME).first,\
BGL_LAST(__LINE__) = adjacent_vertices(UNAME, GNAME).second; \
BGL_FIRST(__LINE__) != BGL_LAST(__LINE__); BGL_FIRST(__LINE__) = BGL_LAST(__LINE__)) \
for (typename boost::graph_traits<GraphType>::vertex_descriptor VNAME; \
BGL_FIRST(__LINE__) != BGL_LAST(__LINE__) ? (VNAME = *BGL_FIRST(__LINE__), true) : false; \
++BGL_FIRST(__LINE__))
#define BGL_FORALL_ADJ(UNAME, VNAME, GNAME, GraphType) \
for (boost::graph_traits<GraphType>::adjacency_iterator \
BGL_FIRST(__LINE__) = adjacent_vertices(UNAME, GNAME).first,\
BGL_LAST(__LINE__) = adjacent_vertices(UNAME, GNAME).second; \
BGL_FIRST(__LINE__) != BGL_LAST(__LINE__); BGL_FIRST(__LINE__) = BGL_LAST(__LINE__)) \
for (boost::graph_traits<GraphType>::vertex_descriptor VNAME; \
BGL_FIRST(__LINE__) != BGL_LAST(__LINE__) ? (VNAME = *BGL_FIRST(__LINE__), true) : false; \
++BGL_FIRST(__LINE__))
#define BGL_FORALL_OUTEDGES_T(UNAME, ENAME, GNAME, GraphType) \
for (typename boost::graph_traits<GraphType>::out_edge_iterator \
BGL_FIRST(__LINE__) = out_edges(UNAME, GNAME).first,\
BGL_LAST(__LINE__) = out_edges(UNAME, GNAME).second; \
BGL_FIRST(__LINE__) != BGL_LAST(__LINE__); BGL_FIRST(__LINE__) = BGL_LAST(__LINE__)) \
for (typename boost::graph_traits<GraphType>::edge_descriptor ENAME; \
BGL_FIRST(__LINE__) != BGL_LAST(__LINE__) ? (ENAME = *BGL_FIRST(__LINE__), true) : false; \
++BGL_FIRST(__LINE__))
#define BGL_FORALL_OUTEDGES(UNAME, ENAME, GNAME, GraphType) \
for (boost::graph_traits<GraphType>::out_edge_iterator \
BGL_FIRST(__LINE__) = out_edges(UNAME, GNAME).first,\
BGL_LAST(__LINE__) = out_edges(UNAME, GNAME).second; \
BGL_FIRST(__LINE__) != BGL_LAST(__LINE__); BGL_FIRST(__LINE__) = BGL_LAST(__LINE__)) \
for (boost::graph_traits<GraphType>::edge_descriptor ENAME; \
BGL_FIRST(__LINE__) != BGL_LAST(__LINE__) ? (ENAME = *BGL_FIRST(__LINE__), true) : false; \
++BGL_FIRST(__LINE__))
#define BGL_FORALL_INEDGES_T(UNAME, ENAME, GNAME, GraphType) \
for (typename boost::graph_traits<GraphType>::in_edge_iterator \
BGL_FIRST(__LINE__) = in_edges(UNAME, GNAME).first,\
BGL_LAST(__LINE__) = in_edges(UNAME, GNAME).second; \
BGL_FIRST(__LINE__) != BGL_LAST(__LINE__); BGL_FIRST(__LINE__) = BGL_LAST(__LINE__)) \
for (typename boost::graph_traits<GraphType>::edge_descriptor ENAME; \
BGL_FIRST(__LINE__) != BGL_LAST(__LINE__) ? (ENAME = *BGL_FIRST(__LINE__), true) : false; \
++BGL_FIRST(__LINE__))
#define BGL_FORALL_INEDGES(UNAME, ENAME, GNAME, GraphType) \
for (boost::graph_traits<GraphType>::in_edge_iterator \
BGL_FIRST(__LINE__) = in_edges(UNAME, GNAME).first,\
BGL_LAST(__LINE__) = in_edges(UNAME, GNAME).second; \
BGL_FIRST(__LINE__) != BGL_LAST(__LINE__); BGL_FIRST(__LINE__) = BGL_LAST(__LINE__)) \
for (boost::graph_traits<GraphType>::edge_descriptor ENAME; \
BGL_FIRST(__LINE__) != BGL_LAST(__LINE__) ? (ENAME = *BGL_FIRST(__LINE__), true) : false; \
++BGL_FIRST(__LINE__))
#endif // BOOST_GRAPH_ITERATION_MACROS_HPP

View File

@@ -1,36 +0,0 @@
//=======================================================================
// Copyright 2002 Indiana University.
// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek
//
// This file is part of the Boost Graph Library
//
// You should have received a copy of the License Agreement for the
// Boost Graph Library along with the software; see the file LICENSE.
//
// Permission to modify the code and to distribute modified code is
// granted, provided the text of this NOTICE is retained, a notice that
// the code was modified is included with the above COPYRIGHT NOTICE and
// with the COPYRIGHT NOTICE in the LICENSE file, and that the LICENSE
// file is distributed with the modified code.
//
// LICENSOR MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED.
// By way of example, but not limitation, Licensor MAKES NO
// REPRESENTATIONS OR WARRANTIES OF MERCHANTABILITY OR FITNESS FOR ANY
// PARTICULAR PURPOSE OR THAT THE USE OF THE LICENSED SOFTWARE COMPONENTS
// OR DOCUMENTATION WILL NOT INFRINGE ANY PATENTS, COPYRIGHTS, TRADEMARKS
// OR OTHER RIGHTS.
//=======================================================================
#ifdef BOOST_GRAPH_ITERATION_MACROS_HPP
#undef BOOST_GRAPH_ITERATION_MACROS_HPP
#undef BGL_CAT
#undef BGL_FIRST
#undef BGL_LAST
#undef BGL_FORALL_VERTICES
#undef BGL_FORALL_EDGES
#undef BGL_FORALL_ADJACENT
#undef BGL_FORALL_OUTEDGES
#undef BGL_FORALL_INEDGES
#endif

View File

@@ -1,200 +0,0 @@
//=======================================================================
// Copyright 1997, 1998, 1999, 2000 University of Notre Dame.
// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek
//
// This file is part of the Boost Graph Library
//
// You should have received a copy of the License Agreement for the
// Boost Graph Library along with the software; see the file LICENSE.
// If not, contact Office of Research, University of Notre Dame, Notre
// Dame, IN 46556.
//
// Permission to modify the code and to distribute modified code is
// granted, provided the text of this NOTICE is retained, a notice that
// the code was modified is included with the above COPYRIGHT NOTICE and
// with the COPYRIGHT NOTICE in the LICENSE file, and that the LICENSE
// file is distributed with the modified code.
//
// LICENSOR MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED.
// By way of example, but not limitation, Licensor MAKES NO
// REPRESENTATIONS OR WARRANTIES OF MERCHANTABILITY OR FITNESS FOR ANY
// PARTICULAR PURPOSE OR THAT THE USE OF THE LICENSED SOFTWARE COMPONENTS
// OR DOCUMENTATION WILL NOT INFRINGE ANY PATENTS, COPYRIGHTS, TRADEMARKS
// OR OTHER RIGHTS.
//=======================================================================
/*
This file implements the function
template <class VertexAndEdgeListGraph, class DistanceMatrix,
class P, class T, class R>
bool
johnson_all_pairs_shortest_paths
(VertexAndEdgeListGraph& g,
DistanceMatrix& D,
const bgl_named_params<P, T, R>& params)
*/
#ifndef BOOST_GRAPH_JOHNSON_HPP
#define BOOST_GRAPH_JOHNSON_HPP
#include <boost/graph/graph_traits.hpp>
#include <boost/property_map.hpp>
#include <boost/graph/bellman_ford_shortest_paths.hpp>
#include <boost/graph/dijkstra_shortest_paths.hpp>
#include <boost/graph/adjacency_list.hpp>
#include <boost/pending/ct_if.hpp>
#include <boost/type_traits/same_traits.hpp>
namespace boost {
template <class VertexAndEdgeListGraph, class DistanceMatrix,
class VertexID, class Weight, class DistanceZero>
bool
johnson_all_pairs_shortest_paths(VertexAndEdgeListGraph& g1,
DistanceMatrix& D,
VertexID id1, Weight w1, DistanceZero zero)
{
typedef graph_traits<VertexAndEdgeListGraph> Traits1;
typedef typename property_traits<Weight>::value_type DT;
function_requires< BasicMatrixConcept<DistanceMatrix,
typename Traits1::vertices_size_type, DT> >();
typedef typename Traits1::directed_category DirCat;
bool is_undirected = is_same<DirCat, undirected_tag>::value;
typedef adjacency_list<vecS, vecS, directedS,
property< vertex_distance_t, DT>,
property< edge_weight_t, DT,
property< edge_weight2_t, DT > > > Graph2;
typedef graph_traits<Graph2> Traits2;
Graph2 g2(num_vertices(g1) + 1);
typename property_map<Graph2, edge_weight_t>::type
w = get(edge_weight, g2);
typename property_map<Graph2, edge_weight2_t>::type
w_hat = get(edge_weight2, g2);
typename property_map<Graph2, vertex_distance_t>::type
d = get(vertex_distance, g2);
typedef typename property_map<Graph2, vertex_index_t>::type VertexID2;
VertexID2 id2 = get(vertex_index, g2);
// Construct g2 where V[g2] = V[g1] U {s}
// and E[g2] = E[g1] U {(s,v)| v in V[g1]}
std::vector<typename Traits1::vertex_descriptor>
verts1(num_vertices(g1) + 1);
typename Traits2::vertex_descriptor s = *vertices(g2).first;
{
typename Traits1::vertex_iterator v, v_end;
int i = 1;
for (tie(v, v_end) = vertices(g1); v != v_end; ++v, ++i) {
typename Traits2::edge_descriptor e; bool z;
tie(e, z) = add_edge(s, id1[*v] + 1, g2);
w[e] = zero;
verts1[i] = *v;
}
typename Traits1::edge_iterator e, e_end;
for (tie(e, e_end) = edges(g1); e != e_end; ++e) {
typename Traits2::edge_descriptor e2; bool z;
tie(e2, z) = add_edge(id1[source(*e, g1)] + 1,
id1[target(*e, g1)] + 1, g2);
w[e2] = get(w1, *e);
if (is_undirected) {
tie(e2, z) = add_edge(id1[target(*e, g1)] + 1,
id1[source(*e, g1)] + 1, g2);
w[e2] = get(w1, *e);
}
}
}
typename Traits2::vertex_iterator v, v_end, u, u_end;
typename Traits2::edge_iterator e, e_end;
std::vector<DT> h_vec(num_vertices(g2));
typedef typename std::vector<DT>::iterator iter_t;
iterator_property_map<iter_t,VertexID2,DT,DT&> h(h_vec.begin(), id2);
DT inf = (std::numeric_limits<DT>::max)();
for (tie(v, v_end) = vertices(g2); v != v_end; ++v)
d[*v] = inf;
put(d, s, zero);
// Using the non-named parameter versions of bellman_ford and
// dijkstra for portability reasons.
dummy_property_map pred; closed_plus<DT> combine;
std::less<DT> compare; bellman_visitor<> bvis;
if (bellman_ford_shortest_paths
(g2, num_vertices(g2), w, pred, d, combine, compare, bvis)) {
for (tie(v, v_end) = vertices(g2); v != v_end; ++v)
put(h, *v, get(d, *v));
// Reweight the edges to remove negatives
for (tie(e, e_end) = edges(g2); e != e_end; ++e) {
typename Traits2::vertex_descriptor a = source(*e, g2),
b = target(*e, g2);
put(w_hat, *e, get(w, *e) + get(h, a) - get(h, b));
}
for (tie(u, u_end) = vertices(g2); u != u_end; ++u) {
dijkstra_visitor<> dvis;
dijkstra_shortest_paths
(g2, *u, pred, d, w_hat, id2, compare, combine, inf, zero,dvis);
for (tie(v, v_end) = vertices(g2); v != v_end; ++v) {
if (*u != s && *v != s) {
typename Traits1::vertex_descriptor u1, v1;
u1 = verts1[id2[*u]]; v1 = verts1[id2[*v]];
D[id2[*u]-1][id2[*v]-1] = get(d, *v) + get(h, *v) - get(h, *u);
}
}
}
return true;
} else
return false;
}
namespace detail {
template <class VertexAndEdgeListGraph, class DistanceMatrix,
class P, class T, class R, class Weight,
class VertexID>
bool
johnson_dispatch(VertexAndEdgeListGraph& g,
DistanceMatrix& D,
const bgl_named_params<P, T, R>& params,
Weight w, VertexID id)
{
typedef typename property_traits<Weight>::value_type WT;
return johnson_all_pairs_shortest_paths
(g, D, id, w,
choose_param(get_param(params, distance_zero_t()), WT()) );
}
} // namespace detail
template <class VertexAndEdgeListGraph, class DistanceMatrix,
class P, class T, class R>
bool
johnson_all_pairs_shortest_paths
(VertexAndEdgeListGraph& g,
DistanceMatrix& D,
const bgl_named_params<P, T, R>& params)
{
return detail::johnson_dispatch
(g, D, params,
choose_const_pmap(get_param(params, edge_weight), g, edge_weight),
choose_const_pmap(get_param(params, vertex_index), g, vertex_index)
);
}
template <class VertexAndEdgeListGraph, class DistanceMatrix>
bool
johnson_all_pairs_shortest_paths
(VertexAndEdgeListGraph& g, DistanceMatrix& D)
{
bgl_named_params<int,int> params(1);
return detail::johnson_dispatch
(g, D, params, get(edge_weight, g), get(vertex_index, g));
}
} // namespace boost
#endif // BOOST_GRAPH_JOHNSON_HPP

View File

@@ -1,501 +0,0 @@
// Copyright 2004 The Trustees of Indiana University.
// Use, modification and distribution is subject to the Boost Software
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// Authors: Douglas Gregor
// Andrew Lumsdaine
#ifndef BOOST_GRAPH_KAMADA_KAWAI_SPRING_LAYOUT_HPP
#define BOOST_GRAPH_KAMADA_KAWAI_SPRING_LAYOUT_HPP
#include <boost/graph/graph_traits.hpp>
#include <boost/graph/johnson_all_pairs_shortest.hpp>
#include <boost/type_traits/is_convertible.hpp>
#include <utility>
#include <iterator>
#include <vector>
#include <limits>
namespace boost {
namespace detail { namespace graph {
/**
* Denotes an edge or display area side length used to scale a
* Kamada-Kawai drawing.
*/
template<bool Edge, typename T>
struct edge_or_side
{
explicit edge_or_side(T value) : value(value) {}
T value;
};
/**
* Compute the edge length from an edge length. This is trivial.
*/
template<typename Graph, typename DistanceMap, typename IndexMap,
typename T>
T compute_edge_length(const Graph&, DistanceMap, IndexMap,
edge_or_side<true, T> length)
{ return length.value; }
/**
* Compute the edge length based on the display area side
length. We do this by dividing the side length by the largest
shortest distance between any two vertices in the graph.
*/
template<typename Graph, typename DistanceMap, typename IndexMap,
typename T>
T
compute_edge_length(const Graph& g, DistanceMap distance, IndexMap index,
edge_or_side<false, T> length)
{
T result(0);
typedef typename graph_traits<Graph>::vertex_iterator vertex_iterator;
for (vertex_iterator ui = vertices(g).first, end = vertices(g).second;
ui != end; ++ui) {
vertex_iterator vi = ui;
for (++vi; vi != end; ++vi) {
T dij = distance[get(index, *ui)][get(index, *vi)];
if (dij > result) result = dij;
}
}
return length.value / result;
}
/**
* Implementation of the Kamada-Kawai spring layout algorithm.
*/
template<typename Graph, typename PositionMap, typename WeightMap,
typename EdgeOrSideLength, typename Done,
typename VertexIndexMap, typename DistanceMatrix,
typename SpringStrengthMatrix, typename PartialDerivativeMap>
struct kamada_kawai_spring_layout_impl
{
typedef typename property_traits<WeightMap>::value_type weight_type;
typedef std::pair<weight_type, weight_type> deriv_type;
typedef typename graph_traits<Graph>::vertex_iterator vertex_iterator;
typedef typename graph_traits<Graph>::vertex_descriptor
vertex_descriptor;
kamada_kawai_spring_layout_impl(
const Graph& g,
PositionMap position,
WeightMap weight,
EdgeOrSideLength edge_or_side_length,
Done done,
weight_type spring_constant,
VertexIndexMap index,
DistanceMatrix distance,
SpringStrengthMatrix spring_strength,
PartialDerivativeMap partial_derivatives)
: g(g), position(position), weight(weight),
edge_or_side_length(edge_or_side_length), done(done),
spring_constant(spring_constant), index(index), distance(distance),
spring_strength(spring_strength),
partial_derivatives(partial_derivatives) {}
// Compute contribution of vertex i to the first partial
// derivatives (dE/dx_m, dE/dy_m) (for vertex m)
deriv_type
compute_partial_derivative(vertex_descriptor m, vertex_descriptor i)
{
deriv_type result(0, 0);
if (i != m) {
weight_type x_diff = position[m].x - position[i].x;
weight_type y_diff = position[m].y - position[i].y;
weight_type dist = sqrt(x_diff * x_diff + y_diff * y_diff);
result.first = spring_strength[get(index, m)][get(index, i)]
* (x_diff - distance[get(index, m)][get(index, i)]*x_diff/dist);
result.second = spring_strength[get(index, m)][get(index, i)]
* (y_diff - distance[get(index, m)][get(index, i)]*y_diff/dist);
}
return result;
}
// Compute partial derivatives dE/dx_m and dE/dy_m
deriv_type
compute_partial_derivatives(vertex_descriptor m)
{
using std::sqrt;
deriv_type result(0, 0);
// TBD: looks like an accumulate to me
std::pair<vertex_iterator, vertex_iterator> verts = vertices(g);
for (/* no init */; verts.first != verts.second; ++verts.first) {
vertex_descriptor i = *verts.first;
deriv_type deriv = compute_partial_derivative(m, i);
result.first += deriv.first;
result.second += deriv.second;
}
return result;
}
// The actual Kamada-Kawai spring layout algorithm implementation
bool run()
{
// Compute d_{ij} and place it in the distance matrix
if (!johnson_all_pairs_shortest_paths(g, distance, index, weight,
weight_type(0)))
return false;
// Compute L based on side length (if needed), or retrieve L
weight_type edge_length =
detail::graph::compute_edge_length(g, distance, index,
edge_or_side_length);
// Compute l_{ij} and k_{ij}
const weight_type K = spring_constant;
vertex_iterator ui, end = vertices(g).second;
for (ui = vertices(g).first; ui != end; ++ui) {
vertex_iterator vi = ui;
for (++vi; vi != end; ++vi) {
weight_type dij = distance[get(index, *ui)][get(index, *vi)];
distance[get(index, *ui)][get(index, *vi)] = edge_length * dij;
distance[get(index, *vi)][get(index, *ui)] = edge_length * dij;
spring_strength[get(index, *ui)][get(index, *vi)] = K/(dij*dij);
spring_strength[get(index, *vi)][get(index, *ui)] = K/(dij*dij);
}
}
// Compute Delta_i and find max
vertex_descriptor p = *vertices(g).first;
weight_type delta_p(0);
for (ui = vertices(g).first; ui != end; ++ui) {
deriv_type deriv = compute_partial_derivatives(*ui);
put(partial_derivatives, *ui, deriv);
weight_type delta =
sqrt(deriv.first*deriv.first + deriv.second*deriv.second);
if (delta > delta_p) {
p = *ui;
delta_p = delta;
}
}
while (!done(delta_p, p, g, true)) {
// The contribution p makes to the partial derivatives of
// each vertex. Computing this (at O(n) cost) allows us to
// update the delta_i values in O(n) time instead of O(n^2)
// time.
std::vector<deriv_type> p_partials(num_vertices(g));
for (ui = vertices(g).first; ui != end; ++ui) {
vertex_descriptor i = *ui;
p_partials[get(index, i)] = compute_partial_derivative(i, p);
}
do {
// Compute the 4 elements of the Jacobian
weight_type dE_dx_dx = 0, dE_dx_dy = 0, dE_dy_dx = 0, dE_dy_dy = 0;
for (ui = vertices(g).first; ui != end; ++ui) {
vertex_descriptor i = *ui;
if (i != p) {
weight_type x_diff = position[p].x - position[i].x;
weight_type y_diff = position[p].y - position[i].y;
weight_type dist = sqrt(x_diff * x_diff + y_diff * y_diff);
weight_type dist_cubed = dist * dist * dist;
weight_type k_mi = spring_strength[get(index,p)][get(index,i)];
weight_type l_mi = distance[get(index, p)][get(index, i)];
dE_dx_dx += k_mi * (1 - (l_mi * y_diff * y_diff)/dist_cubed);
dE_dx_dy += k_mi * l_mi * x_diff * y_diff / dist_cubed;
dE_dy_dx += k_mi * l_mi * x_diff * y_diff / dist_cubed;
dE_dy_dy += k_mi * (1 - (l_mi * x_diff * x_diff)/dist_cubed);
}
}
// Solve for delta_x and delta_y
weight_type dE_dx = get(partial_derivatives, p).first;
weight_type dE_dy = get(partial_derivatives, p).second;
weight_type delta_x =
(dE_dx_dy * dE_dy - dE_dy_dy * dE_dx)
/ (dE_dx_dx * dE_dy_dy - dE_dx_dy * dE_dy_dx);
weight_type delta_y =
(dE_dx_dx * dE_dy - dE_dy_dx * dE_dx)
/ (dE_dy_dx * dE_dx_dy - dE_dx_dx * dE_dy_dy);
// Move p by (delta_x, delta_y)
position[p].x += delta_x;
position[p].y += delta_y;
// Recompute partial derivatives and delta_p
deriv_type deriv = compute_partial_derivatives(p);
put(partial_derivatives, p, deriv);
delta_p =
sqrt(deriv.first*deriv.first + deriv.second*deriv.second);
} while (!done(delta_p, p, g, false));
// Select new p by updating each partial derivative and delta
vertex_descriptor old_p;
for (ui = vertices(g).first; ui != end; ++ui) {
deriv_type old_deriv_p = p_partials[get(index, *ui)];
deriv_type old_p_partial =
compute_partial_derivative(*ui, old_p);
deriv_type deriv = get(partial_derivatives, *ui);
deriv.first += old_p_partial.first - old_deriv_p.first;
deriv.second += old_p_partial.second - old_deriv_p.second;
put(partial_derivatives, *ui, deriv);
weight_type delta =
sqrt(deriv.first*deriv.first + deriv.second*deriv.second);
if (delta > delta_p) {
p = *ui;
delta_p = delta;
}
}
}
return true;
}
const Graph& g;
PositionMap position;
WeightMap weight;
EdgeOrSideLength edge_or_side_length;
Done done;
weight_type spring_constant;
VertexIndexMap index;
DistanceMatrix distance;
SpringStrengthMatrix spring_strength;
PartialDerivativeMap partial_derivatives;
};
} } // end namespace detail::graph
/// States that the given quantity is an edge length.
template<typename T>
inline detail::graph::edge_or_side<true, T>
edge_length(T x)
{ return detail::graph::edge_or_side<true, T>(x); }
/// States that the given quantity is a display area side length.
template<typename T>
inline detail::graph::edge_or_side<false, T>
side_length(T x)
{ return detail::graph::edge_or_side<false, T>(x); }
/**
* \brief Determines when to terminate layout of a particular graph based
* on a given tolerance.
*
* For local movements, where a single vertex is being moved toward
* a local minima the tolerance is taken as an absolute tolerance;
* for global movements, layout terminates when moving individual
* particles results in changes in the maximum vertex energy less
* than the tolerance.
*/
template<typename T = double>
struct layout_tolerance
{
layout_tolerance(const T& tolerance = T(0.01))
: tolerance(tolerance), last_energy(std::numeric_limits<T>::max()) { }
template<typename Graph>
bool
operator()(T delta_p,
typename boost::graph_traits<Graph>::vertex_descriptor p,
const Graph& g,
bool global)
{
if (global) {
double diff = fabs(last_energy - delta_p);
if (diff < T(0)) diff = -diff;
last_energy = delta_p;
return diff < tolerance;
} else {
return delta_p < tolerance;
}
}
private:
T tolerance;
T last_energy;
};
/** \brief Kamada-Kawai spring layout for undirected graphs.
*
* This algorithm performs graph layout (in two dimensions) for
* connected, undirected graphs. It operates by relating the layout
* of graphs to a dynamic spring system and minimizing the energy
* within that system. The strength of a spring between two vertices
* is inversely proportional to the square of the shortest distance
* (in graph terms) between those two vertices. Essentially,
* vertices that are closer in the graph-theoretic sense (i.e., by
* following edges) will have stronger springs and will therefore be
* placed closer together.
*
* Prior to invoking this algorithm, it is recommended that the
* vertices be placed along the vertices of a regular n-sided
* polygon.
*
* \param g (IN) must be a model of Vertex List Graph, Edge List
* Graph, and Incidence Graph and must be undirected.
*
* \param position (OUT) must be a model of Lvalue Property Map,
* where the value type is a class containing fields @c x and @c y
* that will be set to the @c x and @c y coordinates of each vertex.
*
* \param weight (IN) must be a model of Readable Property Map,
* which provides the weight of each edge in the graph @p g.
*
* \param edge_or_side_length (IN) provides either the unit length
* @c e of an edge in the layout or the length of a side @c s of the
* display area, and must be either @c boost::edge_length(e) or @c
* boost::side_length(s), respectively.
*
* \param done (IN) is a 4-argument function object that is passed
* the current value of delta_p (i.e., the energy of vertex @p p),
* the vertex @p p, the graph @p g, and a boolean flag indicating
* whether @p delta_p is the maximum energy in the system (when @c
* true) or the energy of the vertex being moved. Defaults to @c
* layout_tolerance instantiated over the value type of the weight
* map.
*
* \param spring_constant (IN) is the constant multiplied by each
* spring's strength. Larger values create systems with more energy
* that can take longer to stabilize; smaller values create systems
* with less energy that stabilize quickly but do not necessarily
* result in pleasing layouts. The default value is 1.
*
* \param index (IN) is a mapping from vertices to index values
* between 0 and @c num_vertices(g). The default is @c
* get(vertex_index,g).
*
* \param distance (UTIL/OUT) will be used to store the distance
* from every vertex to every other vertex, which is computed in the
* first stages of the algorithm. This value's type must be a model
* of BasicMatrix with value type equal to the value type of the
* weight map. The default is a a vector of vectors.
*
* \param spring_strength (UTIL/OUT) will be used to store the
* strength of the spring between every pair of vertices. This
* value's type must be a model of BasicMatrix with value type equal
* to the value type of the weight map. The default is a a vector of
* vectors.
*
* \param partial_derivatives (UTIL) will be used to store the
* partial derivates of each vertex with respect to the @c x and @c
* y coordinates. This must be a Read/Write Property Map whose value
* type is a pair with both types equivalent to the value type of
* the weight map. The default is an iterator property map.
*
* \returns @c true if layout was successful or @c false if a
* negative weight cycle was detected.
*/
template<typename Graph, typename PositionMap, typename WeightMap,
typename T, bool EdgeOrSideLength, typename Done,
typename VertexIndexMap, typename DistanceMatrix,
typename SpringStrengthMatrix, typename PartialDerivativeMap>
bool
kamada_kawai_spring_layout(
const Graph& g,
PositionMap position,
WeightMap weight,
detail::graph::edge_or_side<EdgeOrSideLength, T> edge_or_side_length,
Done done,
typename property_traits<WeightMap>::value_type spring_constant,
VertexIndexMap index,
DistanceMatrix distance,
SpringStrengthMatrix spring_strength,
PartialDerivativeMap partial_derivatives)
{
BOOST_STATIC_ASSERT((is_convertible<
typename graph_traits<Graph>::directed_category*,
undirected_tag*
>::value));
detail::graph::kamada_kawai_spring_layout_impl<
Graph, PositionMap, WeightMap,
detail::graph::edge_or_side<EdgeOrSideLength, T>, Done, VertexIndexMap,
DistanceMatrix, SpringStrengthMatrix, PartialDerivativeMap>
alg(g, position, weight, edge_or_side_length, done, spring_constant,
index, distance, spring_strength, partial_derivatives);
return alg.run();
}
/**
* \overload
*/
template<typename Graph, typename PositionMap, typename WeightMap,
typename T, bool EdgeOrSideLength, typename Done,
typename VertexIndexMap>
bool
kamada_kawai_spring_layout(
const Graph& g,
PositionMap position,
WeightMap weight,
detail::graph::edge_or_side<EdgeOrSideLength, T> edge_or_side_length,
Done done,
typename property_traits<WeightMap>::value_type spring_constant,
VertexIndexMap index)
{
typedef typename property_traits<WeightMap>::value_type weight_type;
typename graph_traits<Graph>::vertices_size_type n = num_vertices(g);
typedef std::vector<weight_type> weight_vec;
std::vector<weight_vec> distance(n, weight_vec(n));
std::vector<weight_vec> spring_strength(n, weight_vec(n));
std::vector<std::pair<weight_type, weight_type> > partial_derivatives(n);
return
kamada_kawai_spring_layout(
g, position, weight, edge_or_side_length, done, spring_constant, index,
distance.begin(),
spring_strength.begin(),
make_iterator_property_map(partial_derivatives.begin(), index));
}
/**
* \overload
*/
template<typename Graph, typename PositionMap, typename WeightMap,
typename T, bool EdgeOrSideLength, typename Done>
bool
kamada_kawai_spring_layout(
const Graph& g,
PositionMap position,
WeightMap weight,
detail::graph::edge_or_side<EdgeOrSideLength, T> edge_or_side_length,
Done done,
typename property_traits<WeightMap>::value_type spring_constant =
typename property_traits<WeightMap>::value_type(1))
{
return kamada_kawai_spring_layout(g, position, weight, edge_or_side_length,
done, spring_constant,
get(vertex_index, g));
}
/**
* \overload
*/
template<typename Graph, typename PositionMap, typename WeightMap,
typename T, bool EdgeOrSideLength>
bool
kamada_kawai_spring_layout(
const Graph& g,
PositionMap position,
WeightMap weight,
detail::graph::edge_or_side<EdgeOrSideLength, T> edge_or_side_length)
{
typedef typename property_traits<WeightMap>::value_type weight_type;
return kamada_kawai_spring_layout(g, position, weight, edge_or_side_length,
layout_tolerance<weight_type>(),
weight_type(1.0),
get(vertex_index, g));
}
} // end namespace boost
#endif // BOOST_GRAPH_KAMADA_KAWAI_SPRING_LAYOUT_HPP

View File

@@ -1,168 +0,0 @@
//
//=======================================================================
// Copyright 1997, 1998, 1999, 2000 University of Notre Dame.
// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek
//
// This file is part of the Boost Graph Library
//
// You should have received a copy of the License Agreement for the
// Boost Graph Library along with the software; see the file LICENSE.
// If not, contact Office of Research, University of Notre Dame, Notre
// Dame, IN 46556.
//
// Permission to modify the code and to distribute modified code is
// granted, provided the text of this NOTICE is retained, a notice that
// the code was modified is included with the above COPYRIGHT NOTICE and
// with the COPYRIGHT NOTICE in the LICENSE file, and that the LICENSE
// file is distributed with the modified code.
//
// LICENSOR MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED.
// By way of example, but not limitation, Licensor MAKES NO
// REPRESENTATIONS OR WARRANTIES OF MERCHANTABILITY OR FITNESS FOR ANY
// PARTICULAR PURPOSE OR THAT THE USE OF THE LICENSED SOFTWARE COMPONENTS
// OR DOCUMENTATION WILL NOT INFRINGE ANY PATENTS, COPYRIGHTS, TRADEMARKS
// OR OTHER RIGHTS.
//=======================================================================
//
#ifndef BOOST_GRAPH_MST_KRUSKAL_HPP
#define BOOST_GRAPH_MST_KRUSKAL_HPP
/*
*Minimum Spanning Tree
* Kruskal Algorithm
*
*Requirement:
* undirected graph
*/
#include <vector>
#include <queue>
#include <functional>
#include <boost/property_map.hpp>
#include <boost/graph/graph_concepts.hpp>
#include <boost/graph/named_function_params.hpp>
#include <boost/pending/disjoint_sets.hpp>
#include <boost/pending/indirect_cmp.hpp>
namespace boost {
// Kruskal's algorithm for Minimum Spanning Tree
//
// This is a greedy algorithm to calculate the Minimum Spanning Tree
// for an undirected graph with weighted edges. The output will be a
// set of edges.
//
namespace detail {
template <class Graph, class OutputIterator,
class Rank, class Parent, class Weight>
void
kruskal_mst_impl(const Graph& G,
OutputIterator spanning_tree_edges,
Rank rank, Parent parent, Weight weight)
{
typedef typename graph_traits<Graph>::vertex_descriptor Vertex;
typedef typename graph_traits<Graph>::edge_descriptor Edge;
function_requires<VertexListGraphConcept<Graph> >();
function_requires<EdgeListGraphConcept<Graph> >();
function_requires<OutputIteratorConcept<OutputIterator, Edge> >();
function_requires<ReadWritePropertyMapConcept<Rank, Vertex> >();
function_requires<ReadWritePropertyMapConcept<Parent, Vertex> >();
function_requires<ReadablePropertyMapConcept<Weight, Edge> >();
typedef typename property_traits<Weight>::value_type W_value;
typedef typename property_traits<Rank>::value_type R_value;
typedef typename property_traits<Parent>::value_type P_value;
function_requires<ComparableConcept<W_value> >();
function_requires<ConvertibleConcept<P_value, Vertex> >();
function_requires<IntegerConcept<R_value> >();
disjoint_sets<Rank, Parent> dset(rank, parent);
typename graph_traits<Graph>::vertex_iterator ui, uiend;
for (boost::tie(ui, uiend) = vertices(G); ui != uiend; ++ui)
dset.make_set(*ui);
typedef indirect_cmp<Weight, std::greater<W_value> > weight_greater;
weight_greater wl(weight);
std::priority_queue<Edge, std::vector<Edge>, weight_greater> Q(wl);
/*push all edge into Q*/
typename graph_traits<Graph>::edge_iterator ei, eiend;
for (boost::tie(ei, eiend) = edges(G); ei != eiend; ++ei)
Q.push(*ei);
while (! Q.empty()) {
Edge e = Q.top();
Q.pop();
Vertex u = dset.find_set(source(e, G));
Vertex v = dset.find_set(target(e, G));
if ( u != v ) {
*spanning_tree_edges++ = e;
dset.link(u, v);
}
}
}
} // namespace detail
// Named Parameters Variants
template <class Graph, class OutputIterator>
inline void
kruskal_minimum_spanning_tree(const Graph& g,
OutputIterator spanning_tree_edges)
{
typedef typename graph_traits<Graph>::vertices_size_type size_type;
typedef typename graph_traits<Graph>::vertex_descriptor vertex_t;
typedef typename property_map<Graph, vertex_index_t>::type index_map_t;
typename graph_traits<Graph>::vertices_size_type
n = num_vertices(g);
std::vector<size_type> rank_map(n);
std::vector<vertex_t> pred_map(n);
detail::kruskal_mst_impl
(g, spanning_tree_edges,
make_iterator_property_map(rank_map.begin(), get(vertex_index, g), rank_map[0]),
make_iterator_property_map(pred_map.begin(), get(vertex_index, g), pred_map[0]),
get(edge_weight, g));
}
template <class Graph, class OutputIterator, class P, class T, class R>
inline void
kruskal_minimum_spanning_tree(const Graph& g,
OutputIterator spanning_tree_edges,
const bgl_named_params<P, T, R>& params)
{
typedef typename graph_traits<Graph>::vertices_size_type size_type;
typedef typename graph_traits<Graph>::vertex_descriptor vertex_t;
typename graph_traits<Graph>::vertices_size_type n;
n = is_default_param(get_param(params, vertex_rank))
? num_vertices(g) : 1;
std::vector<size_type> rank_map(n);
n = is_default_param(get_param(params, vertex_predecessor))
? num_vertices(g) : 1;
std::vector<vertex_t> pred_map(n);
detail::kruskal_mst_impl
(g, spanning_tree_edges,
choose_param
(get_param(params, vertex_rank),
make_iterator_property_map
(rank_map.begin(),
choose_pmap(get_param(params, vertex_index), g, vertex_index), rank_map[0])),
choose_param
(get_param(params, vertex_predecessor),
make_iterator_property_map
(pred_map.begin(),
choose_const_pmap(get_param(params, vertex_index), g, vertex_index),
pred_map[0])),
choose_const_pmap(get_param(params, edge_weight), g, edge_weight));
}
} // namespace boost
#endif // BOOST_GRAPH_MST_KRUSKAL_HPP

View File

@@ -1,587 +0,0 @@
//=======================================================================
// Copyright 1997, 1998, 1999, 2000 University of Notre Dame.
// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek
//
// This file is part of the Boost Graph Library
//
// You should have received a copy of the License Agreement for the
// Boost Graph Library along with the software; see the file LICENSE.
// If not, contact Office of Research, University of Notre Dame, Notre
// Dame, IN 46556.
//
// Permission to modify the code and to distribute modified code is
// granted, provided the text of this NOTICE is retained, a notice that
// the code was modified is included with the above COPYRIGHT NOTICE and
// with the COPYRIGHT NOTICE in the LICENSE file, and that the LICENSE
// file is distributed with the modified code.
//
// LICENSOR MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED.
// By way of example, but not limitation, Licensor MAKES NO
// REPRESENTATIONS OR WARRANTIES OF MERCHANTABILITY OR FITNESS FOR ANY
// PARTICULAR PURPOSE OR THAT THE USE OF THE LICENSED SOFTWARE COMPONENTS
// OR DOCUMENTATION WILL NOT INFRINGE ANY PATENTS, COPYRIGHTS, TRADEMARKS
// OR OTHER RIGHTS.
//=======================================================================
#ifndef BOOST_GRAPH_LEDA_HPP
#define BOOST_GRAPH_LEDA_HPP
#include <boost/config.hpp>
#include <boost/iterator_adaptors.hpp>
#include <boost/graph/graph_traits.hpp>
#include <boost/graph/properties.hpp>
#include <LEDA/graph.h>
#include <LEDA/node_array.h>
#include <LEDA/node_map.h>
// The functions and classes in this file allows the user to
// treat a LEDA GRAPH object as a boost graph "as is". No
// wrapper is needed for the GRAPH object.
// Remember to define LEDA_PREFIX so that LEDA types such as
// leda_edge show up as "leda_edge" and not just "edge".
// Warning: this implementation relies on partial specialization
// for the graph_traits class (so it won't compile with Visual C++)
// Warning: this implementation is in alpha and has not been tested
namespace boost {
struct leda_out_edge_iterator_policies
{
static void initialize(leda_edge& ) { }
template <typename Iter>
static void increment(Iter& i)
{ i.base() = Succ_Adj_Edge(i.base(), 0); }
template <typename Iter>
static void decrement(Iter& i)
{ i.base() = Pred_Adj_Edge(i.base(), 0); }
template <typename Iter>
static leda_edge dereference(const Iter& i)
{ return i.base(); }
template <typename Iter>
static bool equal(const Iter& x, const Iter& y)
{ return x.base() == y.base(); }
};
struct leda_in_edge_iterator_policies
{
static void initialize(leda_edge& ) { }
template <typename Iter>
static void increment(Iter& i)
{ i.base() = Succ_Adj_Edge(i.base(), 1); }
template <typename Iter>
static void decrement(Iter& i)
{ i.bae() = Pred_Adj_Edge(i.base(), 1); }
template <typename Iter>
static leda_edge dereference(const Iter& i)
{ return i.base(); }
template <typename Iter>
static bool equal(const Iter& x, const Iter& y)
{ return x.base() == y.base(); }
};
struct leda_adjacency_iterator_policies
{
static void initialize(leda_edge& ) { }
template <typename Iter>
static void increment(Iter& i)
{ i.base() = Succ_Adj_Edge(i.base(), 0); }
template <typename Iter>
static void decrement(Iter& i)
{ i.base() = Pred_Adj_Edge(i.base(), 0); }
template <typename Iter>
static leda_node dereference(const Iter& i)
{ return ::target(i.base()); }
template <typename Iter>
static bool equal(const Iter& x, const Iter& y)
{ return x.base() == y.base(); }
};
template <class LedaGraph>
struct leda_vertex_iterator_policies
{
leda_vertex_iterator_policies() { }
leda_vertex_iterator_policies(const LedaGraph* g) : m_g(g) { }
void initialize(leda_node& v) const { }
template <typename Iter>
void increment(Iter& i) const
{ i.base() = m_g->succ_node(i.base()); }
template <typename Iter>
void decrement(Iter& i) const
{ i.base() = m_g->pred_node(i.base()); }
template <typename Iter>
leda_node dereference(const Iter& i) const
{ return i.base(); }
template <typename Iter>
static bool equal(const Iter& x, const Iter& y)
{ return x.base() == y.base(); }
const LedaGraph* m_g;
};
} // namespace boost
#if !defined BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
namespace boost {
struct leda_graph_traversal_category :
public virtual bidirectional_graph_tag,
public virtual adjacency_graph_tag,
public virtual vertex_list_graph_tag { };
template <class vtype, class etype>
struct graph_traits< GRAPH<vtype,etype> > {
typedef leda_node vertex_descriptor;
typedef leda_edge edge_descriptor;
typedef boost::iterator_adaptor<leda_edge,
boost::leda_adjacency_iterator_policies,
leda_node, leda_node, const leda_node*,
boost::multi_pass_input_iterator_tag,
std::ptrdiff_t
> adjacency_iterator;
typedef boost::iterator_adaptor<leda_edge,
boost::leda_out_edge_iterator_policies,
leda_edge, const leda_edge&, const leda_edge*,
std::forward_iterator_tag,
std::ptrdiff_t
> out_edge_iterator;
typedef boost::iterator_adaptor<leda_edge,
boost::leda_in_edge_iterator_policies,
leda_edge, const leda_edge&, const leda_edge*,
std::forward_iterator_tag,
std::ptrdiff_t
> in_edge_iterator;
typedef boost::iterator_adaptor<leda_node,
boost::leda_vertex_iterator_policies< GRAPH<vtype,etype> >,
leda_node, leda_node, const leda_node*,
boost::multi_pass_input_iterator_tag,
std::ptrdiff_t
> vertex_iterator;
typedef directed_tag directed_category;
typedef allow_parallel_edge_tag edge_parallel_category; // not sure here
typedef leda_graph_traversal_category traversal_category;
typedef int vertices_size_type;
typedef int edges_size_type;
typedef int degree_size_type;
};
template <class vtype, class etype>
struct vertex_property< GRAPH<vtype,etype> > {
typedef vtype type;
};
template <class vtype, class etype>
struct edge_property< GRAPH<vtype,etype> > {
typedef etype type;
};
} // namespace boost
#endif
namespace boost {
template <class vtype, class etype>
typename graph_traits< GRAPH<vtype,etype> >::vertex_descriptor
source(typename graph_traits< GRAPH<vtype,etype> >::edge_descriptor e,
const GRAPH<vtype,etype>& g)
{
return source(e);
}
template <class vtype, class etype>
typename graph_traits< GRAPH<vtype,etype> >::vertex_descriptor
target(typename graph_traits< GRAPH<vtype,etype> >::edge_descriptor e,
const GRAPH<vtype,etype>& g)
{
return target(e);
}
template <class vtype, class etype>
inline std::pair<
typename graph_traits< GRAPH<vtype,etype> >::vertex_iterator,
typename graph_traits< GRAPH<vtype,etype> >::vertex_iterator >
vertices(const GRAPH<vtype,etype>& g)
{
typedef typename graph_traits< GRAPH<vtype,etype> >::vertex_iterator
Iter;
return std::make_pair( Iter(g.first_node(),&g), Iter(0,&g) );
}
// no edges(g) function
template <class vtype, class etype>
inline std::pair<
typename graph_traits< GRAPH<vtype,etype> >::out_edge_iterator,
typename graph_traits< GRAPH<vtype,etype> >::out_edge_iterator >
out_edges(
typename graph_traits< GRAPH<vtype,etype> >::vertex_descriptor u,
const GRAPH<vtype,etype>& g)
{
typedef typename graph_traits< GRAPH<vtype,etype> >
::out_edge_iterator Iter;
return std::make_pair( Iter(First_Adj_Edge(u,0)), Iter(0) );
}
template <class vtype, class etype>
inline std::pair<
typename graph_traits< GRAPH<vtype,etype> >::in_edge_iterator,
typename graph_traits< GRAPH<vtype,etype> >::in_edge_iterator >
in_edges(
typename graph_traits< GRAPH<vtype,etype> >::vertex_descriptor u,
const GRAPH<vtype,etype>& g)
{
typedef typename graph_traits< GRAPH<vtype,etype> >
::in_edge_iterator Iter;
return std::make_pair( Iter(First_Adj_Edge(u,1)), Iter(0) );
}
template <class vtype, class etype>
inline std::pair<
typename graph_traits< GRAPH<vtype,etype> >::adjacency_iterator,
typename graph_traits< GRAPH<vtype,etype> >::adjacency_iterator >
adjacent_vertices(
typename graph_traits< GRAPH<vtype,etype> >::vertex_descriptor u,
const GRAPH<vtype,etype>& g)
{
typedef typename graph_traits< GRAPH<vtype,etype> >
::adjacency_iterator Iter;
return std::make_pair( Iter(First_Adj_Edge(u,0)), Iter(0) );
}
template <class vtype, class etype>
typename graph_traits< GRAPH<vtype,etype> >::vertices_size_type
num_vertices(const GRAPH<vtype,etype>& g)
{
return g.number_of_nodes();
}
template <class vtype, class etype>
typename graph_traits< GRAPH<vtype,etype> >::edges_size_type
num_edges(const GRAPH<vtype,etype>& g)
{
return g.number_of_edges();
}
template <class vtype, class etype>
typename graph_traits< GRAPH<vtype,etype> >::degree_size_type
out_degree(
typename graph_traits< GRAPH<vtype,etype> >::vertex_descriptor u,
const GRAPH<vtype,etype>&)
{
return outdeg(u);
}
template <class vtype, class etype>
typename graph_traits< GRAPH<vtype,etype> >::degree_size_type
in_degree(
typename graph_traits< GRAPH<vtype,etype> >::vertex_descriptor u,
const GRAPH<vtype,etype>&)
{
return indeg(u);
}
template <class vtype, class etype>
typename graph_traits< GRAPH<vtype,etype> >::degree_size_type
degree(
typename graph_traits< GRAPH<vtype,etype> >::vertex_descriptor u,
const GRAPH<vtype,etype>&)
{
return outdeg(u) + indeg(u);
}
template <class vtype, class etype>
typename graph_traits< GRAPH<vtype,etype> >::vertex_descriptor
add_vertex(GRAPH<vtype,etype>& g)
{
return g.new_node();
}
template <class vtype, class etype>
typename graph_traits< GRAPH<vtype,etype> >::vertex_descriptor
add_vertex(const vtype& vp, GRAPH<vtype,etype>& g)
{
return g.new_node(vp);
}
// Hmm, LEDA doesn't have the equivalent of clear_vertex() -JGS
// need to write an implementation
template <class vtype, class etype>
void clear_vertex(
typename graph_traits< GRAPH<vtype,etype> >::vertex_descriptor u,
GRAPH<vtype,etype>& g)
{
g.del_node(u);
}
template <class vtype, class etype>
void remove_vertex(
typename graph_traits< GRAPH<vtype,etype> >::vertex_descriptor u,
GRAPH<vtype,etype>& g)
{
g.del_node(u);
}
template <class vtype, class etype>
std::pair<
typename graph_traits< GRAPH<vtype,etype> >::edge_descriptor,
bool>
add_edge(
typename graph_traits< GRAPH<vtype,etype> >::vertex_descriptor u,
typename graph_traits< GRAPH<vtype,etype> >::vertex_descriptor v,
GRAPH<vtype,etype>& g)
{
return std::make_pair(g.new_edge(u, v), true);
}
template <class vtype, class etype>
std::pair<
typename graph_traits< GRAPH<vtype,etype> >::edge_descriptor,
bool>
add_edge(
typename graph_traits< GRAPH<vtype,etype> >::vertex_descriptor u,
typename graph_traits< GRAPH<vtype,etype> >::vertex_descriptor v,
const etype& et,
GRAPH<vtype,etype>& g)
{
return std::make_pair(g.new_edge(u, v, et), true);
}
template <class vtype, class etype>
void
remove_edge(
typename graph_traits< GRAPH<vtype,etype> >::vertex_descriptor u,
typename graph_traits< GRAPH<vtype,etype> >::vertex_descriptor v,
GRAPH<vtype,etype>& g)
{
typename graph_traits< GRAPH<vtype,etype> >::out_edge_iterator
i,iend;
for (boost::tie(i,iend) = out_edges(u,g); i != iend; ++i)
if (target(*i,g) == v)
g.del_edge(*i);
}
template <class vtype, class etype>
void
remove_edge(
typename graph_traits< GRAPH<vtype,etype> >::edge_descriptor e,
GRAPH<vtype,etype>& g)
{
g.del_edge(e);
}
//===========================================================================
// property maps
class leda_graph_id_map
: public put_get_helper<int, leda_graph_id_map>
{
public:
typedef readable_property_map_tag category;
typedef int value_type;
typedef int reference;
typedef leda_node key_type;
leda_graph_id_map() { }
template <class T>
long operator[](T x) const { return x->id(); }
};
template <class vtype, class etype>
inline leda_graph_id_map
get(vertex_index_t, const GRAPH<vtype, etype>& g) {
return leda_graph_id_map();
}
template <class vtype, class etype>
inline leda_graph_id_map
get(edge_index_t, const GRAPH<vtype, etype>& g) {
return leda_graph_id_map();
}
template <class Tag>
struct leda_property_map { };
template <>
struct leda_property_map<vertex_index_t> {
template <class vtype, class etype>
struct bind_ {
typedef leda_graph_id_map type;
typedef leda_graph_id_map const_type;
};
};
template <>
struct leda_property_map<edge_index_t> {
template <class vtype, class etype>
struct bind_ {
typedef leda_graph_id_map type;
typedef leda_graph_id_map const_type;
};
};
template <class Data, class DataRef, class GraphPtr>
class leda_graph_data_map
: public put_get_helper<DataRef,
leda_graph_data_map<Data,DataRef,GraphPtr> >
{
public:
typedef Data value_type;
typedef DataRef reference;
typedef void key_type;
typedef lvalue_property_map_tag category;
leda_graph_data_map(GraphPtr g) : m_g(g) { }
template <class NodeOrEdge>
DataRef operator[](NodeOrEdge x) const { return (*m_g)[x]; }
protected:
GraphPtr m_g;
};
template <>
struct leda_property_map<vertex_all_t> {
template <class vtype, class etype>
struct bind_ {
typedef leda_graph_data_map<vtype, vtype&, GRAPH<vtype, etype>*> type;
typedef leda_graph_data_map<vtype, const vtype&,
const GRAPH<vtype, etype>*> const_type;
};
};
template <class vtype, class etype >
inline typename property_map< GRAPH<vtype, etype>, vertex_all_t>::type
get(vertex_all_t, GRAPH<vtype, etype>& g) {
typedef typename property_map< GRAPH<vtype, etype>, vertex_all_t>::type
pmap_type;
return pmap_type(&g);
}
template <class vtype, class etype >
inline typename property_map< GRAPH<vtype, etype>, vertex_all_t>::const_type
get(vertex_all_t, const GRAPH<vtype, etype>& g) {
typedef typename property_map< GRAPH<vtype, etype>,
vertex_all_t>::const_type pmap_type;
return pmap_type(&g);
}
template <>
struct leda_property_map<edge_all_t> {
template <class vtype, class etype>
struct bind_ {
typedef leda_graph_data_map<etype, etype&, GRAPH<vtype, etype>*> type;
typedef leda_graph_data_map<etype, const etype&,
const GRAPH<vtype, etype>*> const_type;
};
};
template <class vtype, class etype >
inline typename property_map< GRAPH<vtype, etype>, edge_all_t>::type
get(edge_all_t, GRAPH<vtype, etype>& g) {
typedef typename property_map< GRAPH<vtype, etype>, edge_all_t>::type
pmap_type;
return pmap_type(&g);
}
template <class vtype, class etype >
inline typename property_map< GRAPH<vtype, etype>, edge_all_t>::const_type
get(edge_all_t, const GRAPH<vtype, etype>& g) {
typedef typename property_map< GRAPH<vtype, etype>,
edge_all_t>::const_type pmap_type;
return pmap_type(&g);
}
// property map interface to the LEDA node_array class
template <class E, class ERef, class NodeMapPtr>
class leda_node_property_map
: public put_get_helper<ERef, leda_node_property_map<E, ERef, NodeMapPtr> >
{
public:
typedef E value_type;
typedef ERef reference;
typedef leda_node key_type;
typedef lvalue_property_map_tag category;
leda_node_property_map(NodeMapPtr a) : m_array(a) { }
ERef operator[](leda_node n) const { return (*m_array)[n]; }
protected:
NodeMapPtr m_array;
};
template <class E>
leda_node_property_map<E, const E&, const leda_node_array<E>*>
make_leda_node_property_map(const leda_node_array<E>& a)
{
typedef leda_node_property_map<E, const E&, const leda_node_array<E>*>
pmap_type;
return pmap_type(&a);
}
template <class E>
leda_node_property_map<E, E&, leda_node_array<E>*>
make_leda_node_property_map(leda_node_array<E>& a)
{
typedef leda_node_property_map<E, E&, leda_node_array<E>*> pmap_type;
return pmap_type(&a);
}
template <class E>
leda_node_property_map<E, const E&, const leda_node_map<E>*>
make_leda_node_property_map(const leda_node_map<E>& a)
{
typedef leda_node_property_map<E,const E&,const leda_node_map<E>*>
pmap_type;
return pmap_type(&a);
}
template <class E>
leda_node_property_map<E, E&, leda_node_map<E>*>
make_leda_node_property_map(leda_node_map<E>& a)
{
typedef leda_node_property_map<E, E&, leda_node_map<E>*> pmap_type;
return pmap_type(&a);
}
// g++ 'enumeral_type' in template unification not implemented workaround
template <class vtype, class etype, class Tag>
struct property_map<GRAPH<vtype, etype>, Tag> {
typedef typename
leda_property_map<Tag>::template bind_<vtype, etype> map_gen;
typedef typename map_gen::type type;
typedef typename map_gen::const_type const_type;
};
template <class vtype, class etype, class PropertyTag, class Key>
inline
typename boost::property_traits<
typename boost::property_map<GRAPH<vtype, etype>,PropertyTag>::const_type
>::value_type
get(PropertyTag p, const GRAPH<vtype, etype>& g, const Key& key) {
return get(get(p, g), key);
}
template <class vtype, class etype, class PropertyTag, class Key,class Value>
inline void
put(PropertyTag p, GRAPH<vtype, etype>& g,
const Key& key, const Value& value)
{
typedef typename property_map<GRAPH<vtype, etype>, PropertyTag>::type Map;
Map pmap = get(p, g);
put(pmap, key, value);
}
} // namespace boost
#endif // BOOST_GRAPH_LEDA_HPP

View File

@@ -1,143 +0,0 @@
//
//=======================================================================
// Copyright 1997, 1998, 1999, 2000 University of Notre Dame.
// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek
//
// This file is part of the Boost Graph Library
//
// You should have received a copy of the License Agreement for the
// Boost Graph Library along with the software; see the file LICENSE.
// If not, contact Office of Research, University of Notre Dame, Notre
// Dame, IN 46556.
//
// Permission to modify the code and to distribute modified code is
// granted, provided the text of this NOTICE is retained, a notice that
// the code was modified is included with the above COPYRIGHT NOTICE and
// with the COPYRIGHT NOTICE in the LICENSE file, and that the LICENSE
// file is distributed with the modified code.
//
// LICENSOR MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED.
// By way of example, but not limitation, Licensor MAKES NO
// REPRESENTATIONS OR WARRANTIES OF MERCHANTABILITY OR FITNESS FOR ANY
// PARTICULAR PURPOSE OR THAT THE USE OF THE LICENSED SOFTWARE COMPONENTS
// OR DOCUMENTATION WILL NOT INFRINGE ANY PATENTS, COPYRIGHTS, TRADEMARKS
// OR OTHER RIGHTS.
//=======================================================================
//
#ifndef BOOST_GRAPH_MATRIX2GRAPH_HPP
#define BOOST_GRAPH_MATRIX2GRAPH_HPP
#include <utility>
#include <boost/config.hpp>
#include <boost/operators.hpp>
#include <boost/int_iterator.hpp>
#include <boost/graph/graph_traits.hpp>
namespace boost {
template <class Iter, class Vertex>
class matrix_adj_iterator;
template <class Iter, class Vertex>
class matrix_incidence_iterator;
}
#define BOOST_GRAPH_ADAPT_MATRIX_TO_GRAPH(Matrix) \
namespace boost { \
template <> \
struct graph_traits< Matrix > { \
typedef Matrix::OneD::const_iterator Iter; \
typedef Matrix::size_type V; \
typedef V vertex_descriptor; \
typedef Iter E; \
typedef E edge_descriptor; \
typedef boost::matrix_incidence_iterator<Iter, V> out_edge_iterator; \
typedef boost::matrix_adj_iterator<Iter, V> adjacency_iterator; \
typedef Matrix::size_type size_type; \
typedef boost::int_iterator<size_type> vertex_iterator; \
\
friend std::pair<vertex_iterator, vertex_iterator> \
vertices(const Matrix& g) { \
typedef vertex_iterator VIter; \
return std::make_pair(VIter(0), VIter(g.nrows())); \
} \
\
friend std::pair<out_edge_iterator, out_edge_iterator> \
out_edges(V v, const Matrix& g) { \
typedef out_edge_iterator IncIter; \
return std::make_pair(IncIter(g[v].begin()), \
IncIter(g[v].end())); \
} \
friend std::pair<adjacency_iterator, adjacency_iterator> \
adjacent_vertices(V v, const Matrix& g) { \
typedef adjacency_iterator AdjIter; \
return std::make_pair(AdjIter(g[v].begin()), \
AdjIter(g[v].end())); \
} \
friend vertex_descriptor \
source(E e, const Matrix& g) { \
return e.row(); \
} \
friend vertex_descriptor \
target(E e, const Matrix& g) { \
return e.column(); \
} \
friend size_type \
num_vertices(const Matrix& g) { \
return g.nrows(); \
} \
friend size_type \
num_edges(const Matrix& g) { \
return g.nnz(); \
} \
friend size_type \
out_degree(V i, const Matrix& g) { \
return g[i].nnz(); \
} \
}; \
}
namespace boost {
template <class Iter, class Vertex>
class matrix_adj_iterator
: public std::iterator<std::input_iterator_tag, Vertex >
{
typedef matrix_adj_iterator self;
public:
matrix_adj_iterator() { }
matrix_adj_iterator(Iter i) : _iter(i) { }
matrix_adj_iterator(const self& x) : _iter(x._iter) { }
self& operator=(const self& x) { _iter = x._iter; return *this; }
Vertex operator*() { return _iter.column(); }
self& operator++() { ++_iter; return *this; }
self operator++(int) { self t = *this; ++_iter; return t; }
bool operator==(const self& x) const { return _iter == x._iter; }
bool operator!=(const self& x) const { return _iter != x._iter; }
protected:
Iter _iter;
};
template <class Iter, class Vertex>
class matrix_incidence_iterator
: public std::iterator<std::input_iterator_tag, Iter >
{
typedef matrix_incidence_iterator self;
public:
matrix_incidence_iterator() { }
matrix_incidence_iterator(Iter i) : _iter(i) { }
matrix_incidence_iterator(const self& x) : _iter(x._iter) { }
self& operator=(const self& x) { _iter = x._iter; return *this; }
Iter operator*() { return _iter; }
self& operator++() { ++_iter; return *this; }
self operator++(int) { self t = *this; ++_iter; return t; }
bool operator==(const self& x) const { return _iter == x._iter; }
bool operator!=(const self& x) const { return _iter != x._iter; }
protected:
Iter _iter;
};
} /* namespace boost */
#endif /* BOOST_GRAPH_MATRIX2GRAPH_HPP*/

View File

@@ -1,669 +0,0 @@
//-*-c++-*-
//=======================================================================
// Copyright 1997-2001 University of Notre Dame.
// Authors: Lie-Quan Lee, Jeremy Siek
//
// This file is part of the Boost Graph Library
//
// You should have received a copy of the License Agreement for the
// Generic Graph Component Library along with the software; see the
// file LICENSE. If not, contact Office of Research, University of Notre
// Dame, Notre Dame, IN 46556.
//
// Permission to modify the code and to distribute modified code is
// granted, provided the text of this NOTICE is retained, a notice that
// the code was modified is included with the above COPYRIGHT NOTICE and
// with the COPYRIGHT NOTICE in the LICENSE file, and that the LICENSE
// file is distributed with the modified code.
//
// LICENSOR MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED.
// By way of example, but not limitation, Licensor MAKES NO
// REPRESENTATIONS OR WARRANTIES OF MERCHANTABILITY OR FITNESS FOR ANY
// PARTICULAR PURPOSE OR THAT THE USE OF THE LICENSED SOFTWARE COMPONENTS
// OR DOCUMENTATION WILL NOT INFRINGE ANY PATENTS, COPYRIGHTS, TRADEMARKS
// OR OTHER RIGHTS.
//=======================================================================
//
#ifndef MINIMUM_DEGREE_ORDERING_HPP
#define MINIMUM_DEGREE_ORDERING_HPP
#include <vector>
#include <cassert>
#include <boost/config.hpp>
#include <boost/pending/bucket_sorter.hpp>
#include <boost/detail/numeric_traits.hpp> // for integer_traits
namespace boost {
namespace detail {
//
// Given a set of n integers (where the integer values range from
// zero to n-1), we want to keep track of a collection of stacks
// of integers. It so happens that an integer will appear in at
// most one stack at a time, so the stacks form disjoint sets.
// Because of these restrictions, we can use one big array to
// store all the stacks, intertwined with one another.
// No allocation/deallocation happens in the push()/pop() methods
// so this is faster than using std::stack's.
//
template <class SignedInteger>
class Stacks {
typedef SignedInteger value_type;
typedef typename std::vector<value_type>::size_type size_type;
public:
Stacks(size_type n) : data(n) {}
//: stack
class stack {
typedef typename std::vector<value_type>::iterator Iterator;
public:
stack(Iterator _data, const value_type& head)
: data(_data), current(head) {}
// did not use default argument here to avoid internal compiler error
// in g++.
stack(Iterator _data)
: data(_data), current(-(std::numeric_limits<value_type>::max)()) {}
void pop() {
assert(! empty());
current = data[current];
}
void push(value_type v) {
data[v] = current;
current = v;
}
bool empty() {
return current == -(std::numeric_limits<value_type>::max)();
}
value_type& top() { return current; }
private:
Iterator data;
value_type current;
};
// To return a stack object
stack make_stack()
{ return stack(data.begin()); }
protected:
std::vector<value_type> data;
};
// marker class, a generalization of coloring.
//
// This class is to provide a generalization of coloring which has
// complexity of amortized constant time to set all vertices' color
// back to be untagged. It implemented by increasing a tag.
//
// The colors are:
// not tagged
// tagged
// multiple_tagged
// done
//
template <class SignedInteger, class Vertex, class VertexIndexMap>
class Marker {
typedef SignedInteger value_type;
typedef typename std::vector<value_type>::size_type size_type;
static value_type done()
{ return (std::numeric_limits<value_type>::max)()/2; }
public:
Marker(size_type _num, VertexIndexMap index_map)
: tag(1 - (std::numeric_limits<value_type>::max)()),
data(_num, - (std::numeric_limits<value_type>::max)()),
id(index_map) {}
void mark_done(Vertex node) { data[id[node]] = done(); }
bool is_done(Vertex node) { return data[id[node]] == done(); }
void mark_tagged(Vertex node) { data[id[node]] = tag; }
void mark_multiple_tagged(Vertex node) { data[id[node]] = multiple_tag; }
bool is_tagged(Vertex node) const { return data[id[node]] >= tag; }
bool is_not_tagged(Vertex node) const { return data[id[node]] < tag; }
bool is_multiple_tagged(Vertex node) const
{ return data[id[node]] >= multiple_tag; }
void increment_tag() {
const size_type num = data.size();
++tag;
if ( tag >= done() ) {
tag = 1 - (std::numeric_limits<value_type>::max)();
for (size_type i = 0; i < num; ++i)
if ( data[i] < done() )
data[i] = - (std::numeric_limits<value_type>::max)();
}
}
void set_multiple_tag(value_type mdeg0)
{
const size_type num = data.size();
multiple_tag = tag + mdeg0;
if ( multiple_tag >= done() ) {
tag = 1-(std::numeric_limits<value_type>::max)();
for (size_type i=0; i<num; i++)
if ( data[i] < done() )
data[i] = -(std::numeric_limits<value_type>::max)();
multiple_tag = tag + mdeg0;
}
}
void set_tag_as_multiple_tag() { tag = multiple_tag; }
protected:
value_type tag;
value_type multiple_tag;
std::vector<value_type> data;
VertexIndexMap id;
};
template< class Iterator, class SignedInteger,
class Vertex, class VertexIndexMap, int offset = 1 >
class Numbering {
typedef SignedInteger number_type;
number_type num; //start from 1 instead of zero
Iterator data;
number_type max_num;
VertexIndexMap id;
public:
Numbering(Iterator _data, number_type _max_num, VertexIndexMap id)
: num(1), data(_data), max_num(_max_num), id(id) {}
void operator()(Vertex node) { data[id[node]] = -num; }
bool all_done(number_type i = 0) const { return num + i > max_num; }
void increment(number_type i = 1) { num += i; }
bool is_numbered(Vertex node) const {
return data[id[node]] < 0;
}
void indistinguishable(Vertex i, Vertex j) {
data[id[i]] = - (id[j] + offset);
}
};
template <class SignedInteger, class Vertex, class VertexIndexMap>
class degreelists_marker {
public:
typedef SignedInteger value_type;
typedef typename std::vector<value_type>::size_type size_type;
degreelists_marker(size_type n, VertexIndexMap id)
: marks(n, 0), id(id) {}
void mark_need_update(Vertex i) { marks[id[i]] = 1; }
bool need_update(Vertex i) { return marks[id[i]] == 1; }
bool outmatched_or_done (Vertex i) { return marks[id[i]] == -1; }
void mark(Vertex i) { marks[id[i]] = -1; }
void unmark(Vertex i) { marks[id[i]] = 0; }
private:
std::vector<value_type> marks;
VertexIndexMap id;
};
// Helper function object for edge removal
template <class Graph, class MarkerP, class NumberD, class Stack,
class VertexIndexMap>
class predicateRemoveEdge1 {
typedef typename graph_traits<Graph>::vertex_descriptor vertex_t;
typedef typename graph_traits<Graph>::edge_descriptor edge_t;
public:
predicateRemoveEdge1(Graph& _g, MarkerP& _marker,
NumberD _numbering, Stack& n_e, VertexIndexMap id)
: g(&_g), marker(&_marker), numbering(_numbering),
neighbor_elements(&n_e), id(id) {}
bool operator()(edge_t e) {
vertex_t dist = target(e, *g);
if ( marker->is_tagged(dist) )
return true;
marker->mark_tagged(dist);
if (numbering.is_numbered(dist)) {
neighbor_elements->push(id[dist]);
return true;
}
return false;
}
private:
Graph* g;
MarkerP* marker;
NumberD numbering;
Stack* neighbor_elements;
VertexIndexMap id;
};
// Helper function object for edge removal
template <class Graph, class MarkerP>
class predicate_remove_tagged_edges
{
typedef typename graph_traits<Graph>::vertex_descriptor vertex_t;
typedef typename graph_traits<Graph>::edge_descriptor edge_t;
public:
predicate_remove_tagged_edges(Graph& _g, MarkerP& _marker)
: g(&_g), marker(&_marker) {}
bool operator()(edge_t e) {
vertex_t dist = target(e, *g);
if ( marker->is_tagged(dist) )
return true;
return false;
}
private:
Graph* g;
MarkerP* marker;
};
template<class Graph, class DegreeMap,
class InversePermutationMap,
class PermutationMap,
class SuperNodeMap,
class VertexIndexMap>
class mmd_impl
{
// Typedefs
typedef graph_traits<Graph> Traits;
typedef typename Traits::vertices_size_type size_type;
typedef typename detail::integer_traits<size_type>::difference_type
diff_t;
typedef typename Traits::vertex_descriptor vertex_t;
typedef typename Traits::adjacency_iterator adj_iter;
typedef iterator_property_map<vertex_t*,
identity_property_map, vertex_t, vertex_t&> IndexVertexMap;
typedef detail::Stacks<diff_t> Workspace;
typedef bucket_sorter<size_type, vertex_t, DegreeMap, VertexIndexMap>
DegreeLists;
typedef Numbering<InversePermutationMap, diff_t, vertex_t,VertexIndexMap>
NumberingD;
typedef degreelists_marker<diff_t, vertex_t, VertexIndexMap>
DegreeListsMarker;
typedef Marker<diff_t, vertex_t, VertexIndexMap> MarkerP;
// Data Members
// input parameters
Graph& G;
int delta;
DegreeMap degree;
InversePermutationMap inverse_perm;
PermutationMap perm;
SuperNodeMap supernode_size;
VertexIndexMap vertex_index_map;
// internal data-structures
std::vector<vertex_t> index_vertex_vec;
size_type n;
IndexVertexMap index_vertex_map;
DegreeLists degreelists;
NumberingD numbering;
DegreeListsMarker degree_lists_marker;
MarkerP marker;
Workspace work_space;
public:
mmd_impl(Graph& g, size_type n_, int delta, DegreeMap degree,
InversePermutationMap inverse_perm,
PermutationMap perm,
SuperNodeMap supernode_size,
VertexIndexMap id)
: G(g), delta(delta), degree(degree),
inverse_perm(inverse_perm),
perm(perm),
supernode_size(supernode_size),
vertex_index_map(id),
index_vertex_vec(n_),
n(n_),
degreelists(n_ + 1, n_, degree, id),
numbering(inverse_perm, n_, vertex_index_map),
degree_lists_marker(n_, vertex_index_map),
marker(n_, vertex_index_map),
work_space(n_)
{
typename graph_traits<Graph>::vertex_iterator v, vend;
size_type vid = 0;
for (tie(v, vend) = vertices(G); v != vend; ++v, ++vid)
index_vertex_vec[vid] = *v;
index_vertex_map = IndexVertexMap(&index_vertex_vec[0]);
// Initialize degreelists. Degreelists organizes the nodes
// according to their degree.
for (tie(v, vend) = vertices(G); v != vend; ++v) {
put(degree, *v, out_degree(*v, G));
degreelists.push(*v);
}
}
void do_mmd()
{
// Eliminate the isolated nodes -- these are simply the nodes
// with no neighbors, which are accessible as a list (really, a
// stack) at location 0. Since these don't affect any other
// nodes, we can eliminate them without doing degree updates.
typename DegreeLists::stack list_isolated = degreelists[0];
while (!list_isolated.empty()) {
vertex_t node = list_isolated.top();
marker.mark_done(node);
numbering(node);
numbering.increment();
list_isolated.pop();
}
size_type min_degree = 1;
typename DegreeLists::stack list_min_degree = degreelists[min_degree];
while (list_min_degree.empty()) {
++min_degree;
list_min_degree = degreelists[min_degree];
}
// check if the whole eliminating process is done
while (!numbering.all_done()) {
size_type min_degree_limit = min_degree + delta; // WARNING
typename Workspace::stack llist = work_space.make_stack();
// multiple elimination
while (delta >= 0) {
// Find the next non-empty degree
for (list_min_degree = degreelists[min_degree];
list_min_degree.empty() && min_degree <= min_degree_limit;
++min_degree, list_min_degree = degreelists[min_degree])
;
if (min_degree > min_degree_limit)
break;
const vertex_t node = list_min_degree.top();
const size_type node_id = vertex_index_map[node];
list_min_degree.pop();
numbering(node);
// check if node is the last one
if (numbering.all_done(supernode_size[node])) {
numbering.increment(supernode_size[node]);
break;
}
marker.increment_tag();
marker.mark_tagged(node);
this->eliminate(node);
numbering.increment(supernode_size[node]);
llist.push(node_id);
} // multiple elimination
if (numbering.all_done())
break;
this->update( llist, min_degree);
}
} // do_mmd()
void eliminate(vertex_t node)
{
typename Workspace::stack element_neighbor = work_space.make_stack();
// Create two function objects for edge removal
typedef typename Workspace::stack WorkStack;
predicateRemoveEdge1<Graph, MarkerP, NumberingD,
WorkStack, VertexIndexMap>
p(G, marker, numbering, element_neighbor, vertex_index_map);
predicate_remove_tagged_edges<Graph, MarkerP> p2(G, marker);
// Reconstruct the adjacent node list, push element neighbor in a List.
remove_out_edge_if(node, p, G);
//during removal element neighbors are collected.
while (!element_neighbor.empty()) {
// element absorb
size_type e_id = element_neighbor.top();
vertex_t element = index_vertex_map[e_id];
adj_iter i, i_end;
for (tie(i, i_end) = adjacent_vertices(element, G); i != i_end; ++i){
vertex_t i_node = *i;
if (!marker.is_tagged(i_node) && !numbering.is_numbered(i_node)) {
marker.mark_tagged(i_node);
add_edge(node, i_node, G);
}
}
element_neighbor.pop();
}
adj_iter v, ve;
for (tie(v, ve) = adjacent_vertices(node, G); v != ve; ++v) {
vertex_t v_node = *v;
if (!degree_lists_marker.need_update(v_node)
&& !degree_lists_marker.outmatched_or_done(v_node)) {
degreelists.remove(v_node);
}
//update out edges of v_node
remove_out_edge_if(v_node, p2, G);
if ( out_degree(v_node, G) == 0 ) { // indistinguishable nodes
supernode_size[node] += supernode_size[v_node];
supernode_size[v_node] = 0;
numbering.indistinguishable(v_node, node);
marker.mark_done(v_node);
degree_lists_marker.mark(v_node);
} else { // not indistinguishable nodes
add_edge(v_node, node, G);
degree_lists_marker.mark_need_update(v_node);
}
}
} // eliminate()
template <class Stack>
void update(Stack llist, size_type& min_degree)
{
size_type min_degree0 = min_degree + delta + 1;
while (! llist.empty()) {
size_type deg, deg0 = 0;
marker.set_multiple_tag(min_degree0);
typename Workspace::stack q2list = work_space.make_stack();
typename Workspace::stack qxlist = work_space.make_stack();
vertex_t current = index_vertex_map[llist.top()];
adj_iter i, ie;
for (tie(i,ie) = adjacent_vertices(current, G); i != ie; ++i) {
vertex_t i_node = *i;
const size_type i_id = vertex_index_map[i_node];
if (supernode_size[i_node] != 0) {
deg0 += supernode_size[i_node];
marker.mark_multiple_tagged(i_node);
if (degree_lists_marker.need_update(i_node)) {
if (out_degree(i_node, G) == 2)
q2list.push(i_id);
else
qxlist.push(i_id);
}
}
}
while (!q2list.empty()) {
const size_type u_id = q2list.top();
vertex_t u_node = index_vertex_map[u_id];
// if u_id is outmatched by others, no need to update degree
if (degree_lists_marker.outmatched_or_done(u_node)) {
q2list.pop();
continue;
}
marker.increment_tag();
deg = deg0;
adj_iter nu = adjacent_vertices(u_node, G).first;
vertex_t neighbor = *nu;
if (neighbor == u_node) {
++nu;
neighbor = *nu;
}
if (numbering.is_numbered(neighbor)) {
adj_iter i, ie;
for (tie(i,ie) = adjacent_vertices(neighbor, G);
i != ie; ++i) {
const vertex_t i_node = *i;
if (i_node == u_node || supernode_size[i_node] == 0)
continue;
if (marker.is_tagged(i_node)) {
if (degree_lists_marker.need_update(i_node)) {
if ( out_degree(i_node, G) == 2 ) { // is indistinguishable
supernode_size[u_node] += supernode_size[i_node];
supernode_size[i_node] = 0;
numbering.indistinguishable(i_node, u_node);
marker.mark_done(i_node);
degree_lists_marker.mark(i_node);
} else // is outmatched
degree_lists_marker.mark(i_node);
}
} else {
marker.mark_tagged(i_node);
deg += supernode_size[i_node];
}
}
} else
deg += supernode_size[neighbor];
deg -= supernode_size[u_node];
degree[u_node] = deg; //update degree
degreelists[deg].push(u_node);
//u_id has been pushed back into degreelists
degree_lists_marker.unmark(u_node);
if (min_degree > deg)
min_degree = deg;
q2list.pop();
} // while (!q2list.empty())
while (!qxlist.empty()) {
const size_type u_id = qxlist.top();
const vertex_t u_node = index_vertex_map[u_id];
// if u_id is outmatched by others, no need to update degree
if (degree_lists_marker.outmatched_or_done(u_node)) {
qxlist.pop();
continue;
}
marker.increment_tag();
deg = deg0;
adj_iter i, ie;
for (tie(i, ie) = adjacent_vertices(u_node, G); i != ie; ++i) {
vertex_t i_node = *i;
if (marker.is_tagged(i_node))
continue;
marker.mark_tagged(i_node);
if (numbering.is_numbered(i_node)) {
adj_iter j, je;
for (tie(j, je) = adjacent_vertices(i_node, G); j != je; ++j) {
const vertex_t j_node = *j;
if (marker.is_not_tagged(j_node)) {
marker.mark_tagged(j_node);
deg += supernode_size[j_node];
}
}
} else
deg += supernode_size[i_node];
} // for adjacent vertices of u_node
deg -= supernode_size[u_node];
degree[u_node] = deg;
degreelists[deg].push(u_node);
// u_id has been pushed back into degreelists
degree_lists_marker.unmark(u_node);
if (min_degree > deg)
min_degree = deg;
qxlist.pop();
} // while (!qxlist.empty()) {
marker.set_tag_as_multiple_tag();
llist.pop();
} // while (! llist.empty())
} // update()
void build_permutation(InversePermutationMap next,
PermutationMap prev)
{
// collect the permutation info
size_type i;
for (i = 0; i < n; ++i) {
diff_t size = supernode_size[index_vertex_map[i]];
if ( size <= 0 ) {
prev[i] = next[i];
supernode_size[index_vertex_map[i]]
= next[i] + 1; // record the supernode info
} else
prev[i] = - next[i];
}
for (i = 1; i < n + 1; ++i) {
if ( prev[i-1] > 0 )
continue;
diff_t parent = i;
while ( prev[parent - 1] < 0 ) {
parent = - prev[parent - 1];
}
diff_t root = parent;
diff_t num = prev[root - 1] + 1;
next[i-1] = - num;
prev[root-1] = num;
parent = i;
diff_t next_node = - prev[parent - 1];
while (next_node > 0) {
prev[parent-1] = - root;
parent = next_node;
next_node = - prev[parent - 1];
}
}
for (i = 0; i < n; i++) {
diff_t num = - next[i] - 1;
next[i] = num;
prev[num] = i;
}
} // build_permutation()
};
} //namespace detail
// MMD algorithm
//
//The implementation presently includes the enhancements for mass
//elimination, incomplete degree update, multiple elimination, and
//external degree.
//
//Important Note: This implementation requires the BGL graph to be
//directed. Therefore, nonzero entry (i, j) in a symmetrical matrix
//A coresponds to two directed edges (i->j and j->i).
//
//see Alan George and Joseph W. H. Liu, The Evolution of the Minimum
//Degree Ordering Algorithm, SIAM Review, 31, 1989, Page 1-19
template<class Graph, class DegreeMap,
class InversePermutationMap,
class PermutationMap,
class SuperNodeMap, class VertexIndexMap>
void minimum_degree_ordering
(Graph& G,
DegreeMap degree,
InversePermutationMap inverse_perm,
PermutationMap perm,
SuperNodeMap supernode_size,
int delta,
VertexIndexMap vertex_index_map)
{
detail::mmd_impl<Graph,DegreeMap,InversePermutationMap,
PermutationMap, SuperNodeMap, VertexIndexMap>
impl(G, num_vertices(G), delta, degree, inverse_perm,
perm, supernode_size, vertex_index_map);
impl.do_mmd();
impl.build_permutation(inverse_perm, perm);
}
} // namespace boost
#endif // MINIMUM_DEGREE_ORDERING_HPP

View File

@@ -1,633 +0,0 @@
//=======================================================================
// Copyright 1997, 1998, 1999, 2000 University of Notre Dame.
// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek
//
// This file is part of the Boost Graph Library
//
// You should have received a copy of the License Agreement for the
// Boost Graph Library along with the software; see the file LICENSE.
// If not, contact Office of Research, University of Notre Dame, Notre
// Dame, IN 46556.
//
// Permission to modify the code and to distribute modified code is
// granted, provided the text of this NOTICE is retained, a notice that
// the code was modified is included with the above COPYRIGHT NOTICE and
// with the COPYRIGHT NOTICE in the LICENSE file, and that the LICENSE
// file is distributed with the modified code.
//
// LICENSOR MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED.
// By way of example, but not limitation, Licensor MAKES NO
// REPRESENTATIONS OR WARRANTIES OF MERCHANTABILITY OR FITNESS FOR ANY
// PARTICULAR PURPOSE OR THAT THE USE OF THE LICENSED SOFTWARE COMPONENTS
// OR DOCUMENTATION WILL NOT INFRINGE ANY PATENTS, COPYRIGHTS, TRADEMARKS
// OR OTHER RIGHTS.
//=======================================================================
#ifndef BOOST_GRAPH_NAMED_FUNCTION_PARAMS_HPP
#define BOOST_GRAPH_NAMED_FUNCTION_PARAMS_HPP
#include <boost/graph/properties.hpp>
namespace boost {
struct distance_compare_t { };
struct distance_combine_t { };
struct distance_inf_t { };
struct distance_zero_t { };
struct buffer_param_t { };
struct edge_copy_t { };
struct vertex_copy_t { };
struct vertex_isomorphism_t { };
struct vertex_invariant_t { };
struct vertex_invariant1_t { };
struct vertex_invariant2_t { };
struct edge_compare_t { };
struct vertex_max_invariant_t { };
struct orig_to_copy_t { };
struct root_vertex_t { };
namespace detail {
template <class T>
struct wrap_ref {
wrap_ref(T& r) : ref(r) {}
T& ref;
};
}
template <typename T, typename Tag, typename Base = no_property>
struct bgl_named_params : public Base
{
typedef bgl_named_params self;
typedef Base next_type;
typedef Tag tag_type;
typedef T value_type;
bgl_named_params(T v) : m_value(v) { }
bgl_named_params(T v, const Base& b) : Base(b), m_value(v) { }
T m_value;
template <typename WeightMap>
bgl_named_params<WeightMap, edge_weight_t, self>
weight_map(const WeightMap& pmap) const {
typedef bgl_named_params<WeightMap, edge_weight_t, self> Params;
return Params(pmap, *this);
}
template <typename WeightMap>
bgl_named_params<WeightMap, edge_weight2_t, self>
weight_map2(const WeightMap& pmap) const {
typedef bgl_named_params<WeightMap, edge_weight2_t, self> Params;
return Params(pmap, *this);
}
template <typename DistanceMap>
bgl_named_params<DistanceMap, vertex_distance_t, self>
distance_map(const DistanceMap& pmap) const {
typedef bgl_named_params<DistanceMap, vertex_distance_t, self> Params;
return Params(pmap, *this);
}
template <typename PredecessorMap>
bgl_named_params<PredecessorMap, vertex_predecessor_t, self>
predecessor_map(const PredecessorMap& pmap) const {
typedef bgl_named_params<PredecessorMap, vertex_predecessor_t, self>
Params;
return Params(pmap, *this);
}
template <typename RankMap>
bgl_named_params<RankMap, vertex_rank_t, self>
rank_map(const RankMap& pmap) const {
typedef bgl_named_params<RankMap, vertex_rank_t, self>
Params;
return Params(pmap, *this);
}
template <typename RootMap>
bgl_named_params<RootMap, vertex_root_t, self>
root_map(const RootMap& pmap) const {
typedef bgl_named_params<RootMap, vertex_root_t, self>
Params;
return Params(pmap, *this);
}
template <typename Vertex>
bgl_named_params<Vertex, root_vertex_t, self>
root_vertex(const Vertex& r) const {
typedef bgl_named_params<Vertex, root_vertex_t, self> Params;
return Params(r, *this);
}
template <typename EdgeCentralityMap>
bgl_named_params<EdgeCentralityMap, edge_centrality_t, self>
edge_centrality_map(const EdgeCentralityMap& r) const {
typedef bgl_named_params<EdgeCentralityMap, edge_centrality_t, self> Params;
return Params(r, *this);
}
template <typename CentralityMap>
bgl_named_params<CentralityMap, vertex_centrality_t, self>
centrality_map(const CentralityMap& r) const {
typedef bgl_named_params<CentralityMap, vertex_centrality_t, self> Params;
return Params(r, *this);
}
template <typename ColorMap>
bgl_named_params<ColorMap, vertex_color_t, self>
color_map(const ColorMap& pmap) const {
typedef bgl_named_params<ColorMap, vertex_color_t, self> Params;
return Params(pmap, *this);
}
template <typename ColorMap>
bgl_named_params<ColorMap, vertex_color_t, self>
vertex_color_map(const ColorMap& pmap) const {
typedef bgl_named_params<ColorMap, vertex_color_t, self> Params;
return Params(pmap, *this);
}
template <typename ColorMap>
bgl_named_params<ColorMap, edge_color_t, self>
edge_color_map(const ColorMap& pmap) const {
typedef bgl_named_params<ColorMap, edge_color_t, self> Params;
return Params(pmap, *this);
}
template <typename CapacityMap>
bgl_named_params<CapacityMap, edge_capacity_t, self>
capacity_map(CapacityMap pmap) {
typedef bgl_named_params<CapacityMap, edge_capacity_t, self> Params;
return Params(pmap, *this);
}
template <typename Residual_CapacityMap>
bgl_named_params<Residual_CapacityMap, edge_residual_capacity_t, self>
residual_capacity_map(Residual_CapacityMap pmap) {
typedef bgl_named_params<Residual_CapacityMap,
edge_residual_capacity_t, self>
Params;
return Params(pmap, *this);
}
template <typename ReverseMap>
bgl_named_params<ReverseMap, edge_reverse_t, self>
reverse_edge_map(ReverseMap pmap) {
typedef bgl_named_params<ReverseMap,
edge_reverse_t, self>
Params;
return Params(pmap, *this);
}
template <typename DiscoverTimeMap>
bgl_named_params<DiscoverTimeMap, vertex_discover_time_t, self>
discover_time_map(const DiscoverTimeMap& pmap) const {
typedef bgl_named_params<DiscoverTimeMap, vertex_discover_time_t, self>
Params;
return Params(pmap, *this);
}
template <typename IndexMap>
bgl_named_params<IndexMap, vertex_index_t, self>
vertex_index_map(const IndexMap& pmap) const {
typedef bgl_named_params<IndexMap, vertex_index_t, self> Params;
return Params(pmap, *this);
}
template <typename IndexMap>
bgl_named_params<IndexMap, vertex_index1_t, self>
vertex_index1_map(const IndexMap& pmap) const {
typedef bgl_named_params<IndexMap, vertex_index1_t, self> Params;
return Params(pmap, *this);
}
template <typename IndexMap>
bgl_named_params<IndexMap, vertex_index2_t, self>
vertex_index2_map(const IndexMap& pmap) const {
typedef bgl_named_params<IndexMap, vertex_index2_t, self> Params;
return Params(pmap, *this);
}
template <typename Visitor>
bgl_named_params<Visitor, graph_visitor_t, self>
visitor(const Visitor& vis) const {
typedef bgl_named_params<Visitor, graph_visitor_t, self> Params;
return Params(vis, *this);
}
template <typename Compare>
bgl_named_params<Compare, distance_compare_t, self>
distance_compare(Compare cmp) const {
typedef bgl_named_params<Compare, distance_compare_t, self> Params;
return Params(cmp, *this);
}
template <typename Combine>
bgl_named_params<Combine, distance_combine_t, self>
distance_combine(Combine cmb) const {
typedef bgl_named_params<Combine, distance_combine_t, self> Params;
return Params(cmb, *this);
}
template <typename Init>
bgl_named_params<Init, distance_inf_t, self>
distance_inf(Init init) const {
typedef bgl_named_params<Init, distance_inf_t, self> Params;
return Params(init, *this);
}
template <typename Init>
bgl_named_params<Init, distance_zero_t, self>
distance_zero(Init init) const {
typedef bgl_named_params<Init, distance_zero_t, self> Params;
return Params(init, *this);
}
template <typename Buffer>
bgl_named_params<detail::wrap_ref<Buffer>, buffer_param_t, self>
buffer(Buffer& b) const {
typedef bgl_named_params<detail::wrap_ref<Buffer>, buffer_param_t, self>
Params;
return Params(detail::wrap_ref<Buffer>(b), *this);
}
template <typename Copier>
bgl_named_params<Copier, edge_copy_t, self>
edge_copy(const Copier& c) const {
typedef bgl_named_params<Copier, edge_copy_t, self> Params;
return Params(c, *this);
}
template <typename Copier>
bgl_named_params<Copier, vertex_copy_t, self>
vertex_copy(const Copier& c) const {
typedef bgl_named_params<Copier, vertex_copy_t, self> Params;
return Params(c, *this);
}
template <typename Orig2CopyMap>
bgl_named_params<Orig2CopyMap, orig_to_copy_t, self>
orig_to_copy(const Orig2CopyMap& c) const {
typedef bgl_named_params<Orig2CopyMap, orig_to_copy_t, self> Params;
return Params(c, *this);
}
template <typename IsoMap>
bgl_named_params<IsoMap, vertex_isomorphism_t, self>
isomorphism_map(const IsoMap& c) const {
typedef bgl_named_params<IsoMap, vertex_isomorphism_t, self> Params;
return Params(c, *this);
}
template <typename VertexInvar>
bgl_named_params<VertexInvar, vertex_invariant_t, self>
vertex_invariant(const VertexInvar& c) const {
typedef bgl_named_params<VertexInvar, vertex_invariant_t, self> Params;
return Params(c, *this);
}
};
template <typename WeightMap>
bgl_named_params<WeightMap, edge_weight_t>
weight_map(WeightMap pmap) {
typedef bgl_named_params<WeightMap, edge_weight_t> Params;
return Params(pmap);
}
template <typename WeightMap>
bgl_named_params<WeightMap, edge_weight2_t>
weight_map2(WeightMap pmap) {
typedef bgl_named_params<WeightMap, edge_weight2_t> Params;
return Params(pmap);
}
template <typename DistanceMap>
bgl_named_params<DistanceMap, vertex_distance_t>
distance_map(DistanceMap pmap) {
typedef bgl_named_params<DistanceMap, vertex_distance_t> Params;
return Params(pmap);
}
template <typename PredecessorMap>
bgl_named_params<PredecessorMap, vertex_predecessor_t>
predecessor_map(PredecessorMap pmap) {
typedef bgl_named_params<PredecessorMap, vertex_predecessor_t> Params;
return Params(pmap);
}
template <typename RankMap>
bgl_named_params<RankMap, vertex_rank_t>
rank_map(RankMap pmap) {
typedef bgl_named_params<RankMap, vertex_rank_t> Params;
return Params(pmap);
}
template <typename RootMap>
bgl_named_params<RootMap, vertex_root_t>
root_map(RootMap pmap) {
typedef bgl_named_params<RootMap, vertex_root_t> Params;
return Params(pmap);
}
template <typename Vertex>
bgl_named_params<Vertex, root_vertex_t>
root_vertex(const Vertex& r) {
typedef bgl_named_params<Vertex, root_vertex_t> Params;
return Params(r);
}
template <typename EdgeCentralityMap>
bgl_named_params<EdgeCentralityMap, edge_centrality_t>
edge_centrality_map(const EdgeCentralityMap& r) {
typedef bgl_named_params<EdgeCentralityMap, edge_centrality_t> Params;
return Params(r);
}
template <typename CentralityMap>
bgl_named_params<CentralityMap, vertex_centrality_t>
centrality_map(const CentralityMap& r) {
typedef bgl_named_params<CentralityMap, vertex_centrality_t> Params;
return Params(r);
}
template <typename ColorMap>
bgl_named_params<ColorMap, vertex_color_t>
color_map(ColorMap pmap) {
typedef bgl_named_params<ColorMap, vertex_color_t> Params;
return Params(pmap);
}
template <typename CapacityMap>
bgl_named_params<CapacityMap, edge_capacity_t>
capacity_map(CapacityMap pmap) {
typedef bgl_named_params<CapacityMap, edge_capacity_t> Params;
return Params(pmap);
}
template <typename Residual_CapacityMap>
bgl_named_params<Residual_CapacityMap, edge_residual_capacity_t>
residual_capacity_map(Residual_CapacityMap pmap) {
typedef bgl_named_params<Residual_CapacityMap, edge_residual_capacity_t>
Params;
return Params(pmap);
}
template <typename ReverseMap>
bgl_named_params<ReverseMap, edge_reverse_t>
reverse_edge_map(ReverseMap pmap) {
typedef bgl_named_params<ReverseMap, edge_reverse_t>
Params;
return Params(pmap);
}
template <typename DiscoverTimeMap>
bgl_named_params<DiscoverTimeMap, vertex_discover_time_t>
discover_time_map(DiscoverTimeMap pmap) {
typedef bgl_named_params<DiscoverTimeMap, vertex_discover_time_t> Params;
return Params(pmap);
}
template <typename IndexMap>
bgl_named_params<IndexMap, vertex_index_t>
vertex_index_map(IndexMap pmap) {
typedef bgl_named_params<IndexMap, vertex_index_t> Params;
return Params(pmap);
}
template <typename IndexMap>
bgl_named_params<IndexMap, vertex_index1_t>
vertex_index1_map(const IndexMap& pmap) {
typedef bgl_named_params<IndexMap, vertex_index1_t> Params;
return Params(pmap);
}
template <typename IndexMap>
bgl_named_params<IndexMap, vertex_index2_t>
vertex_index2_map(const IndexMap& pmap) {
typedef bgl_named_params<IndexMap, vertex_index2_t> Params;
return Params(pmap);
}
template <typename Visitor>
bgl_named_params<Visitor, graph_visitor_t>
visitor(const Visitor& vis) {
typedef bgl_named_params<Visitor, graph_visitor_t> Params;
return Params(vis);
}
template <typename Compare>
bgl_named_params<Compare, distance_compare_t>
distance_compare(Compare cmp) {
typedef bgl_named_params<Compare, distance_compare_t> Params;
return Params(cmp);
}
template <typename Combine>
bgl_named_params<Combine, distance_combine_t>
distance_combine(Combine cmb) {
typedef bgl_named_params<Combine, distance_combine_t> Params;
return Params(cmb);
}
template <typename Init>
bgl_named_params<Init, distance_inf_t>
distance_inf(Init init) {
typedef bgl_named_params<Init, distance_inf_t> Params;
return Params(init);
}
template <typename Init>
bgl_named_params<Init, distance_zero_t>
distance_zero(Init init) {
typedef bgl_named_params<Init, distance_zero_t> Params;
return Params(init);
}
template <typename Buffer>
bgl_named_params<detail::wrap_ref<Buffer>, buffer_param_t>
buffer(Buffer& b) {
typedef bgl_named_params<detail::wrap_ref<Buffer>, buffer_param_t> Params;
return Params(detail::wrap_ref<Buffer>(b));
}
template <typename Copier>
bgl_named_params<Copier, edge_copy_t>
edge_copy(const Copier& c) {
typedef bgl_named_params<Copier, edge_copy_t> Params;
return Params(c);
}
template <typename Copier>
bgl_named_params<Copier, vertex_copy_t>
vertex_copy(const Copier& c) {
typedef bgl_named_params<Copier, vertex_copy_t> Params;
return Params(c);
}
template <typename Orig2CopyMap>
bgl_named_params<Orig2CopyMap, orig_to_copy_t>
orig_to_copy(const Orig2CopyMap& c) {
typedef bgl_named_params<Orig2CopyMap, orig_to_copy_t> Params;
return Params(c);
}
template <typename IsoMap>
bgl_named_params<IsoMap, vertex_isomorphism_t>
isomorphism_map(const IsoMap& c) {
typedef bgl_named_params<IsoMap, vertex_isomorphism_t> Params;
return Params(c);
}
template <typename VertexInvar>
bgl_named_params<VertexInvar, vertex_invariant_t>
vertex_invariant(const VertexInvar& c) {
typedef bgl_named_params<VertexInvar, vertex_invariant_t> Params;
return Params(c);
}
//===========================================================================
// Functions for extracting parameters from bgl_named_params
template <class Tag1, class Tag2, class T1, class Base>
inline
typename property_value< bgl_named_params<T1,Tag1,Base>, Tag2>::type
get_param(const bgl_named_params<T1,Tag1,Base>& p, Tag2 tag2)
{
enum { match = detail::same_property<Tag1,Tag2>::value };
typedef typename
property_value< bgl_named_params<T1,Tag1,Base>, Tag2>::type T2;
T2* t2 = 0;
typedef detail::property_value_dispatch<match> Dispatcher;
return Dispatcher::const_get_value(p, t2, tag2);
}
namespace detail {
// MSVC++ workaround
template <class Param>
struct choose_param_helper {
template <class Default> struct result { typedef Param type; };
template <typename Default>
static const Param& apply(const Param& p, const Default&) { return p; }
};
template <>
struct choose_param_helper<error_property_not_found> {
template <class Default> struct result { typedef Default type; };
template <typename Default>
static const Default& apply(const error_property_not_found&, const Default& d)
{ return d; }
};
} // namespace detail
template <class P, class Default>
const typename detail::choose_param_helper<P>::template result<Default>::type&
choose_param(const P& param, const Default& d) {
return detail::choose_param_helper<P>::apply(param, d);
}
template <typename T>
inline bool is_default_param(const T&) { return false; }
inline bool is_default_param(const detail::error_property_not_found&)
{ return true; }
namespace detail {
struct choose_parameter {
template <class P, class Graph, class Tag>
struct bind_ {
typedef const P& const_result_type;
typedef const P& result_type;
typedef P type;
};
template <class P, class Graph, class Tag>
static typename bind_<P, Graph, Tag>::const_result_type
const_apply(const P& p, const Graph&, Tag&)
{ return p; }
template <class P, class Graph, class Tag>
static typename bind_<P, Graph, Tag>::result_type
apply(const P& p, Graph&, Tag&)
{ return p; }
};
struct choose_default_param {
template <class P, class Graph, class Tag>
struct bind_ {
typedef typename property_map<Graph, Tag>::type
result_type;
typedef typename property_map<Graph, Tag>::const_type
const_result_type;
typedef typename property_map<Graph, Tag>::const_type
type;
};
template <class P, class Graph, class Tag>
static typename bind_<P, Graph, Tag>::const_result_type
const_apply(const P&, const Graph& g, Tag tag) {
return get(tag, g);
}
template <class P, class Graph, class Tag>
static typename bind_<P, Graph, Tag>::result_type
apply(const P&, Graph& g, Tag tag) {
return get(tag, g);
}
};
template <class Param>
struct choose_property_map {
typedef choose_parameter type;
};
template <>
struct choose_property_map<detail::error_property_not_found> {
typedef choose_default_param type;
};
template <class Param, class Graph, class Tag>
struct choose_pmap_helper {
typedef typename choose_property_map<Param>::type Selector;
typedef typename Selector:: template bind_<Param, Graph, Tag> Bind;
typedef Bind type;
typedef typename Bind::result_type result_type;
typedef typename Bind::const_result_type const_result_type;
typedef typename Bind::type result;
};
// used in the max-flow algorithms
template <class Graph, class P, class T, class R>
struct edge_capacity_value
{
typedef bgl_named_params<P, T, R> Params;
typedef typename property_value< Params, edge_capacity_t>::type Param;
typedef typename detail::choose_pmap_helper<Param, Graph,
edge_capacity_t>::result CapacityEdgeMap;
typedef typename property_traits<CapacityEdgeMap>::value_type type;
};
} // namespace detail
// Use this function instead of choose_param() when you want
// to avoid requiring get(tag, g) when it is not used.
template <typename Param, typename Graph, typename PropertyTag>
typename
detail::choose_pmap_helper<Param,Graph,PropertyTag>::const_result_type
choose_const_pmap(const Param& p, const Graph& g, PropertyTag tag)
{
typedef typename
detail::choose_pmap_helper<Param,Graph,PropertyTag>::Selector Choice;
return Choice::const_apply(p, g, tag);
}
template <typename Param, typename Graph, typename PropertyTag>
typename detail::choose_pmap_helper<Param,Graph,PropertyTag>::result_type
choose_pmap(const Param& p, Graph& g, PropertyTag tag)
{
typedef typename
detail::choose_pmap_helper<Param,Graph,PropertyTag>::Selector Choice;
return Choice::apply(p, g, tag);
}
} // namespace boost
#endif // BOOST_GRAPH_NAMED_FUNCTION_PARAMS_HPP

View File

@@ -1,339 +0,0 @@
//
//=======================================================================
// Copyright 1997, 1998, 1999, 2000 University of Notre Dame.
// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek
//
// This file is part of the Boost Graph Library
//
// You should have received a copy of the License Agreement for the
// Boost Graph Library along with the software; see the file LICENSE.
// If not, contact Office of Research, University of Notre Dame, Notre
// Dame, IN 46556.
//
// Permission to modify the code and to distribute modified code is
// granted, provided the text of this NOTICE is retained, a notice that
// the code was modified is included with the above COPYRIGHT NOTICE and
// with the COPYRIGHT NOTICE in the LICENSE file, and that the LICENSE
// file is distributed with the modified code.
//
// LICENSOR MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED.
// By way of example, but not limitation, Licensor MAKES NO
// REPRESENTATIONS OR WARRANTIES OF MERCHANTABILITY OR FITNESS FOR ANY
// PARTICULAR PURPOSE OR THAT THE USE OF THE LICENSED SOFTWARE COMPONENTS
// OR DOCUMENTATION WILL NOT INFRINGE ANY PATENTS, COPYRIGHTS, TRADEMARKS
// OR OTHER RIGHTS.
//=======================================================================
//
#ifndef BOOST_GRAPH_NEIGHBOR_BREADTH_FIRST_SEARCH_HPP
#define BOOST_GRAPH_NEIGHBOR_BREADTH_FIRST_SEARCH_HPP
/*
Neighbor Breadth First Search
Like BFS, but traverses in-edges as well as out-edges.
(for directed graphs only. use normal BFS for undirected graphs)
*/
#include <boost/config.hpp>
#include <vector>
#include <boost/pending/queue.hpp>
#include <boost/graph/graph_traits.hpp>
#include <boost/graph/graph_concepts.hpp>
#include <boost/graph/visitors.hpp>
#include <boost/graph/named_function_params.hpp>
namespace boost {
template <class Visitor, class Graph>
struct NeighborBFSVisitorConcept {
void constraints() {
function_requires< CopyConstructibleConcept<Visitor> >();
vis.initialize_vertex(u, g);
vis.discover_vertex(u, g);
vis.examine_vertex(u, g);
vis.examine_out_edge(e, g);
vis.examine_in_edge(e, g);
vis.tree_out_edge(e, g);
vis.tree_in_edge(e, g);
vis.non_tree_out_edge(e, g);
vis.non_tree_in_edge(e, g);
vis.gray_target(e, g);
vis.black_target(e, g);
vis.gray_source(e, g);
vis.black_source(e, g);
vis.finish_vertex(u, g);
}
Visitor vis;
Graph g;
typename graph_traits<Graph>::vertex_descriptor u;
typename graph_traits<Graph>::edge_descriptor e;
};
template <class Visitors = null_visitor>
class neighbor_bfs_visitor {
public:
neighbor_bfs_visitor(Visitors vis = Visitors()) : m_vis(vis) { }
template <class Vertex, class Graph>
void initialize_vertex(Vertex u, Graph& g) {
invoke_visitors(m_vis, u, g, on_initialize_vertex());
}
template <class Vertex, class Graph>
void discover_vertex(Vertex u, Graph& g) {
invoke_visitors(m_vis, u, g, on_discover_vertex());
}
template <class Vertex, class Graph>
void examine_vertex(Vertex u, Graph& g) {
invoke_visitors(m_vis, u, g, on_examine_vertex());
}
template <class Edge, class Graph>
void examine_out_edge(Edge e, Graph& g) {
invoke_visitors(m_vis, e, g, on_examine_edge());
}
template <class Edge, class Graph>
void tree_out_edge(Edge e, Graph& g) {
invoke_visitors(m_vis, e, g, on_tree_edge());
}
template <class Edge, class Graph>
void non_tree_out_edge(Edge e, Graph& g) {
invoke_visitors(m_vis, e, g, on_non_tree_edge());
}
template <class Edge, class Graph>
void gray_target(Edge e, Graph& g) {
invoke_visitors(m_vis, e, g, on_gray_target());
}
template <class Edge, class Graph>
void black_target(Edge e, Graph& g) {
invoke_visitors(m_vis, e, g, on_black_target());
}
template <class Edge, class Graph>
void examine_in_edge(Edge e, Graph& g) {
invoke_visitors(m_vis, e, g, on_examine_edge());
}
template <class Edge, class Graph>
void tree_in_edge(Edge e, Graph& g) {
invoke_visitors(m_vis, e, g, on_tree_edge());
}
template <class Edge, class Graph>
void non_tree_in_edge(Edge e, Graph& g) {
invoke_visitors(m_vis, e, g, on_non_tree_edge());
}
template <class Edge, class Graph>
void gray_source(Edge e, Graph& g) {
invoke_visitors(m_vis, e, g, on_gray_target());
}
template <class Edge, class Graph>
void black_source(Edge e, Graph& g) {
invoke_visitors(m_vis, e, g, on_black_target());
}
template <class Vertex, class Graph>
void finish_vertex(Vertex u, Graph& g) {
invoke_visitors(m_vis, u, g, on_finish_vertex());
}
protected:
Visitors m_vis;
};
template <class Visitors>
neighbor_bfs_visitor<Visitors>
make_neighbor_bfs_visitor(Visitors vis) {
return neighbor_bfs_visitor<Visitors>(vis);
}
namespace detail {
template <class BidirectionalGraph, class Buffer, class BFSVisitor,
class ColorMap>
void neighbor_bfs_impl
(const BidirectionalGraph& g,
typename graph_traits<BidirectionalGraph>::vertex_descriptor s,
Buffer& Q, BFSVisitor vis, ColorMap color)
{
function_requires< BidirectionalGraphConcept<BidirectionalGraph> >();
typedef graph_traits<BidirectionalGraph> GTraits;
typedef typename GTraits::vertex_descriptor Vertex;
typedef typename GTraits::edge_descriptor Edge;
function_requires<
NeighborBFSVisitorConcept<BFSVisitor, BidirectionalGraph> >();
function_requires< ReadWritePropertyMapConcept<ColorMap, Vertex> >();
typedef typename property_traits<ColorMap>::value_type ColorValue;
typedef color_traits<ColorValue> Color;
put(color, s, Color::gray());
vis.discover_vertex(s, g);
Q.push(s);
while (! Q.empty()) {
Vertex u = Q.top();
Q.pop(); // pop before push to avoid problem if Q is priority_queue.
vis.examine_vertex(u, g);
typename GTraits::out_edge_iterator ei, ei_end;
for (tie(ei, ei_end) = out_edges(u, g); ei != ei_end; ++ei) {
Edge e = *ei;
vis.examine_out_edge(e, g);
Vertex v = target(e, g);
ColorValue v_color = get(color, v);
if (v_color == Color::white()) {
vis.tree_out_edge(e, g);
put(color, v, Color::gray());
vis.discover_vertex(v, g);
Q.push(v);
} else {
vis.non_tree_out_edge(e, g);
if (v_color == Color::gray())
vis.gray_target(e, g);
else
vis.black_target(e, g);
}
} // for out-edges
typename GTraits::in_edge_iterator in_ei, in_ei_end;
for (tie(in_ei, in_ei_end) = in_edges(u, g);
in_ei != in_ei_end; ++in_ei) {
Edge e = *in_ei;
vis.examine_in_edge(e, g);
Vertex v = source(e, g);
ColorValue v_color = get(color, v);
if (v_color == Color::white()) {
vis.tree_in_edge(e, g);
put(color, v, Color::gray());
vis.discover_vertex(v, g);
Q.push(v);
} else {
vis.non_tree_in_edge(e, g);
if (v_color == Color::gray())
vis.gray_source(e, g);
else
vis.black_source(e, g);
}
} // for in-edges
put(color, u, Color::black());
vis.finish_vertex(u, g);
} // while
}
template <class VertexListGraph, class ColorMap, class BFSVisitor,
class P, class T, class R>
void neighbor_bfs_helper
(VertexListGraph& g,
typename graph_traits<VertexListGraph>::vertex_descriptor s,
ColorMap color,
BFSVisitor vis,
const bgl_named_params<P, T, R>& params)
{
typedef graph_traits<VertexListGraph> Traits;
// Buffer default
typedef typename Traits::vertex_descriptor Vertex;
typedef boost::queue<Vertex> queue_t;
queue_t Q;
detail::wrap_ref<queue_t> Qref(Q);
// Initialization
typedef typename property_traits<ColorMap>::value_type ColorValue;
typedef color_traits<ColorValue> Color;
typename boost::graph_traits<VertexListGraph>::vertex_iterator i, i_end;
for (tie(i, i_end) = vertices(g); i != i_end; ++i) {
put(color, *i, Color::white());
vis.initialize_vertex(*i, g);
}
neighbor_bfs_impl
(g, s,
choose_param(get_param(params, buffer_param_t()), Qref).ref,
vis, color);
}
//-------------------------------------------------------------------------
// Choose between default color and color parameters. Using
// function dispatching so that we don't require vertex index if
// the color default is not being used.
template <class ColorMap>
struct neighbor_bfs_dispatch {
template <class VertexListGraph, class P, class T, class R>
static void apply
(VertexListGraph& g,
typename graph_traits<VertexListGraph>::vertex_descriptor s,
const bgl_named_params<P, T, R>& params,
ColorMap color)
{
neighbor_bfs_helper
(g, s, color,
choose_param(get_param(params, graph_visitor),
make_neighbor_bfs_visitor(null_visitor())),
params);
}
};
template <>
struct neighbor_bfs_dispatch<detail::error_property_not_found> {
template <class VertexListGraph, class P, class T, class R>
static void apply
(VertexListGraph& g,
typename graph_traits<VertexListGraph>::vertex_descriptor s,
const bgl_named_params<P, T, R>& params,
detail::error_property_not_found)
{
std::vector<default_color_type> color_vec(num_vertices(g));
null_visitor null_vis;
neighbor_bfs_helper
(g, s,
make_iterator_property_map
(color_vec.begin(),
choose_const_pmap(get_param(params, vertex_index),
g, vertex_index), color_vec[0]),
choose_param(get_param(params, graph_visitor),
make_neighbor_bfs_visitor(null_vis)),
params);
}
};
} // namespace detail
// Named Parameter Variant
template <class VertexListGraph, class P, class T, class R>
void neighbor_breadth_first_search
(const VertexListGraph& g,
typename graph_traits<VertexListGraph>::vertex_descriptor s,
const bgl_named_params<P, T, R>& params)
{
// The graph is passed by *const* reference so that graph adaptors
// (temporaries) can be passed into this function. However, the
// graph is not really const since we may write to property maps
// of the graph.
VertexListGraph& ng = const_cast<VertexListGraph&>(g);
typedef typename property_value< bgl_named_params<P,T,R>,
vertex_color_t>::type C;
detail::neighbor_bfs_dispatch<C>::apply(ng, s, params,
get_param(params, vertex_color));
}
// This version does not initialize colors, user has to.
template <class IncidenceGraph, class P, class T, class R>
void neighbor_breadth_first_visit
(IncidenceGraph& g,
typename graph_traits<IncidenceGraph>::vertex_descriptor s,
const bgl_named_params<P, T, R>& params)
{
typedef graph_traits<IncidenceGraph> Traits;
// Buffer default
typedef boost::queue<typename Traits::vertex_descriptor> queue_t;
queue_t Q;
detail::wrap_ref<queue_t> Qref(Q);
detail::neighbor_bfs_impl
(g, s,
choose_param(get_param(params, buffer_param_t()), Qref).ref,
choose_param(get_param(params, graph_visitor),
make_neighbor_bfs_visitor(null_visitor())),
choose_pmap(get_param(params, vertex_color), g, vertex_color)
);
}
} // namespace boost
#endif // BOOST_GRAPH_NEIGHBOR_BREADTH_FIRST_SEARCH_HPP

View File

@@ -1,107 +0,0 @@
//=======================================================================
// Copyright 1997, 1998, 1999, 2000 University of Notre Dame.
// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek
//
// This file is part of the Boost Graph Library
//
// You should have received a copy of the License Agreement for the
// Boost Graph Library along with the software; see the file LICENSE.
// If not, contact Office of Research, University of Notre Dame, Notre
// Dame, IN 46556.
//
// Permission to modify the code and to distribute modified code is
// granted, provided the text of this NOTICE is retained, a notice that
// the code was modified is included with the above COPYRIGHT NOTICE and
// with the COPYRIGHT NOTICE in the LICENSE file, and that the LICENSE
// file is distributed with the modified code.
//
// LICENSOR MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED.
// By way of example, but not limitation, Licensor MAKES NO
// REPRESENTATIONS OR WARRANTIES OF MERCHANTABILITY OR FITNESS FOR ANY
// PARTICULAR PURPOSE OR THAT THE USE OF THE LICENSED SOFTWARE COMPONENTS
// OR DOCUMENTATION WILL NOT INFRINGE ANY PATENTS, COPYRIGHTS, TRADEMARKS
// OR OTHER RIGHTS.
//=======================================================================
//
#ifndef BOOST_GRAPH_MST_PRIM_HPP
#define BOOST_GRAPH_MST_PRIM_HPP
#include <functional>
#include <boost/graph/graph_traits.hpp>
#include <boost/graph/dijkstra_shortest_paths.hpp>
namespace boost {
namespace detail {
// this should be somewhere else in boost...
template <class U, class V> struct _project2nd {
V operator()(U, V v) const { return v; }
};
}
namespace detail {
// This is Prim's algorithm to calculate the Minimum Spanning Tree
// for an undirected graph with weighted edges.
template <class Graph, class P, class T, class R, class Weight>
inline void
prim_mst_impl(const Graph& G,
typename graph_traits<Graph>::vertex_descriptor s,
const bgl_named_params<P,T,R>& params,
Weight)
{
typedef typename property_traits<Weight>::value_type W;
std::less<W> compare;
detail::_project2nd<W,W> combine;
dijkstra_shortest_paths(G, s, params.distance_compare(compare).
distance_combine(combine));
}
} // namespace detail
template <class VertexListGraph, class DijkstraVisitor,
class PredecessorMap, class DistanceMap,
class WeightMap, class IndexMap>
inline void
prim_minimum_spanning_tree
(const VertexListGraph& g,
typename graph_traits<VertexListGraph>::vertex_descriptor s,
PredecessorMap predecessor, DistanceMap distance, WeightMap weight,
IndexMap index_map,
DijkstraVisitor vis)
{
typedef typename property_traits<WeightMap>::value_type W;
std::less<W> compare;
detail::_project2nd<W,W> combine;
dijkstra_shortest_paths(g, s, predecessor, distance, weight, index_map,
compare, combine, (std::numeric_limits<W>::max)(), 0,
vis);
}
template <class VertexListGraph, class PredecessorMap,
class P, class T, class R>
inline void prim_minimum_spanning_tree
(const VertexListGraph& g,
PredecessorMap p_map,
const bgl_named_params<P,T,R>& params)
{
detail::prim_mst_impl
(g,
choose_param(get_param(params, root_vertex_t()), *vertices(g).first),
params.predecessor_map(p_map),
choose_const_pmap(get_param(params, edge_weight), g, edge_weight));
}
template <class VertexListGraph, class PredecessorMap>
inline void prim_minimum_spanning_tree
(const VertexListGraph& g, PredecessorMap p_map)
{
detail::prim_mst_impl
(g, *vertices(g).first, predecessor_map(p_map).
weight_map(get(edge_weight, g)),
get(edge_weight, g));
}
} // namespace boost
#endif // BOOST_GRAPH_MST_PRIM_HPP

View File

@@ -1,60 +0,0 @@
//
//=======================================================================
// Copyright 2002 Marc Wintermantel (wintermantel@imes.mavt.ethz.ch)
// ETH Zurich, Center of Structure Technologies (www.imes.ethz.ch/st)
//
// This file is part of the Boost Graph Library
//
// You should have received a copy of the License Agreement for the
// Boost Graph Library along with the software; see the file LICENSE.
// If not, contact Office of Research, University of Notre Dame, Notre
// Dame, IN 46556.
//
// Permission to modify the code and to distribute modified code is
// granted, provided the text of this NOTICE is retained, a notice that
// the code was modified is included with the above COPYRIGHT NOTICE and
// with the COPYRIGHT NOTICE in the LICENSE file, and that the LICENSE
// file is distributed with the modified code.
//
// LICENSOR MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED.
// By way of example, but not limitation, Licensor MAKES NO
// REPRESENTATIONS OR WARRANTIES OF MERCHANTABILITY OR FITNESS FOR ANY
// PARTICULAR PURPOSE OR THAT THE USE OF THE LICENSED SOFTWARE COMPONENTS
// OR DOCUMENTATION WILL NOT INFRINGE ANY PATENTS, COPYRIGHTS, TRADEMARKS
// OR OTHER RIGHTS.
//=======================================================================
//
#ifndef BOOST_GRAPH_PROFILE_HPP
#define BOOST_GRAPH_PROFILE_HPP
#include <boost/graph/graph_traits.hpp>
#include <boost/detail/numeric_traits.hpp>
#include <boost/graph/bandwidth.hpp>
namespace boost {
template <typename Graph, typename VertexIndexMap>
typename graph_traits<Graph>::vertices_size_type
profile(const Graph& g, VertexIndexMap index)
{
typename graph_traits<Graph>::vertices_size_type b = 0;
typename graph_traits<Graph>::vertex_iterator i, end;
for (tie(i, end) = vertices(g); i != end; ++i){
b += ith_bandwidth(*i, g, index) + 1;
}
return b;
}
template <typename Graph>
typename graph_traits<Graph>::vertices_size_type
profile(const Graph& g)
{
return profile(g, get(vertex_index, g));
}
} // namespace boost
#endif // BOOST_GRAPH_PROFILE_HPP

View File

@@ -1,384 +0,0 @@
//=======================================================================
// Copyright 1997, 1998, 1999, 2000 University of Notre Dame.
// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek
//
// This file is part of the Boost Graph Library
//
// You should have received a copy of the License Agreement for the
// Boost Graph Library along with the software; see the file LICENSE.
// If not, contact Office of Research, University of Notre Dame, Notre
// Dame, IN 46556.
//
// Permission to modify the code and to distribute modified code is
// granted, provided the text of this NOTICE is retained, a notice that
// the code was modified is included with the above COPYRIGHT NOTICE and
// with the COPYRIGHT NOTICE in the LICENSE file, and that the LICENSE
// file is distributed with the modified code.
//
// LICENSOR MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED.
// By way of example, but not limitation, Licensor MAKES NO
// REPRESENTATIONS OR WARRANTIES OF MERCHANTABILITY OR FITNESS FOR ANY
// PARTICULAR PURPOSE OR THAT THE USE OF THE LICENSED SOFTWARE COMPONENTS
// OR DOCUMENTATION WILL NOT INFRINGE ANY PATENTS, COPYRIGHTS, TRADEMARKS
// OR OTHER RIGHTS.
//=======================================================================
#ifndef BOOST_GRAPH_PROPERTIES_HPP
#define BOOST_GRAPH_PROPERTIES_HPP
#include <boost/config.hpp>
#include <cassert>
#include <boost/pending/property.hpp>
#include <boost/property_map.hpp>
#include <boost/graph/graph_traits.hpp>
#include <boost/type_traits/is_convertible.hpp>
namespace boost {
enum default_color_type { white_color, gray_color, green_color, red_color, black_color };
template <class ColorValue>
struct color_traits {
static default_color_type white() { return white_color; }
static default_color_type gray() { return gray_color; }
static default_color_type green() { return green_color; }
static default_color_type red() { return red_color; }
static default_color_type black() { return black_color; }
};
// These functions are now obsolete, replaced by color_traits.
inline default_color_type white(default_color_type) { return white_color; }
inline default_color_type gray(default_color_type) { return gray_color; }
inline default_color_type green(default_color_type) { return green_color; }
inline default_color_type red(default_color_type) { return red_color; }
inline default_color_type black(default_color_type) { return black_color; }
#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
template <>
struct property_traits<default_color_type*> {
typedef default_color_type value_type;
typedef std::ptrdiff_t key_type;
typedef default_color_type& reference;
typedef lvalue_property_map_tag category;
};
// get/put already defined for T*
#endif
struct graph_property_tag { };
struct vertex_property_tag { };
struct edge_property_tag { };
#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
// See examples/edge_property.cpp for how to use this.
#define BOOST_INSTALL_PROPERTY(KIND, NAME) \
template <> struct property_kind<KIND##_##NAME##_t> { \
typedef KIND##_property_tag type; \
}
#else
#define BOOST_INSTALL_PROPERTY(KIND, NAME) \
template <> struct property_kind<KIND##_##NAME##_t> { \
typedef KIND##_property_tag type; \
}
#endif
#define BOOST_DEF_PROPERTY(KIND, NAME) \
enum KIND##_##NAME##_t { KIND##_##NAME }; \
BOOST_INSTALL_PROPERTY(KIND, NAME)
BOOST_DEF_PROPERTY(vertex, all);
BOOST_DEF_PROPERTY(edge, all);
BOOST_DEF_PROPERTY(graph, all);
BOOST_DEF_PROPERTY(vertex, index);
BOOST_DEF_PROPERTY(vertex, index1);
BOOST_DEF_PROPERTY(vertex, index2);
BOOST_DEF_PROPERTY(vertex, root);
BOOST_DEF_PROPERTY(edge, index);
BOOST_DEF_PROPERTY(edge, name);
BOOST_DEF_PROPERTY(edge, weight);
BOOST_DEF_PROPERTY(edge, weight2);
BOOST_DEF_PROPERTY(edge, color);
BOOST_DEF_PROPERTY(vertex, name);
BOOST_DEF_PROPERTY(graph, name);
BOOST_DEF_PROPERTY(vertex, distance);
BOOST_DEF_PROPERTY(vertex, color);
BOOST_DEF_PROPERTY(vertex, degree);
BOOST_DEF_PROPERTY(vertex, in_degree);
BOOST_DEF_PROPERTY(vertex, out_degree);
BOOST_DEF_PROPERTY(vertex, current_degree);
BOOST_DEF_PROPERTY(vertex, priority);
BOOST_DEF_PROPERTY(vertex, discover_time);
BOOST_DEF_PROPERTY(vertex, finish_time);
BOOST_DEF_PROPERTY(vertex, predecessor);
BOOST_DEF_PROPERTY(vertex, rank);
BOOST_DEF_PROPERTY(vertex, centrality);
BOOST_DEF_PROPERTY(edge, reverse);
BOOST_DEF_PROPERTY(edge, capacity);
BOOST_DEF_PROPERTY(edge, residual_capacity);
BOOST_DEF_PROPERTY(edge, centrality);
BOOST_DEF_PROPERTY(graph, visitor);
// These tags are used for property bundles
BOOST_DEF_PROPERTY(vertex, bundle);
BOOST_DEF_PROPERTY(edge, bundle);
#undef BOOST_DEF_PROPERTY
namespace detail {
struct dummy_edge_property_selector {
template <class Graph, class Property, class Tag>
struct bind_ {
typedef identity_property_map type;
typedef identity_property_map const_type;
};
};
struct dummy_vertex_property_selector {
template <class Graph, class Property, class Tag>
struct bind_ {
typedef identity_property_map type;
typedef identity_property_map const_type;
};
};
} // namespace detail
// Graph classes can either partially specialize property_map
// or they can specialize these two selector classes.
template <class GraphTag>
struct edge_property_selector {
typedef detail::dummy_edge_property_selector type;
};
template <class GraphTag>
struct vertex_property_selector {
typedef detail::dummy_vertex_property_selector type;
};
namespace detail {
template <class Graph, class PropertyTag>
struct edge_property_map {
typedef typename Graph::edge_property_type Property;
typedef typename Graph::graph_tag graph_tag;
typedef typename edge_property_selector<graph_tag>::type Selector;
typedef typename Selector::template bind_<Graph,Property,PropertyTag>
Bind;
typedef typename Bind::type type;
typedef typename Bind::const_type const_type;
};
template <class Graph, class PropertyTag>
class vertex_property_map {
typedef typename Graph::vertex_property_type Property;
typedef typename Graph::graph_tag graph_tag;
typedef typename vertex_property_selector<graph_tag>::type Selector;
typedef typename Selector::template bind_<Graph,Property,PropertyTag>
Bind;
public:
typedef typename Bind::type type;
typedef typename Bind::const_type const_type;
};
// This selects the kind of property map, whether is maps from
// edges or from vertices.
//
// It is overly complicated because it's a workaround for
// partial specialization.
struct choose_vertex_property_map {
template <class Graph, class Property>
struct bind_ {
typedef vertex_property_map<Graph, Property> type;
};
};
struct choose_edge_property_map {
template <class Graph, class Property>
struct bind_ {
typedef edge_property_map<Graph, Property> type;
};
};
template <class Kind>
struct property_map_kind_selector {
// VC++ gets confused if this isn't defined, even though
// this never gets used.
typedef choose_vertex_property_map type;
};
template <> struct property_map_kind_selector<vertex_property_tag> {
typedef choose_vertex_property_map type;
};
template <> struct property_map_kind_selector<edge_property_tag> {
typedef choose_edge_property_map type;
};
} // namespace detail
template <class Graph, class Property>
struct property_map {
private:
typedef typename property_kind<Property>::type Kind;
typedef typename detail::property_map_kind_selector<Kind>::type Selector;
typedef typename Selector::template bind_<Graph, Property> Bind;
typedef typename Bind::type Map;
public:
typedef typename Map::type type;
typedef typename Map::const_type const_type;
};
// shortcut for accessing the value type of the property map
template <class Graph, class Property>
class property_map_value {
typedef typename property_map<Graph, Property>::const_type PMap;
public:
typedef typename property_traits<PMap>::value_type type;
};
template <class Graph, class Property>
class graph_property {
public:
typedef typename property_value<typename Graph::graph_property_type,
Property>::type type;
};
template <class Graph>
class vertex_property {
public:
typedef typename Graph::vertex_property_type type;
};
template <class Graph>
class edge_property {
public:
typedef typename Graph::edge_property_type type;
};
template <typename Graph>
class degree_property_map
: public put_get_helper<typename graph_traits<Graph>::degree_size_type,
degree_property_map<Graph> >
{
public:
typedef typename graph_traits<Graph>::vertex_descriptor key_type;
typedef typename graph_traits<Graph>::degree_size_type value_type;
typedef value_type reference;
typedef readable_property_map_tag category;
degree_property_map(const Graph& g) : m_g(g) { }
value_type operator[](const key_type& v) const {
return degree(v, m_g);
}
private:
const Graph& m_g;
};
template <typename Graph>
inline degree_property_map<Graph>
make_degree_map(const Graph& g) {
return degree_property_map<Graph>(g);
}
//========================================================================
// Iterator Property Map Generating Functions contributed by
// Kevin Vanhorn. (see also the property map generating functions
// in boost/property_map.hpp)
#if !defined(BOOST_NO_STD_ITERATOR_TRAITS)
// A helper function for creating a vertex property map out of a
// random access iterator and the internal vertex index map from a
// graph.
template <class PropertyGraph, class RandomAccessIterator>
inline
iterator_property_map<
RandomAccessIterator,
typename property_map<PropertyGraph, vertex_index_t>::type,
typename std::iterator_traits<RandomAccessIterator>::value_type,
typename std::iterator_traits<RandomAccessIterator>::reference
>
make_iterator_vertex_map(RandomAccessIterator iter, const PropertyGraph& g)
{
return make_iterator_property_map(iter, get(vertex_index, g));
}
// Use this next function when vertex_descriptor is known to be an
// integer type, with values ranging from 0 to num_vertices(g).
//
template <class RandomAccessIterator>
inline
iterator_property_map<
RandomAccessIterator,
identity_property_map,
typename std::iterator_traits<RandomAccessIterator>::value_type,
typename std::iterator_traits<RandomAccessIterator>::reference
>
make_iterator_vertex_map(RandomAccessIterator iter)
{
return make_iterator_property_map(iter, identity_property_map());
}
#endif
template <class PropertyGraph, class RandomAccessContainer>
inline
iterator_property_map<
typename RandomAccessContainer::iterator,
typename property_map<PropertyGraph, vertex_index_t>::type,
typename RandomAccessContainer::value_type,
typename RandomAccessContainer::reference
>
make_container_vertex_map(RandomAccessContainer& c, const PropertyGraph& g)
{
assert(c.size() >= num_vertices(g));
return make_iterator_vertex_map(c.begin(), g);
}
template <class RandomAccessContainer> inline
iterator_property_map<
typename RandomAccessContainer::iterator,
identity_property_map,
typename RandomAccessContainer::value_type,
typename RandomAccessContainer::reference
>
make_container_vertex_map(RandomAccessContainer& c)
{
return make_iterator_vertex_map(c.begin());
}
#if defined (BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
# define BOOST_GRAPH_NO_BUNDLED_PROPERTIES
#endif
#ifndef BOOST_GRAPH_NO_BUNDLED_PROPERTIES
template<typename Graph, typename Descriptor, typename Bundle, typename T>
struct bundle_property_map
: put_get_helper<T&, bundle_property_map<Graph, Descriptor, Bundle, T> >
{
typedef Descriptor key_type;
typedef T value_type;
typedef T& reference;
typedef lvalue_property_map_tag category;
bundle_property_map(Graph* g, T Bundle::* pm) : g(g), pm(pm) {}
reference operator[](key_type k) const { return (*g)[k].*pm; }
private:
Graph* g;
T Bundle::* pm;
};
namespace detail {
template<typename VertexBundle, typename EdgeBundle, typename Bundle>
struct is_vertex_bundle : is_convertible<Bundle*, VertexBundle*> {};
}
template <typename Graph, typename T, typename Bundle>
struct property_map<Graph, T Bundle::*>
{
private:
typedef graph_traits<Graph> traits;
typedef typename Graph::vertex_bundled vertex_bundled;
typedef typename Graph::edge_bundled edge_bundled;
typedef typename ct_if<(detail::is_vertex_bundle<vertex_bundled, edge_bundled, Bundle>::value),
typename traits::vertex_descriptor,
typename traits::edge_descriptor>::type
descriptor;
public:
typedef bundle_property_map<Graph, descriptor, Bundle, T> type;
typedef bundle_property_map<const Graph, descriptor, Bundle, const T> const_type;
};
#endif
} // namespace boost
#endif /* BOOST_GRAPH_PROPERTIES_HPPA */

View File

@@ -1,118 +0,0 @@
// (C) Copyright François Faure, iMAGIS-GRAVIR / UJF, 2001. Permission
// to copy, use, modify, sell and distribute this software is granted
// provided this copyright notice appears in all copies. This software
// is provided "as is" without express or implied warranty, and with
// no claim as to its suitability for any purpose.
// Revision History:
// 03 May 2001 Jeremy Siek
// Generalized the property map iterator and moved that
// part to boost/property_map.hpp. Also modified to
// differentiate between const/mutable graphs and
// added a workaround to avoid partial specialization.
// 02 May 2001 François Faure
// Initial version.
#ifndef BOOST_GRAPH_PROPERTY_ITER_RANGE_HPP
#define BOOST_GRAPH_PROPERTY_ITER_RANGE_HPP
#include <boost/property_map_iterator.hpp>
#include <boost/graph/properties.hpp>
#include <boost/pending/ct_if.hpp>
#include <boost/type_traits/same_traits.hpp>
namespace boost {
//======================================================================
// graph property iterator range
template <class Graph, class PropertyTag>
class graph_property_iter_range {
typedef typename property_map<Graph, PropertyTag>::type map_type;
typedef typename property_map<Graph, PropertyTag>::const_type
const_map_type;
typedef typename property_kind<PropertyTag>::type Kind;
typedef typename ct_if<is_same<Kind, vertex_property_tag>::value,
typename graph_traits<Graph>::vertex_iterator,
typename graph_traits<Graph>::edge_iterator>::type iter;
public:
typedef typename property_map_iterator_generator<map_type, iter>::type
iterator;
typedef typename property_map_iterator_generator<const_map_type, iter>
::type const_iterator;
typedef std::pair<iterator, iterator> type;
typedef std::pair<const_iterator, const_iterator> const_type;
};
namespace detail {
template<class Graph,class Tag>
typename graph_property_iter_range<Graph,Tag>::type
get_property_iter_range_kind(Graph& graph, const Tag& tag,
const vertex_property_tag& )
{
typedef typename graph_property_iter_range<Graph,Tag>::iterator iter;
return std::make_pair(iter(vertices(graph).first, get(tag, graph)),
iter(vertices(graph).second, get(tag, graph)));
}
template<class Graph,class Tag>
typename graph_property_iter_range<Graph,Tag>::const_type
get_property_iter_range_kind(const Graph& graph, const Tag& tag,
const vertex_property_tag& )
{
typedef typename graph_property_iter_range<Graph,Tag>
::const_iterator iter;
return std::make_pair(iter(vertices(graph).first, get(tag, graph)),
iter(vertices(graph).second, get(tag, graph)));
}
template<class Graph,class Tag>
typename graph_property_iter_range<Graph,Tag>::type
get_property_iter_range_kind(Graph& graph, const Tag& tag,
const edge_property_tag& )
{
typedef typename graph_property_iter_range<Graph,Tag>::iterator iter;
return std::make_pair(iter(edges(graph).first, get(tag, graph)),
iter(edges(graph).second, get(tag, graph)));
}
template<class Graph,class Tag>
typename graph_property_iter_range<Graph,Tag>::const_type
get_property_iter_range_kind(const Graph& graph, const Tag& tag,
const edge_property_tag& )
{
typedef typename graph_property_iter_range<Graph,Tag>
::const_iterator iter;
return std::make_pair(iter(edges(graph).first, get(tag, graph)),
iter(edges(graph).second, get(tag, graph)));
}
} // namespace detail
//======================================================================
// get an iterator range of properties
template<class Graph, class Tag>
typename graph_property_iter_range<Graph, Tag>::type
get_property_iter_range(Graph& graph, const Tag& tag)
{
typedef typename property_kind<Tag>::type Kind;
return detail::get_property_iter_range_kind(graph, tag, Kind());
}
template<class Graph, class Tag>
typename graph_property_iter_range<Graph, Tag>::const_type
get_property_iter_range(const Graph& graph, const Tag& tag)
{
typedef typename property_kind<Tag>::type Kind;
return detail::get_property_iter_range_kind(graph, tag, Kind());
}
} // namespace boost
#endif // BOOST_GRAPH_PROPERTY_ITER_RANGE_HPP

View File

@@ -1,742 +0,0 @@
//=======================================================================
// Copyright 2000 University of Notre Dame.
// Authors: Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee
//
// This file is part of the Boost Graph Library
//
// You should have received a copy of the License Agreement for the
// Boost Graph Library along with the software; see the file LICENSE.
// If not, contact Office of Research, University of Notre Dame, Notre
// Dame, IN 46556.
//
// Permission to modify the code and to distribute modified code is
// granted, provided the text of this NOTICE is retained, a notice that
// the code was modified is included with the above COPYRIGHT NOTICE and
// with the COPYRIGHT NOTICE in the LICENSE file, and that the LICENSE
// file is distributed with the modified code.
//
// LICENSOR MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED.
// By way of example, but not limitation, Licensor MAKES NO
// REPRESENTATIONS OR WARRANTIES OF MERCHANTABILITY OR FITNESS FOR ANY
// PARTICULAR PURPOSE OR THAT THE USE OF THE LICENSED SOFTWARE COMPONENTS
// OR DOCUMENTATION WILL NOT INFRINGE ANY PATENTS, COPYRIGHTS, TRADEMARKS
// OR OTHER RIGHTS.
//=======================================================================
#ifndef BOOST_PUSH_RELABEL_MAX_FLOW_HPP
#define BOOST_PUSH_RELABEL_MAX_FLOW_HPP
#include <boost/config.hpp>
#include <cassert>
#include <vector>
#include <list>
#include <iosfwd>
#include <algorithm> // for std::min and std::max
#include <boost/pending/queue.hpp>
#include <boost/limits.hpp>
#include <boost/graph/graph_concepts.hpp>
#include <boost/graph/named_function_params.hpp>
namespace boost {
namespace detail {
// This implementation is based on Goldberg's
// "On Implementing Push-Relabel Method for the Maximum Flow Problem"
// by B.V. Cherkassky and A.V. Goldberg, IPCO '95, pp. 157--171
// and on the h_prf.c and hi_pr.c code written by the above authors.
// This implements the highest-label version of the push-relabel method
// with the global relabeling and gap relabeling heuristics.
// The terms "rank", "distance", "height" are synonyms in
// Goldberg's implementation, paper and in the CLR. A "layer" is a
// group of vertices with the same distance. The vertices in each
// layer are categorized as active or inactive. An active vertex
// has positive excess flow and its distance is less than n (it is
// not blocked).
template <class Vertex>
struct preflow_layer {
std::list<Vertex> active_vertices;
std::list<Vertex> inactive_vertices;
};
template <class Graph,
class EdgeCapacityMap, // integer value type
class ResidualCapacityEdgeMap,
class ReverseEdgeMap,
class VertexIndexMap, // vertex_descriptor -> integer
class FlowValue>
class push_relabel
{
public:
typedef graph_traits<Graph> Traits;
typedef typename Traits::vertex_descriptor vertex_descriptor;
typedef typename Traits::edge_descriptor edge_descriptor;
typedef typename Traits::vertex_iterator vertex_iterator;
typedef typename Traits::out_edge_iterator out_edge_iterator;
typedef typename Traits::vertices_size_type vertices_size_type;
typedef typename Traits::edges_size_type edges_size_type;
typedef preflow_layer<vertex_descriptor> Layer;
typedef std::vector< Layer > LayerArray;
typedef typename LayerArray::iterator layer_iterator;
typedef typename LayerArray::size_type distance_size_type;
typedef color_traits<default_color_type> ColorTraits;
//=======================================================================
// Some helper predicates
inline bool is_admissible(vertex_descriptor u, vertex_descriptor v) {
return distance[u] == distance[v] + 1;
}
inline bool is_residual_edge(edge_descriptor a) {
return 0 < residual_capacity[a];
}
inline bool is_saturated(edge_descriptor a) {
return residual_capacity[a] == 0;
}
//=======================================================================
// Layer List Management Functions
typedef typename std::list<vertex_descriptor>::iterator list_iterator;
void add_to_active_list(vertex_descriptor u, Layer& layer) {
BOOST_USING_STD_MIN();
BOOST_USING_STD_MAX();
layer.active_vertices.push_front(u);
max_active = max BOOST_PREVENT_MACRO_SUBSTITUTION(distance[u], max_active);
min_active = min BOOST_PREVENT_MACRO_SUBSTITUTION(distance[u], min_active);
layer_list_ptr[u] = layer.active_vertices.begin();
}
void remove_from_active_list(vertex_descriptor u) {
layers[distance[u]].active_vertices.erase(layer_list_ptr[u]);
}
void add_to_inactive_list(vertex_descriptor u, Layer& layer) {
layer.inactive_vertices.push_front(u);
layer_list_ptr[u] = layer.inactive_vertices.begin();
}
void remove_from_inactive_list(vertex_descriptor u) {
layers[distance[u]].inactive_vertices.erase(layer_list_ptr[u]);
}
//=======================================================================
// initialization
push_relabel(Graph& g_,
EdgeCapacityMap cap,
ResidualCapacityEdgeMap res,
ReverseEdgeMap rev,
vertex_descriptor src_,
vertex_descriptor sink_,
VertexIndexMap idx)
: g(g_), n(num_vertices(g_)), capacity(cap), src(src_), sink(sink_),
index(idx),
excess_flow(num_vertices(g_)),
layer_list_ptr(num_vertices(g_)),
current(num_vertices(g_)),
distance(num_vertices(g_)),
color(num_vertices(g_)),
reverse_edge(rev),
residual_capacity(res),
layers(num_vertices(g_)),
push_count(0), update_count(0), relabel_count(0),
gap_count(0), gap_node_count(0),
work_since_last_update(0)
{
vertex_iterator u_iter, u_end;
// Don't count the reverse edges
edges_size_type m = num_edges(g) / 2;
nm = alpha() * n + m;
// Initialize flow to zero which means initializing
// the residual capacity to equal the capacity.
out_edge_iterator ei, e_end;
for (tie(u_iter, u_end) = vertices(g); u_iter != u_end; ++u_iter)
for (tie(ei, e_end) = out_edges(*u_iter, g); ei != e_end; ++ei) {
residual_capacity[*ei] = capacity[*ei];
}
for (tie(u_iter, u_end) = vertices(g); u_iter != u_end; ++u_iter) {
vertex_descriptor u = *u_iter;
excess_flow[u] = 0;
current[u] = out_edges(u, g).first;
}
bool overflow_detected = false;
FlowValue test_excess = 0;
out_edge_iterator a_iter, a_end;
for (tie(a_iter, a_end) = out_edges(src, g); a_iter != a_end; ++a_iter)
if (target(*a_iter, g) != src)
test_excess += residual_capacity[*a_iter];
if (test_excess > (std::numeric_limits<FlowValue>::max)())
overflow_detected = true;
if (overflow_detected)
excess_flow[src] = (std::numeric_limits<FlowValue>::max)();
else {
excess_flow[src] = 0;
for (tie(a_iter, a_end) = out_edges(src, g);
a_iter != a_end; ++a_iter) {
edge_descriptor a = *a_iter;
if (target(a, g) != src) {
++push_count;
FlowValue delta = residual_capacity[a];
residual_capacity[a] -= delta;
residual_capacity[reverse_edge[a]] += delta;
excess_flow[target(a, g)] += delta;
}
}
}
max_distance = num_vertices(g) - 1;
max_active = 0;
min_active = n;
for (tie(u_iter, u_end) = vertices(g); u_iter != u_end; ++u_iter) {
vertex_descriptor u = *u_iter;
if (u == sink) {
distance[u] = 0;
continue;
} else if (u == src && !overflow_detected)
distance[u] = n;
else
distance[u] = 1;
if (excess_flow[u] > 0)
add_to_active_list(u, layers[1]);
else if (distance[u] < n)
add_to_inactive_list(u, layers[1]);
}
} // push_relabel constructor
//=======================================================================
// This is a breadth-first search over the residual graph
// (well, actually the reverse of the residual graph).
// Would be cool to have a graph view adaptor for hiding certain
// edges, like the saturated (non-residual) edges in this case.
// Goldberg's implementation abused "distance" for the coloring.
void global_distance_update()
{
BOOST_USING_STD_MAX();
++update_count;
vertex_iterator u_iter, u_end;
for (tie(u_iter,u_end) = vertices(g); u_iter != u_end; ++u_iter) {
color[*u_iter] = ColorTraits::white();
distance[*u_iter] = n;
}
color[sink] = ColorTraits::gray();
distance[sink] = 0;
for (distance_size_type l = 0; l <= max_distance; ++l) {
layers[l].active_vertices.clear();
layers[l].inactive_vertices.clear();
}
max_distance = max_active = 0;
min_active = n;
Q.push(sink);
while (! Q.empty()) {
vertex_descriptor u = Q.top();
Q.pop();
distance_size_type d_v = distance[u] + 1;
out_edge_iterator ai, a_end;
for (tie(ai, a_end) = out_edges(u, g); ai != a_end; ++ai) {
edge_descriptor a = *ai;
vertex_descriptor v = target(a, g);
if (color[v] == ColorTraits::white()
&& is_residual_edge(reverse_edge[a])) {
distance[v] = d_v;
color[v] = ColorTraits::gray();
current[v] = out_edges(v, g).first;
max_distance = max BOOST_PREVENT_MACRO_SUBSTITUTION(d_v, max_distance);
if (excess_flow[v] > 0)
add_to_active_list(v, layers[d_v]);
else
add_to_inactive_list(v, layers[d_v]);
Q.push(v);
}
}
}
} // global_distance_update()
//=======================================================================
// This function is called "push" in Goldberg's h_prf implementation,
// but it is called "discharge" in the paper and in hi_pr.c.
void discharge(vertex_descriptor u)
{
assert(excess_flow[u] > 0);
while (1) {
out_edge_iterator ai, ai_end;
for (ai = current[u], ai_end = out_edges(u, g).second;
ai != ai_end; ++ai) {
edge_descriptor a = *ai;
if (is_residual_edge(a)) {
vertex_descriptor v = target(a, g);
if (is_admissible(u, v)) {
++push_count;
if (v != sink && excess_flow[v] == 0) {
remove_from_inactive_list(v);
add_to_active_list(v, layers[distance[v]]);
}
push_flow(a);
if (excess_flow[u] == 0)
break;
}
}
} // for out_edges of i starting from current
Layer& layer = layers[distance[u]];
distance_size_type du = distance[u];
if (ai == ai_end) { // i must be relabeled
relabel_distance(u);
if (layer.active_vertices.empty()
&& layer.inactive_vertices.empty())
gap(du);
if (distance[u] == n)
break;
} else { // i is no longer active
current[u] = ai;
add_to_inactive_list(u, layer);
break;
}
} // while (1)
} // discharge()
//=======================================================================
// This corresponds to the "push" update operation of the paper,
// not the "push" function in Goldberg's h_prf.c implementation.
// The idea is to push the excess flow from from vertex u to v.
void push_flow(edge_descriptor u_v)
{
vertex_descriptor
u = source(u_v, g),
v = target(u_v, g);
BOOST_USING_STD_MIN();
FlowValue flow_delta
= min BOOST_PREVENT_MACRO_SUBSTITUTION(excess_flow[u], residual_capacity[u_v]);
residual_capacity[u_v] -= flow_delta;
residual_capacity[reverse_edge[u_v]] += flow_delta;
excess_flow[u] -= flow_delta;
excess_flow[v] += flow_delta;
} // push_flow()
//=======================================================================
// The main purpose of this routine is to set distance[v]
// to the smallest value allowed by the valid labeling constraints,
// which are:
// distance[t] = 0
// distance[u] <= distance[v] + 1 for every residual edge (u,v)
//
distance_size_type relabel_distance(vertex_descriptor u)
{
BOOST_USING_STD_MAX();
++relabel_count;
work_since_last_update += beta();
distance_size_type min_distance = num_vertices(g);
distance[u] = min_distance;
// Examine the residual out-edges of vertex i, choosing the
// edge whose target vertex has the minimal distance.
out_edge_iterator ai, a_end, min_edge_iter;
for (tie(ai, a_end) = out_edges(u, g); ai != a_end; ++ai) {
++work_since_last_update;
edge_descriptor a = *ai;
vertex_descriptor v = target(a, g);
if (is_residual_edge(a) && distance[v] < min_distance) {
min_distance = distance[v];
min_edge_iter = ai;
}
}
++min_distance;
if (min_distance < n) {
distance[u] = min_distance; // this is the main action
current[u] = min_edge_iter;
max_distance = max BOOST_PREVENT_MACRO_SUBSTITUTION(min_distance, max_distance);
}
return min_distance;
} // relabel_distance()
//=======================================================================
// cleanup beyond the gap
void gap(distance_size_type empty_distance)
{
++gap_count;
distance_size_type r; // distance of layer before the current layer
r = empty_distance - 1;
// Set the distance for the vertices beyond the gap to "infinity".
for (layer_iterator l = layers.begin() + empty_distance + 1;
l < layers.begin() + max_distance; ++l) {
list_iterator i;
for (i = l->inactive_vertices.begin();
i != l->inactive_vertices.end(); ++i) {
distance[*i] = n;
++gap_node_count;
}
l->inactive_vertices.clear();
}
max_distance = r;
max_active = r;
}
//=======================================================================
// This is the core part of the algorithm, "phase one".
FlowValue maximum_preflow()
{
work_since_last_update = 0;
while (max_active >= min_active) { // "main" loop
Layer& layer = layers[max_active];
list_iterator u_iter = layer.active_vertices.begin();
if (u_iter == layer.active_vertices.end())
--max_active;
else {
vertex_descriptor u = *u_iter;
remove_from_active_list(u);
discharge(u);
if (work_since_last_update * global_update_frequency() > nm) {
global_distance_update();
work_since_last_update = 0;
}
}
} // while (max_active >= min_active)
return excess_flow[sink];
} // maximum_preflow()
//=======================================================================
// remove excess flow, the "second phase"
// This does a DFS on the reverse flow graph of nodes with excess flow.
// If a cycle is found, cancel it.
// Return the nodes with excess flow in topological order.
//
// Unlike the prefl_to_flow() implementation, we use
// "color" instead of "distance" for the DFS labels
// "parent" instead of nl_prev for the DFS tree
// "topo_next" instead of nl_next for the topological ordering
void convert_preflow_to_flow()
{
vertex_iterator u_iter, u_end;
out_edge_iterator ai, a_end;
vertex_descriptor r, restart, u;
std::vector<vertex_descriptor> parent(n);
std::vector<vertex_descriptor> topo_next(n);
vertex_descriptor tos(parent[0]),
bos(parent[0]); // bogus initialization, just to avoid warning
bool bos_null = true;
// handle self-loops
for (tie(u_iter, u_end) = vertices(g); u_iter != u_end; ++u_iter)
for (tie(ai, a_end) = out_edges(*u_iter, g); ai != a_end; ++ai)
if (target(*ai, g) == *u_iter)
residual_capacity[*ai] = capacity[*ai];
// initialize
for (tie(u_iter, u_end) = vertices(g); u_iter != u_end; ++u_iter) {
u = *u_iter;
color[u] = ColorTraits::white();
parent[u] = u;
current[u] = out_edges(u, g).first;
}
// eliminate flow cycles and topologically order the vertices
for (tie(u_iter, u_end) = vertices(g); u_iter != u_end; ++u_iter) {
u = *u_iter;
if (color[u] == ColorTraits::white()
&& excess_flow[u] > 0
&& u != src && u != sink ) {
r = u;
color[r] = ColorTraits::gray();
while (1) {
for (; current[u] != out_edges(u, g).second; ++current[u]) {
edge_descriptor a = *current[u];
if (capacity[a] == 0 && is_residual_edge(a)) {
vertex_descriptor v = target(a, g);
if (color[v] == ColorTraits::white()) {
color[v] = ColorTraits::gray();
parent[v] = u;
u = v;
break;
} else if (color[v] == ColorTraits::gray()) {
// find minimum flow on the cycle
FlowValue delta = residual_capacity[a];
while (1) {
BOOST_USING_STD_MIN();
delta = min BOOST_PREVENT_MACRO_SUBSTITUTION(delta, residual_capacity[*current[v]]);
if (v == u)
break;
else
v = target(*current[v], g);
}
// remove delta flow units
v = u;
while (1) {
a = *current[v];
residual_capacity[a] -= delta;
residual_capacity[reverse_edge[a]] += delta;
v = target(a, g);
if (v == u)
break;
}
// back-out of DFS to the first saturated edge
restart = u;
for (v = target(*current[u], g); v != u; v = target(a, g)){
a = *current[v];
if (color[v] == ColorTraits::white()
|| is_saturated(a)) {
color[target(*current[v], g)] = ColorTraits::white();
if (color[v] != ColorTraits::white())
restart = v;
}
}
if (restart != u) {
u = restart;
++current[u];
break;
}
} // else if (color[v] == ColorTraits::gray())
} // if (capacity[a] == 0 ...
} // for out_edges(u, g) (though "u" changes during loop)
if (current[u] == out_edges(u, g).second) {
// scan of i is complete
color[u] = ColorTraits::black();
if (u != src) {
if (bos_null) {
bos = u;
bos_null = false;
tos = u;
} else {
topo_next[u] = tos;
tos = u;
}
}
if (u != r) {
u = parent[u];
++current[u];
} else
break;
}
} // while (1)
} // if (color[u] == white && excess_flow[u] > 0 & ...)
} // for all vertices in g
// return excess flows
// note that the sink is not on the stack
if (! bos_null) {
for (u = tos; u != bos; u = topo_next[u]) {
ai = out_edges(u, g).first;
while (excess_flow[u] > 0 && ai != out_edges(u, g).second) {
if (capacity[*ai] == 0 && is_residual_edge(*ai))
push_flow(*ai);
++ai;
}
}
// do the bottom
u = bos;
ai = out_edges(u, g).first;
while (excess_flow[u] > 0) {
if (capacity[*ai] == 0 && is_residual_edge(*ai))
push_flow(*ai);
++ai;
}
}
} // convert_preflow_to_flow()
//=======================================================================
inline bool is_flow()
{
vertex_iterator u_iter, u_end;
out_edge_iterator ai, a_end;
// check edge flow values
for (tie(u_iter, u_end) = vertices(g); u_iter != u_end; ++u_iter) {
for (tie(ai, a_end) = out_edges(*u_iter, g); ai != a_end; ++ai) {
edge_descriptor a = *ai;
if (capacity[a] > 0)
if ((residual_capacity[a] + residual_capacity[reverse_edge[a]]
!= capacity[a] + capacity[reverse_edge[a]])
|| (residual_capacity[a] < 0)
|| (residual_capacity[reverse_edge[a]] < 0))
return false;
}
}
// check conservation
FlowValue sum;
for (tie(u_iter, u_end) = vertices(g); u_iter != u_end; ++u_iter) {
vertex_descriptor u = *u_iter;
if (u != src && u != sink) {
if (excess_flow[u] != 0)
return false;
sum = 0;
for (tie(ai, a_end) = out_edges(u, g); ai != a_end; ++ai)
if (capacity[*ai] > 0)
sum -= capacity[*ai] - residual_capacity[*ai];
else
sum += residual_capacity[*ai];
if (excess_flow[u] != sum)
return false;
}
}
return true;
} // is_flow()
bool is_optimal() {
// check if mincut is saturated...
global_distance_update();
return distance[src] >= n;
}
void print_statistics(std::ostream& os) const {
os << "pushes: " << push_count << std::endl
<< "relabels: " << relabel_count << std::endl
<< "updates: " << update_count << std::endl
<< "gaps: " << gap_count << std::endl
<< "gap nodes: " << gap_node_count << std::endl
<< std::endl;
}
void print_flow_values(std::ostream& os) const {
os << "flow values" << std::endl;
vertex_iterator u_iter, u_end;
out_edge_iterator ei, e_end;
for (tie(u_iter, u_end) = vertices(g); u_iter != u_end; ++u_iter)
for (tie(ei, e_end) = out_edges(*u_iter, g); ei != e_end; ++ei)
if (capacity[*ei] > 0)
os << *u_iter << " " << target(*ei, g) << " "
<< (capacity[*ei] - residual_capacity[*ei]) << std::endl;
os << std::endl;
}
//=======================================================================
Graph& g;
vertices_size_type n;
vertices_size_type nm;
EdgeCapacityMap capacity;
vertex_descriptor src;
vertex_descriptor sink;
VertexIndexMap index;
// will need to use random_access_property_map with these
std::vector< FlowValue > excess_flow;
std::vector< list_iterator > layer_list_ptr;
std::vector< out_edge_iterator > current;
std::vector< distance_size_type > distance;
std::vector< default_color_type > color;
// Edge Property Maps that must be interior to the graph
ReverseEdgeMap reverse_edge;
ResidualCapacityEdgeMap residual_capacity;
LayerArray layers;
distance_size_type max_distance; // maximal distance
distance_size_type max_active; // maximal distance with active node
distance_size_type min_active; // minimal distance with active node
boost::queue<vertex_descriptor> Q;
// Statistics counters
long push_count;
long update_count;
long relabel_count;
long gap_count;
long gap_node_count;
inline double global_update_frequency() { return 0.5; }
inline vertices_size_type alpha() { return 6; }
inline long beta() { return 12; }
long work_since_last_update;
};
} // namespace detail
template <class Graph,
class CapacityEdgeMap, class ResidualCapacityEdgeMap,
class ReverseEdgeMap, class VertexIndexMap>
typename property_traits<CapacityEdgeMap>::value_type
push_relabel_max_flow
(Graph& g,
typename graph_traits<Graph>::vertex_descriptor src,
typename graph_traits<Graph>::vertex_descriptor sink,
CapacityEdgeMap cap, ResidualCapacityEdgeMap res,
ReverseEdgeMap rev, VertexIndexMap index_map)
{
typedef typename property_traits<CapacityEdgeMap>::value_type FlowValue;
detail::push_relabel<Graph, CapacityEdgeMap, ResidualCapacityEdgeMap,
ReverseEdgeMap, VertexIndexMap, FlowValue>
algo(g, cap, res, rev, src, sink, index_map);
FlowValue flow = algo.maximum_preflow();
algo.convert_preflow_to_flow();
assert(algo.is_flow());
assert(algo.is_optimal());
return flow;
} // push_relabel_max_flow()
template <class Graph, class P, class T, class R>
typename detail::edge_capacity_value<Graph, P, T, R>::type
push_relabel_max_flow
(Graph& g,
typename graph_traits<Graph>::vertex_descriptor src,
typename graph_traits<Graph>::vertex_descriptor sink,
const bgl_named_params<P, T, R>& params)
{
return push_relabel_max_flow
(g, src, sink,
choose_const_pmap(get_param(params, edge_capacity), g, edge_capacity),
choose_pmap(get_param(params, edge_residual_capacity),
g, edge_residual_capacity),
choose_const_pmap(get_param(params, edge_reverse), g, edge_reverse),
choose_const_pmap(get_param(params, vertex_index), g, vertex_index)
);
}
template <class Graph>
typename property_traits<
typename property_map<Graph, edge_capacity_t>::const_type
>::value_type
push_relabel_max_flow
(Graph& g,
typename graph_traits<Graph>::vertex_descriptor src,
typename graph_traits<Graph>::vertex_descriptor sink)
{
bgl_named_params<int, buffer_param_t> params(0); // bogus empty param
return push_relabel_max_flow(g, src, sink, params);
}
} // namespace boost
#endif // BOOST_PUSH_RELABEL_MAX_FLOW_HPP

View File

@@ -1,220 +0,0 @@
//
//=======================================================================
// Copyright 1997, 1998, 1999, 2000 University of Notre Dame.
// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek
//
// This file is part of the Boost Graph Library
//
// You should have received a copy of the License Agreement for the
// Boost Graph Library along with the software; see the file LICENSE.
// If not, contact Office of Research, University of Notre Dame, Notre
// Dame, IN 46556.
//
// Permission to modify the code and to distribute modified code is
// granted, provided the text of this NOTICE is retained, a notice that
// the code was modified is included with the above COPYRIGHT NOTICE and
// with the COPYRIGHT NOTICE in the LICENSE file, and that the LICENSE
// file is distributed with the modified code.
//
// LICENSOR MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED.
// By way of example, but not limitation, Licensor MAKES NO
// REPRESENTATIONS OR WARRANTIES OF MERCHANTABILITY OR FITNESS FOR ANY
// PARTICULAR PURPOSE OR THAT THE USE OF THE LICENSED SOFTWARE COMPONENTS
// OR DOCUMENTATION WILL NOT INFRINGE ANY PATENTS, COPYRIGHTS, TRADEMARKS
// OR OTHER RIGHTS.
//=======================================================================
//
// Copyright (C) Vladimir Prus 2003. Permission to copy, use,
// modify, sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
#ifndef BOOST_GRAPH_RANDOM_HPP
#define BOOST_GRAPH_RANDOM_HPP
#include <boost/graph/graph_traits.hpp>
#include <boost/random/uniform_int.hpp>
#include <boost/random/variate_generator.hpp>
#include <boost/pending/property.hpp>
#include <boost/graph/properties.hpp>
#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/copy.hpp>
#include <boost/mpl/if.hpp>
#include <boost/type_traits/is_convertible.hpp>
#include <iostream>
namespace boost {
// grab a random vertex from the graph's vertex set
template <class Graph, class RandomNumGen>
typename graph_traits<Graph>::vertex_descriptor
random_vertex(Graph& g, RandomNumGen& gen)
{
if (num_vertices(g) > 1) {
uniform_int<> distrib(0, num_vertices(g)-1);
variate_generator<RandomNumGen&, uniform_int<> > rand_gen(gen, distrib);
std::size_t n = rand_gen();
typename graph_traits<Graph>::vertex_iterator
i = vertices(g).first;
while (n-- > 0) ++i; // std::advance not VC++ portable
return *i;
} else
return *vertices(g).first;
}
template <class Graph, class RandomNumGen>
typename graph_traits<Graph>::edge_descriptor
random_edge(Graph& g, RandomNumGen& gen) {
if (num_edges(g) > 1) {
uniform_int<> distrib(0, num_edges(g)-1);
variate_generator<RandomNumGen&, uniform_int<> > rand_gen(gen, distrib);
typename graph_traits<Graph>::edges_size_type
n = rand_gen();
typename graph_traits<Graph>::edge_iterator
i = edges(g).first;
while (n-- > 0) ++i; // std::advance not VC++ portable
return *i;
} else
return *edges(g).first;
}
namespace detail {
class dummy_property_copier {
public:
template<class V1, class V2>
void operator()(const V1&, const V2&) const {}
};
}
template <typename MutableGraph, class RandNumGen>
void generate_random_graph1
(MutableGraph& g,
typename graph_traits<MutableGraph>::vertices_size_type V,
typename graph_traits<MutableGraph>::vertices_size_type E,
RandNumGen& gen,
bool allow_parallel = true,
bool self_edges = false)
{
typedef graph_traits<MutableGraph> Traits;
typedef typename Traits::vertices_size_type v_size_t;
typedef typename Traits::edges_size_type e_size_t;
typedef typename Traits::vertex_descriptor vertex_descriptor;
// When parallel edges are not allowed, we create a new graph which
// does not allow parallel edges, construct it and copy back.
// This is not efficient if 'g' already disallow parallel edges,
// but that's task for later.
if (!allow_parallel) {
typedef typename boost::graph_traits<MutableGraph>::directed_category dir;
typedef typename mpl::if_<is_convertible<dir, directed_tag>,
directedS, undirectedS>::type select;
adjacency_list<setS, vecS, select> g2;
generate_random_graph1(g2, V, E, gen, true, self_edges);
copy_graph(g2, g, vertex_copy(detail::dummy_property_copier()).
edge_copy(detail::dummy_property_copier()));
} else {
for (v_size_t i = 0; i < V; ++i)
add_vertex(g);
for (e_size_t j = 0; j < E; ++j) {
vertex_descriptor a = random_vertex(g, gen), b;
do {
b = random_vertex(g, gen);
} while (self_edges == false && a == b);
add_edge(a, b, g);
}
}
}
template <typename MutableGraph, class RandNumGen>
void generate_random_graph
(MutableGraph& g,
typename graph_traits<MutableGraph>::vertices_size_type V,
typename graph_traits<MutableGraph>::vertices_size_type E,
RandNumGen& gen,
bool allow_parallel = true,
bool self_edges = false)
{
generate_random_graph1(g, V, E, gen, allow_parallel, self_edges);
}
template <typename MutableGraph, typename RandNumGen,
typename VertexOutputIterator, typename EdgeOutputIterator>
void generate_random_graph
(MutableGraph& g,
typename graph_traits<MutableGraph>::vertices_size_type V,
typename graph_traits<MutableGraph>::vertices_size_type E,
RandNumGen& gen,
VertexOutputIterator vertex_out,
EdgeOutputIterator edge_out,
bool self_edges = false)
{
typedef graph_traits<MutableGraph> Traits;
typedef typename Traits::vertices_size_type v_size_t;
typedef typename Traits::edges_size_type e_size_t;
typedef typename Traits::vertex_descriptor vertex_t;
typedef typename Traits::edge_descriptor edge_t;
for (v_size_t i = 0; i < V; ++i)
*vertex_out++ = add_vertex(g);
for (e_size_t j = 0; j < E; ++j) {
vertex_t a = random_vertex(g, gen), b;
do {
b = random_vertex(g, gen);
} while (self_edges == false && a == b);
edge_t e; bool inserted;
tie(e, inserted) = add_edge(a, b, g);
if (inserted)
*edge_out++ = std::make_pair(source(e, g), target(e, g));
}
}
namespace detail {
template<class Property, class G, class RandomGenerator>
void randomize_property(G& g, RandomGenerator& rg,
Property, vertex_property_tag)
{
typename property_map<G, Property>::type pm = get(Property(), g);
typename graph_traits<G>::vertex_iterator vi, ve;
for (tie(vi, ve) = vertices(g); vi != ve; ++vi) {
pm[*vi] = rg();
}
}
template<class Property, class G, class RandomGenerator>
void randomize_property(G& g, RandomGenerator& rg,
Property, edge_property_tag)
{
typename property_map<G, Property>::type pm = get(Property(), g);
typename graph_traits<G>::edge_iterator ei, ee;
for (tie(ei, ee) = edges(g); ei != ee; ++ei) {
pm[*ei] = rg();
}
}
}
template<class Property, class G, class RandomGenerator>
void randomize_property(G& g, RandomGenerator& rg)
{
detail::randomize_property
(g, rg, Property(), typename property_kind<Property>::type());
}
}
#endif

View File

@@ -1,294 +0,0 @@
//=======================================================================
// Copyright 1997, 1998, 1999, 2000 University of Notre Dame.
// Authors: Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee
//
// This file is part of the Boost Graph Library
//
// You should have received a copy of the License Agreement for the
// Boost Graph Library along with the software; see the file LICENSE.
// If not, contact Office of Research, University of Notre Dame, Notre
// Dame, IN 46556.
//
// Permission to modify the code and to distribute modified code is
// granted, provided the text of this NOTICE is retained, a notice that
// the code was modified is included with the above COPYRIGHT NOTICE and
// with the COPYRIGHT NOTICE in the LICENSE file, and that the LICENSE
// file is distributed with the modified code.
//
// LICENSOR MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED.
// By way of example, but not limitation, Licensor MAKES NO
// REPRESENTATIONS OR WARRANTIES OF MERCHANTABILITY OR FITNESS FOR ANY
// PARTICULAR PURPOSE OR THAT THE USE OF THE LICENSED SOFTWARE COMPONENTS
// OR DOCUMENTATION WILL NOT INFRINGE ANY PATENTS, COPYRIGHTS, TRADEMARKS
// OR OTHER RIGHTS.
//=======================================================================
/*
Reads maximal flow problem in extended DIMACS format.
Reads from stdin.
This works, but could use some polishing.
*/
/* ----------------------------------------------------------------- */
#include <vector>
#include <stdio.h>
namespace boost {
template <class Graph, class CapacityMap, class ReverseEdgeMap>
int read_dimacs_max_flow(Graph& g,
CapacityMap capacity,
ReverseEdgeMap reverse_edge,
typename graph_traits<Graph>::vertex_descriptor& src,
typename graph_traits<Graph>::vertex_descriptor& sink)
{
// const int MAXLINE = 100; /* max line length in the input file */
const int ARC_FIELDS = 3; /* no of fields in arc line */
const int NODE_FIELDS = 2; /* no of fields in node line */
const int P_FIELDS = 3; /* no of fields in problem line */
const char* PROBLEM_TYPE = "max"; /* name of problem type*/
typedef typename graph_traits<Graph>::vertices_size_type vertices_size_type;
typedef typename graph_traits<Graph>::vertex_descriptor vertex_descriptor;
typedef typename graph_traits<Graph>::edge_descriptor edge_descriptor;
std::vector<vertex_descriptor> verts;
long m, n, /* number of edges and nodes */
i, head, tail, cap;
long no_lines=0, /* no of current input line */
no_plines=0, /* no of problem-lines */
no_nslines=0, /* no of node-source-lines */
no_nklines=0, /* no of node-source-lines */
no_alines=0; /* no of arc-lines */
std::string in_line; /* for reading input line */
char pr_type[3]; /* for reading type of the problem */
char nd; /* source (s) or sink (t) */
int k, /* temporary */
err_no; /* no of detected error */
/* -------------- error numbers & error messages ---------------- */
const int EN1 = 0;
const int EN2 = 1;
const int EN3 = 2;
const int EN4 = 3;
// const int EN6 = 4;
// const int EN10 = 5;
// const int EN7 = 6;
const int EN8 = 7;
const int EN9 = 8;
const int EN11 = 9;
const int EN12 = 10;
// const int EN13 = 11;
const int EN14 = 12;
const int EN16 = 13;
const int EN15 = 14;
const int EN17 = 15;
const int EN18 = 16;
const int EN21 = 17;
const int EN19 = 18;
const int EN20 = 19;
const int EN22 = 20;
static char *err_message[] =
{
/* 0*/ "more than one problem line.",
/* 1*/ "wrong number of parameters in the problem line.",
/* 2*/ "it is not a Max Flow problem line.",
/* 3*/ "bad value of a parameter in the problem line.",
/* 4*/ "can't obtain enough memory to solve this problem.",
/* 5*/ "more than one line with the problem name.",
/* 6*/ "can't read problem name.",
/* 7*/ "problem description must be before node description.",
/* 8*/ "this parser doesn't support multiply sources and sinks.",
/* 9*/ "wrong number of parameters in the node line.",
/*10*/ "wrong value of parameters in the node line.",
/*11*/ " ",
/*12*/ "source and sink descriptions must be before arc descriptions.",
/*13*/ "too many arcs in the input.",
/*14*/ "wrong number of parameters in the arc line.",
/*15*/ "wrong value of parameters in the arc line.",
/*16*/ "unknown line type in the input.",
/*17*/ "reading error.",
/*18*/ "not enough arcs in the input.",
/*19*/ "source or sink doesn't have incident arcs.",
/*20*/ "can't read anything from the input file."
};
/* --------------------------------------------------------------- */
/* The main loop:
- reads the line of the input,
- analyses its type,
- checks correctness of parameters,
- puts data to the arrays,
- does service functions
*/
while (std::getline(std::cin, in_line)) {
++no_lines;
switch (in_line[0]) {
case 'c': /* skip lines with comments */
case '\n': /* skip empty lines */
case '\0': /* skip empty lines at the end of file */
break;
case 'p': /* problem description */
if ( no_plines > 0 )
/* more than one problem line */
{ err_no = EN1 ; goto error; }
no_plines = 1;
if (
/* reading problem line: type of problem, no of nodes, no of arcs */
sscanf ( in_line.c_str(), "%*c %3s %ld %ld", pr_type, &n, &m )
!= P_FIELDS
)
/*wrong number of parameters in the problem line*/
{ err_no = EN2; goto error; }
if ( strcmp ( pr_type, PROBLEM_TYPE ) )
/*wrong problem type*/
{ err_no = EN3; goto error; }
if ( n <= 0 || m <= 0 )
/*wrong value of no of arcs or nodes*/
{ err_no = EN4; goto error; }
{
for (long vi = 0; vi < n; ++vi)
verts.push_back(add_vertex(g));
}
break;
case 'n': /* source(s) description */
if ( no_plines == 0 )
/* there was not problem line above */
{ err_no = EN8; goto error; }
/* reading source or sink */
k = sscanf ( in_line.c_str(),"%*c %ld %c", &i, &nd );
--i; // index from 0
if ( k < NODE_FIELDS )
/* node line is incorrect */
{ err_no = EN11; goto error; }
if ( i < 0 || i > n )
/* wrong value of node */
{ err_no = EN12; goto error; }
switch (nd) {
case 's': /* source line */
if ( no_nslines != 0)
/* more than one source line */
{ err_no = EN9; goto error; }
no_nslines = 1;
src = verts[i];
break;
case 't': /* sink line */
if ( no_nklines != 0)
/* more than one sink line */
{ err_no = EN9; goto error; }
no_nklines = 1;
sink = verts[i];
break;
default:
/* wrong type of node-line */
err_no = EN12; goto error;
}
break;
case 'a': /* arc description */
if ( no_nslines == 0 || no_nklines == 0 )
/* there was not source and sink description above */
{ err_no = EN14; goto error; }
if ( no_alines >= m )
/*too many arcs on input*/
{ err_no = EN16; goto error; }
if (
/* reading an arc description */
sscanf ( in_line.c_str(),"%*c %ld %ld %ld",
&tail, &head, &cap )
!= ARC_FIELDS
)
/* arc description is not correct */
{ err_no = EN15; goto error; }
--tail; // index from 0, not 1
--head;
if ( tail < 0 || tail > n ||
head < 0 || head > n
)
/* wrong value of nodes */
{ err_no = EN17; goto error; }
{
edge_descriptor e1, e2;
bool in1, in2;
tie(e1, in1) = add_edge(verts[tail], verts[head], g);
tie(e2, in2) = add_edge(verts[head], verts[tail], g);
if (!in1 || !in2) {
std::cerr << "unable to add edge (" << head << "," << tail << ")"
<< std::endl;
return -1;
}
capacity[e1] = cap;
capacity[e2] = 0;
reverse_edge[e1] = e2;
reverse_edge[e2] = e1;
}
++no_alines;
break;
default:
/* unknown type of line */
err_no = EN18; goto error;
} /* end of switch */
} /* end of input loop */
/* ----- all is red or error while reading ----- */
if ( feof (stdin) == 0 ) /* reading error */
{ err_no=EN21; goto error; }
if ( no_lines == 0 ) /* empty input */
{ err_no = EN22; goto error; }
if ( no_alines < m ) /* not enough arcs */
{ err_no = EN19; goto error; }
if ( out_degree(src, g) == 0 || out_degree(sink, g) == 0 )
/* no arc goes out of the source */
{ err_no = EN20; goto error; }
/* Thanks God! all is done */
return (0);
/* ---------------------------------- */
error: /* error found reading input */
printf ( "\nline %ld of input - %s\n",
no_lines, err_message[err_no] );
exit (1);
return (0); /* to avoid warning */
}
/* -------------------- end of parser -------------------*/
} // namespace boost

View File

@@ -1,99 +0,0 @@
//
//=======================================================================
// Copyright 1997, 1998, 1999, 2000 University of Notre Dame.
// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek
//
// This file is part of the Boost Graph Library
//
// You should have received a copy of the License Agreement for the
// Boost Graph Library along with the software; see the file LICENSE.
// If not, contact Office of Research, University of Notre Dame, Notre
// Dame, IN 46556.
//
// Permission to modify the code and to distribute modified code is
// granted, provided the text of this NOTICE is retained, a notice that
// the code was modified is included with the above COPYRIGHT NOTICE and
// with the COPYRIGHT NOTICE in the LICENSE file, and that the LICENSE
// file is distributed with the modified code.
//
// LICENSOR MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED.
// By way of example, but not limitation, Licensor MAKES NO
// REPRESENTATIONS OR WARRANTIES OF MERCHANTABILITY OR FITNESS FOR ANY
// PARTICULAR PURPOSE OR THAT THE USE OF THE LICENSED SOFTWARE COMPONENTS
// OR DOCUMENTATION WILL NOT INFRINGE ANY PATENTS, COPYRIGHTS, TRADEMARKS
// OR OTHER RIGHTS.
//=======================================================================
//
#ifndef BOOST_GRAPH_RELAX_HPP
#define BOOST_GRAPH_RELAX_HPP
#include <functional>
#include <boost/limits.hpp> // for numeric limits
#include <boost/graph/graph_traits.hpp>
#include <boost/property_map.hpp>
namespace boost {
// The following version of the plus functor prevents
// problems due to overflow at positive infinity.
template <class T>
struct closed_plus
{
// std::abs just isn't portable :(
template <class X>
inline X my_abs(const X& x) const { return x < 0 ? -x : x; }
T operator()(const T& a, const T& b) const {
using namespace std;
T inf = (numeric_limits<T>::max)();
if (b > 0 && my_abs(inf - a) < b)
return inf;
return a + b;
}
};
template <class Graph, class WeightMap,
class PredecessorMap, class DistanceMap,
class BinaryFunction, class BinaryPredicate>
bool relax(typename graph_traits<Graph>::edge_descriptor e,
const Graph& g, const WeightMap& w,
PredecessorMap& p, DistanceMap& d,
const BinaryFunction& combine, const BinaryPredicate& compare)
{
typedef typename graph_traits<Graph>::directed_category DirCat;
bool is_undirected = is_same<DirCat, undirected_tag>::value;
typedef typename graph_traits<Graph>::vertex_descriptor Vertex;
Vertex u = source(e, g), v = target(e, g);
typedef typename property_traits<DistanceMap>::value_type D;
typedef typename property_traits<WeightMap>::value_type W;
D d_u = get(d, u), d_v = get(d, v);
W w_e = get(w, e);
if ( compare(combine(d_u, w_e), d_v) ) {
put(d, v, combine(d_u, w_e));
put(p, v, u);
return true;
} else if (is_undirected && compare(combine(d_v, w_e), d_u)) {
put(d, u, combine(d_v, w_e));
put(p, u, v);
return true;
} else
return false;
}
template <class Graph, class WeightMap,
class PredecessorMap, class DistanceMap>
bool relax(typename graph_traits<Graph>::edge_descriptor e,
const Graph& g, WeightMap w, PredecessorMap p, DistanceMap d)
{
typedef typename property_traits<DistanceMap>::value_type D;
typedef closed_plus<D> Combine;
typedef std::less<D> Compare;
return relax(e, g, w, p, d, Combine(), Compare());
}
} // namespace boost
#endif /* BOOST_GRAPH_RELAX_HPP */

View File

@@ -1,273 +0,0 @@
// (C) Copyright David Abrahams 2000.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef REVERSE_GRAPH_DWA092300_H_
# define REVERSE_GRAPH_DWA092300_H_
#include <boost/graph/adjacency_iterator.hpp>
#include <boost/graph/properties.hpp>
#include <boost/tuple/tuple.hpp>
namespace boost {
struct reverse_graph_tag { };
namespace detail {
template <bool isEdgeList> struct choose_rev_edge_iter { };
template <> struct choose_rev_edge_iter<true> {
template <class G> struct bind_ {
typedef typename graph_traits<G>::edge_iterator type;
};
};
template <> struct choose_rev_edge_iter<false> {
template <class G> struct bind_ {
typedef void type;
};
};
} // namespace detail
template <class BidirectionalGraph, class GraphRef = const BidirectionalGraph&>
class reverse_graph {
typedef reverse_graph<BidirectionalGraph, GraphRef> Self;
typedef graph_traits<BidirectionalGraph> Traits;
public:
typedef BidirectionalGraph base_type;
// Constructor
reverse_graph(GraphRef g) : m_g(g) {}
// Graph requirements
typedef typename Traits::vertex_descriptor vertex_descriptor;
typedef typename Traits::edge_descriptor edge_descriptor;
typedef typename Traits::directed_category directed_category;
typedef typename Traits::edge_parallel_category edge_parallel_category;
typedef typename Traits::traversal_category traversal_category;
// IncidenceGraph requirements
typedef typename Traits::in_edge_iterator out_edge_iterator;
typedef typename Traits::degree_size_type degree_size_type;
// BidirectionalGraph requirements
typedef typename Traits::out_edge_iterator in_edge_iterator;
// AdjacencyGraph requirements
typedef typename adjacency_iterator_generator<Self,
vertex_descriptor, out_edge_iterator>::type adjacency_iterator;
// VertexListGraph requirements
typedef typename Traits::vertex_iterator vertex_iterator;
// EdgeListGraph requirements
enum { is_edge_list = is_convertible<traversal_category,
edge_list_graph_tag>::value };
typedef detail::choose_rev_edge_iter<is_edge_list> ChooseEdgeIter;
typedef typename ChooseEdgeIter::
template bind_<BidirectionalGraph>::type edge_iterator;
typedef typename Traits::vertices_size_type vertices_size_type;
typedef typename Traits::edges_size_type edges_size_type;
// More typedefs used by detail::edge_property_map, vertex_property_map
typedef typename BidirectionalGraph::edge_property_type
edge_property_type;
typedef typename BidirectionalGraph::vertex_property_type
vertex_property_type;
typedef reverse_graph_tag graph_tag;
static vertex_descriptor null_vertex()
{ return Traits::null_vertex(); }
// would be private, but template friends aren't portable enough.
// private:
GraphRef m_g;
};
template <class BidirectionalGraph>
inline reverse_graph<BidirectionalGraph>
make_reverse_graph(const BidirectionalGraph& g)
{
return reverse_graph<BidirectionalGraph>(g);
}
template <class BidirectionalGraph>
inline reverse_graph<BidirectionalGraph, BidirectionalGraph&>
make_reverse_graph(BidirectionalGraph& g)
{
return reverse_graph<BidirectionalGraph, BidirectionalGraph&>(g);
}
template <class BidirectionalGraph, class GRef>
std::pair<typename reverse_graph<BidirectionalGraph>::vertex_iterator,
typename reverse_graph<BidirectionalGraph>::vertex_iterator>
vertices(const reverse_graph<BidirectionalGraph,GRef>& g)
{
return vertices(g.m_g);
}
template <class BidirectionalGraph, class GRef>
std::pair<typename reverse_graph<BidirectionalGraph>::edge_iterator,
typename reverse_graph<BidirectionalGraph>::edge_iterator>
edges(const reverse_graph<BidirectionalGraph,GRef>& g)
{
return edges(g.m_g);
}
template <class BidirectionalGraph, class GRef>
inline std::pair<typename BidirectionalGraph::in_edge_iterator,
typename BidirectionalGraph::in_edge_iterator>
out_edges(const typename BidirectionalGraph::vertex_descriptor u,
const reverse_graph<BidirectionalGraph,GRef>& g)
{
return in_edges(u, g.m_g);
}
template <class BidirectionalGraph, class GRef>
inline typename BidirectionalGraph::vertices_size_type
num_vertices(const reverse_graph<BidirectionalGraph,GRef>& g)
{
return num_vertices(g.m_g);
}
template <class BidirectionalGraph, class GRef>
inline typename reverse_graph<BidirectionalGraph>::edges_size_type
num_edges(const reverse_graph<BidirectionalGraph,GRef>& g)
{
return num_edges(g.m_g);
}
template <class BidirectionalGraph, class GRef>
inline typename BidirectionalGraph::degree_size_type
out_degree(const typename BidirectionalGraph::vertex_descriptor u,
const reverse_graph<BidirectionalGraph,GRef>& g)
{
return in_degree(u, g.m_g);
}
template <class BidirectionalGraph, class GRef>
inline std::pair<typename BidirectionalGraph::edge_descriptor, bool>
edge(const typename BidirectionalGraph::vertex_descriptor u,
const typename BidirectionalGraph::vertex_descriptor v,
const reverse_graph<BidirectionalGraph,GRef>& g)
{
return edge(v, u, g);
}
template <class BidirectionalGraph, class GRef>
inline std::pair<typename BidirectionalGraph::out_edge_iterator,
typename BidirectionalGraph::out_edge_iterator>
in_edges(const typename BidirectionalGraph::vertex_descriptor u,
const reverse_graph<BidirectionalGraph,GRef>& g)
{
return out_edges(u, g.m_g);
}
template <class BidirectionalGraph, class GRef>
inline std::pair<typename reverse_graph<BidirectionalGraph,GRef>::adjacency_iterator,
typename reverse_graph<BidirectionalGraph,GRef>::adjacency_iterator>
adjacent_vertices(const typename BidirectionalGraph::vertex_descriptor u,
const reverse_graph<BidirectionalGraph,GRef>& g)
{
typedef reverse_graph<BidirectionalGraph,GRef> Graph;
typename Graph::out_edge_iterator first, last;
tie(first, last) = out_edges(u, g);
typedef typename Graph::adjacency_iterator adjacency_iterator;
return std::make_pair(adjacency_iterator(first, const_cast<Graph*>(&g)),
adjacency_iterator(last, const_cast<Graph*>(&g)));
}
template <class BidirectionalGraph, class GRef>
inline typename BidirectionalGraph::degree_size_type
in_degree(const typename BidirectionalGraph::vertex_descriptor u,
const reverse_graph<BidirectionalGraph,GRef>& g)
{
return out_degree(u, g.m_g);
}
template <class Edge, class BidirectionalGraph, class GRef>
inline typename graph_traits<BidirectionalGraph>::vertex_descriptor
source(const Edge& e, const reverse_graph<BidirectionalGraph,GRef>& g)
{
return target(e, g.m_g);
}
template <class Edge, class BidirectionalGraph, class GRef>
inline typename graph_traits<BidirectionalGraph>::vertex_descriptor
target(const Edge& e, const reverse_graph<BidirectionalGraph,GRef>& g)
{
return source(e, g.m_g);
}
namespace detail {
struct reverse_graph_vertex_property_selector {
template <class ReverseGraph, class Property, class Tag>
struct bind_ {
typedef typename ReverseGraph::base_type Graph;
typedef property_map<Graph, Tag> PMap;
typedef typename PMap::type type;
typedef typename PMap::const_type const_type;
};
};
struct reverse_graph_edge_property_selector {
template <class ReverseGraph, class Property, class Tag>
struct bind_ {
typedef typename ReverseGraph::base_type Graph;
typedef property_map<Graph, Tag> PMap;
typedef typename PMap::type type;
typedef typename PMap::const_type const_type;
};
};
} // namespace detail
template <>
struct vertex_property_selector<reverse_graph_tag> {
typedef detail::reverse_graph_vertex_property_selector type;
};
template <>
struct edge_property_selector<reverse_graph_tag> {
typedef detail::reverse_graph_edge_property_selector type;
};
template <class BidirGraph, class GRef, class Property>
typename property_map<BidirGraph, Property>::type
get(Property p, reverse_graph<BidirGraph,GRef>& g)
{
return get(p, g.m_g);
}
template <class BidirGraph, class GRef, class Property>
typename property_map<BidirGraph, Property>::const_type
get(Property p, const reverse_graph<BidirGraph,GRef>& g)
{
const BidirGraph& gref = g.m_g; // in case GRef is non-const
return get(p, gref);
}
template <class BidirectionalGraph, class GRef, class Property, class Key>
typename property_traits<
typename property_map<BidirectionalGraph, Property>::const_type
>::value_type
get(Property p, const reverse_graph<BidirectionalGraph,GRef>& g, const Key& k)
{
return get(p, g.m_g, k);
}
template <class BidirectionalGraph, class GRef, class Property, class Key, class Value>
void
put(Property p, const reverse_graph<BidirectionalGraph,GRef>& g, const Key& k,
const Value& val)
{
put(p, g.m_g, k, val);
}
} // namespace boost
#endif

View File

@@ -1,109 +0,0 @@
//=======================================================================
// Copyright 1997, 1998, 1999, 2000 University of Notre Dame.
// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek
//
// This file is part of the Boost Graph Library
//
// You should have received a copy of the License Agreement for the
// Boost Graph Library along with the software; see the file LICENSE.
// If not, contact Office of Research, University of Notre Dame, Notre
// Dame, IN 46556.
//
// Permission to modify the code and to distribute modified code is
// granted, provided the text of this NOTICE is retained, a notice that
// the code was modified is included with the above COPYRIGHT NOTICE and
// with the COPYRIGHT NOTICE in the LICENSE file, and that the LICENSE
// file is distributed with the modified code.
//
// LICENSOR MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED.
// By way of example, but not limitation, Licensor MAKES NO
// REPRESENTATIONS OR WARRANTIES OF MERCHANTABILITY OR FITNESS FOR ANY
// PARTICULAR PURPOSE OR THAT THE USE OF THE LICENSED SOFTWARE COMPONENTS
// OR DOCUMENTATION WILL NOT INFRINGE ANY PATENTS, COPYRIGHTS, TRADEMARKS
// OR OTHER RIGHTS.
//=======================================================================
#ifndef BOOST_GRAPH_SEQUENTIAL_VERTEX_COLORING_HPP
#define BOOST_GRAPH_SEQUENTIAL_VERTEX_COLORING_HPP
#include <vector>
#include <boost/graph/graph_traits.hpp>
/* This algorithm is to find coloring of a graph
Algorithm:
Let G = (V,E) be a graph with vertices (somehow) ordered v_1, v_2, ...,
v_n. For k = 1, 2, ..., n the sequential algorithm assigns v_k to the
smallest possible color.
Reference:
Thomas F. Coleman and Jorge J. More, Estimation of sparse Jacobian
matrices and graph coloring problems. J. Numer. Anal. V20, P187-209, 1983
v_k is stored as o[k] here.
The color of the vertex v will be stored in color[v].
i.e., vertex v belongs to coloring color[v] */
namespace boost {
template <class VertexListGraph, class OrderPA, class ColorMap>
typename graph_traits<VertexListGraph>::size_type
sequential_vertex_coloring(const VertexListGraph& G, OrderPA order,
ColorMap color)
{
using graph_traits;
using boost::tie;
typedef graph_traits<VertexListGraph> GraphTraits;
typedef typename GraphTraits::vertex_descriptor Vertex;
typedef typename GraphTraits::size_type size_type;
size_type max_color = 0;
const size_type V = num_vertices(G);
// We need to keep track of which colors are used by
// adjacent vertices. We do this by marking the colors
// that are used. The mark array contains the mark
// for each color. The length of mark is the
// number of vertices since the maximum possible number of colors
// is the number of vertices.
std::vector<size_type> mark(V, numeric_limits_max(max_color));
//Initialize colors
typename GraphTraits::vertex_iterator v, vend;
for (tie(v, vend) = vertices(G); v != vend; ++v)
put(color, *v, V-1);
//Determine the color for every vertex one by one
for ( size_type i = 0; i < V; i++) {
Vertex current = get(order,i);
typename GraphTraits::adjacency_iterator v, vend;
//Mark the colors of vertices adjacent to current.
//i can be the value for marking since i increases successively
for (tie(v,vend) = adjacent_vertices(current, G); v != vend; ++v)
mark[get(color,*v)] = i;
//Next step is to assign the smallest un-marked color
//to the current vertex.
size_type j = 0;
//Scan through all useable colors, find the smallest possible
//color which is not used by neighbors. Note that if mark[j]
//is equal to i, color j is used by one of the current vertex's
//neighbors.
while ( j < max_color && mark[j] == i )
++j;
if ( j == max_color ) //All colors are used up. Add one more color
++max_color;
//At this point, j is the smallest possible color
put(color, current, j); //Save the color of vertex current
}
return max_color;
}
}
#endif

View File

@@ -1,464 +0,0 @@
//
//=======================================================================
// Copyright 2002 Marc Wintermantel (wintermantel@imes.mavt.ethz.ch)
// ETH Zurich, Center of Structure Technologies (www.imes.ethz.ch/st)
//
// This file is part of the Boost Graph Library
//
// You should have received a copy of the License Agreement for the
// Boost Graph Library along with the software; see the file LICENSE.
// If not, contact Office of Research, University of Notre Dame, Notre
// Dame, IN 46556.
//
// Permission to modify the code and to distribute modified code is
// granted, provided the text of this NOTICE is retained, a notice that
// the code was modified is included with the above COPYRIGHT NOTICE and
// with the COPYRIGHT NOTICE in the LICENSE file, and that the LICENSE
// file is distributed with the modified code.
//
// LICENSOR MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED.
// By way of example, but not limitation, Licensor MAKES NO
// REPRESENTATIONS OR WARRANTIES OF MERCHANTABILITY OR FITNESS FOR ANY
// PARTICULAR PURPOSE OR THAT THE USE OF THE LICENSED SOFTWARE COMPONENTS
// OR DOCUMENTATION WILL NOT INFRINGE ANY PATENTS, COPYRIGHTS, TRADEMARKS
// OR OTHER RIGHTS.
//=======================================================================
//
#ifndef BOOST_GRAPH_SLOAN_HPP
#define BOOST_GRAPH_SLOAN_HPP
#define WEIGHT1 1 //default weight for the distance in the Sloan algorithm
#define WEIGHT2 2 //default weight for the degree in the Sloan algorithm
#define MAXINT 2147483647 //Maximum value for a 32bit integer
#include <boost/config.hpp>
#include <vector>
#include <queue>
#include <boost/pending/queue.hpp>
#include <boost/graph/graph_traits.hpp>
#include <boost/graph/breadth_first_search.hpp>
#include <boost/graph/properties.hpp>
#include <boost/pending/indirect_cmp.hpp>
#include <boost/property_map.hpp>
#include <algorithm>
#include <utility>
#include <boost/graph/visitors.hpp>
#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/cuthill_mckee_ordering.hpp>
////////////////////////////////////////////////////////////
//
//Sloan-Algorithm for graph reordering
//(optimzes profile and wavefront, not primiraly bandwidth
//
////////////////////////////////////////////////////////////
namespace boost {
/////////////////////////////////////////////////////////////////////////
// Function that returns the maximum depth of
// a rooted level strucutre (RLS)
//
/////////////////////////////////////////////////////////////////////////
template<class Distance>
unsigned RLS_depth(Distance& d)
{
unsigned h_s = 0;
typename Distance::iterator iter;
for (iter = d.begin(); iter != d.end(); ++iter)
{
if(*iter > h_s)
{
h_s = *iter;
}
}
return h_s;
}
/////////////////////////////////////////////////////////////////////////
// Function that returns the width of the largest level of
// a rooted level strucutre (RLS)
//
/////////////////////////////////////////////////////////////////////////
template<class Distance, class my_int>
unsigned RLS_max_width(Distance& d, my_int depth)
{
//Searching for the maximum width of a level
std::vector<unsigned> dummy_width(depth+1, 0);
std::vector<unsigned>::iterator my_it;
typename Distance::iterator iter;
unsigned w_max = 0;
for (iter = d.begin(); iter != d.end(); ++iter)
{
dummy_width[*iter]++;
}
for(my_it = dummy_width.begin(); my_it != dummy_width.end(); ++my_it)
{
if(*my_it > w_max) w_max = *my_it;
}
return w_max;
}
/////////////////////////////////////////////////////////////////////////
// Function for finding a good starting node for Sloan algorithm
//
// This is to find a good starting node. "good" is in the sense
// of the ordering generated.
/////////////////////////////////////////////////////////////////////////
template <class Graph, class ColorMap, class DegreeMap>
typename graph_traits<Graph>::vertex_descriptor
sloan_start_end_vertices(Graph& G,
typename graph_traits<Graph>::vertex_descriptor &s,
ColorMap color,
DegreeMap degree)
{
typedef typename property_traits<DegreeMap>::value_type DS;
typedef typename graph_traits<Graph>::vertex_descriptor Vertex;
typedef typename std::vector< typename graph_traits<Graph>::vertices_size_type>::iterator vec_iter;
typedef typename graph_traits<Graph>::vertices_size_type size_type;
typedef typename property_map<Graph, vertex_index_t>::const_type VertexID;
s = *(vertices(G).first);
Vertex e = s;
Vertex i;
unsigned my_degree = get(degree, s );
unsigned dummy, h_i, h_s, w_i, w_e;
bool new_start = true;
unsigned maximum_degree = 0;
//Creating a std-vector for storing the distance from the start vertex in dist
std::vector<typename graph_traits<Graph>::vertices_size_type> dist(num_vertices(G), 0);
//Wrap a property_map_iterator around the std::iterator
boost::iterator_property_map<vec_iter, VertexID, size_type, size_type&> dist_pmap(dist.begin(), get(vertex_index, G));
//Creating a property_map for the indices of a vertex
typename property_map<Graph, vertex_index_t>::type index_map = get(vertex_index, G);
//Creating a priority queue
typedef indirect_cmp<DegreeMap, std::greater<DS> > Compare;
Compare comp(degree);
std::priority_queue<Vertex, std::vector<Vertex>, Compare> degree_queue(comp);
//step 1
//Scan for the vertex with the smallest degree and the maximum degree
typename graph_traits<Graph>::vertex_iterator ui, ui_end;
for (tie(ui, ui_end) = vertices(G); ui != ui_end; ++ui)
{
dummy = get(degree, *ui);
if(dummy < my_degree)
{
my_degree = dummy;
s = *ui;
}
if(dummy > maximum_degree)
{
maximum_degree = dummy;
}
}
//end 1
do{
new_start = false; //Setting the loop repetition status to false
//step 2
//initialize the the disance std-vector with 0
for(typename std::vector<typename graph_traits<Graph>::vertices_size_type>::iterator iter = dist.begin(); iter != dist.end(); ++iter) *iter = 0;
//generating the RLS (rooted level structure)
breadth_first_search
(G, s, visitor
(
make_bfs_visitor(record_distances(dist_pmap, on_tree_edge() ) )
)
);
//end 2
//step 3
//calculating the depth of the RLS
h_s = RLS_depth(dist);
//step 4
//pushing one node of each degree in an ascending manner into degree_queue
std::vector<bool> shrink_trace(maximum_degree, false);
for (tie(ui, ui_end) = vertices(G); ui != ui_end; ++ui)
{
dummy = get(degree, *ui);
if( (dist[index_map[*ui]] == h_s ) && ( !shrink_trace[ dummy ] ) )
{
degree_queue.push(*ui);
shrink_trace[ dummy ] = true;
}
}
//end 3 & 4
//step 5
//Initializing w
w_e = MAXINT;
//end 5
//step 6
//Testing for termination
while( !degree_queue.empty() )
{
i = degree_queue.top(); //getting the node with the lowest degree from the degree queue
degree_queue.pop(); //ereasing the node with the lowest degree from the degree queue
//generating a RLS
for(typename std::vector<typename graph_traits<Graph>::vertices_size_type>::iterator iter = dist.begin(); iter != dist.end(); ++iter) *iter = 0;
breadth_first_search
(G, i, boost::visitor
(
make_bfs_visitor(record_distances(dist_pmap, on_tree_edge() ) )
)
);
//Calculating depth and width of the rooted level
h_i = RLS_depth(dist);
w_i = RLS_max_width(dist, h_i);
//Testing for termination
if( (h_i > h_s) && (w_i < w_e) )
{
h_s = h_i;
s = i;
while(!degree_queue.empty()) degree_queue.pop();
new_start = true;
}
else if(w_i < w_e)
{
w_e = w_i;
e = i;
}
}
//end 6
}while(new_start);
return e;
}
//////////////////////////////////////////////////////////////////////////
// Sloan algorithm with a given starting Vertex.
//
// This algorithm requires user to provide a starting vertex to
// compute Sloan ordering.
//////////////////////////////////////////////////////////////////////////
template <class Graph, class OutputIterator,
class ColorMap, class DegreeMap,
class PriorityMap, class Weight>
OutputIterator
sloan_ordering(Graph& g,
typename graph_traits<Graph>::vertex_descriptor s,
typename graph_traits<Graph>::vertex_descriptor e,
OutputIterator permutation,
ColorMap color,
DegreeMap degree,
PriorityMap priority,
Weight W1,
Weight W2)
{
//typedef typename property_traits<DegreeMap>::value_type DS;
typedef typename property_traits<PriorityMap>::value_type DS;
typedef typename property_traits<ColorMap>::value_type ColorValue;
typedef color_traits<ColorValue> Color;
typedef typename graph_traits<Graph>::vertex_descriptor Vertex;
typedef typename std::vector<typename graph_traits<Graph>::vertices_size_type>::iterator vec_iter;
typedef typename graph_traits<Graph>::vertices_size_type size_type;
typedef typename property_map<Graph, vertex_index_t>::const_type VertexID;
//Creating a std-vector for storing the distance from the end vertex in it
typename std::vector<typename graph_traits<Graph>::vertices_size_type> dist(num_vertices(g), 0);
//Wrap a property_map_iterator around the std::iterator
boost::iterator_property_map<vec_iter, VertexID, size_type, size_type&> dist_pmap(dist.begin(), get(vertex_index, g));
breadth_first_search
(g, e, visitor
(
make_bfs_visitor(record_distances(dist_pmap, on_tree_edge() ) )
)
);
//Creating a property_map for the indices of a vertex
typename property_map<Graph, vertex_index_t>::type index_map = get(vertex_index, g);
//Sets the color and priority to their initial status
unsigned cdeg;
typename graph_traits<Graph>::vertex_iterator ui, ui_end;
for (tie(ui, ui_end) = vertices(g); ui != ui_end; ++ui)
{
put(color, *ui, Color::white());
cdeg=get(degree, *ui)+1;
put(priority, *ui, W1*dist[index_map[*ui]]-W2*cdeg );
}
//Priority list
typedef indirect_cmp<PriorityMap, std::greater<DS> > Compare;
Compare comp(priority);
std::list<Vertex> priority_list;
//Some more declarations
typename graph_traits<Graph>::out_edge_iterator ei, ei_end, ei2, ei2_end;
Vertex u, v, w;
put(color, s, Color::green()); //Sets the color of the starting vertex to gray
priority_list.push_front(s); //Puts s into the priority_list
while ( !priority_list.empty() )
{
priority_list.sort(comp); //Orders the elements in the priority list in an ascending manner
u = priority_list.front(); //Accesses the last element in the priority list
priority_list.pop_front(); //Removes the last element in the priority list
if(get(color, u) == Color::green() )
{
//for-loop over all out-edges of vertex u
for (tie(ei, ei_end) = out_edges(u, g); ei != ei_end; ++ei)
{
v = target(*ei, g);
put( priority, v, get(priority, v) + W2 ); //updates the priority
if (get(color, v) == Color::white() ) //test if the vertex is inactive
{
put(color, v, Color::green() ); //giving the vertex a preactive status
priority_list.push_front(v); //writing the vertex in the priority_queue
}
}
}
//Here starts step 8
*permutation++ = u; //Puts u to the first position in the permutation-vector
put(color, u, Color::black() ); //Gives u an inactive status
//for loop over all the adjacent vertices of u
for (tie(ei, ei_end) = out_edges(u, g); ei != ei_end; ++ei) {
v = target(*ei, g);
if (get(color, v) == Color::green() ) { //tests if the vertex is inactive
put(color, v, Color::red() ); //giving the vertex an active status
put(priority, v, get(priority, v)+W2); //updates the priority
//for loop over alll adjacent vertices of v
for (tie(ei2, ei2_end) = out_edges(v, g); ei2 != ei2_end; ++ei2) {
w = target(*ei2, g);
if(get(color, w) != Color::black() ) { //tests if vertex is postactive
put(priority, w, get(priority, w)+W2); //updates the priority
if(get(color, w) == Color::white() ){
put(color, w, Color::green() ); // gives the vertex a preactive status
priority_list.push_front(w); // puts the vertex into the priority queue
} //end if
} //end if
} //end for
} //end if
} //end for
} //end while
return permutation;
}
/////////////////////////////////////////////////////////////////////////////////////////
// Same algorithm as before, but without the weights given (taking default weights
template <class Graph, class OutputIterator,
class ColorMap, class DegreeMap,
class PriorityMap>
OutputIterator
sloan_ordering(Graph& g,
typename graph_traits<Graph>::vertex_descriptor s,
typename graph_traits<Graph>::vertex_descriptor e,
OutputIterator permutation,
ColorMap color,
DegreeMap degree,
PriorityMap priority)
{
return sloan_ordering(g, s, e, permutation, color, degree, priority, WEIGHT1, WEIGHT2);
}
//////////////////////////////////////////////////////////////////////////
// Sloan algorithm without a given starting Vertex.
//
// This algorithm finds a good starting vertex itself to
// compute Sloan-ordering.
//////////////////////////////////////////////////////////////////////////
template < class Graph, class OutputIterator,
class Color, class Degree,
class Priority, class Weight>
inline OutputIterator
sloan_ordering(Graph& G,
OutputIterator permutation,
Color color,
Degree degree,
Priority priority,
Weight W1,
Weight W2 )
{
typedef typename boost::graph_traits<Graph>::vertex_descriptor Vertex;
Vertex s, e;
e = sloan_start_end_vertices(G, s, color, degree);
return sloan_ordering(G, s, e, permutation, color, degree, priority, W1, W2);
}
/////////////////////////////////////////////////////////////////////////////////////////
// Same as before, but without given weights (default weights are taken instead)
template < class Graph, class OutputIterator,
class Color, class Degree,
class Priority >
inline OutputIterator
sloan_ordering(Graph& G,
OutputIterator permutation,
Color color,
Degree degree,
Priority priority)
{
return sloan_ordering(G, permutation, color, degree, priority, WEIGHT1, WEIGHT2);
}
} // namespace boost
#endif // BOOST_GRAPH_SLOAN_HPP

View File

@@ -1,127 +0,0 @@
//=======================================================================
// Copyright 1997, 1998, 1999, 2000 University of Notre Dame.
// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek
//
// This file is part of the Boost Graph Library
//
// You should have received a copy of the License Agreement for the
// Boost Graph Library along with the software; see the file LICENSE.
// If not, contact Office of Research, University of Notre Dame, Notre
// Dame, IN 46556.
//
// Permission to modify the code and to distribute modified code is
// granted, provided the text of this NOTICE is retained, a notice that
// the code was modified is included with the above COPYRIGHT NOTICE and
// with the COPYRIGHT NOTICE in the LICENSE file, and that the LICENSE
// file is distributed with the modified code.
//
// LICENSOR MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED.
// By way of example, but not limitation, Licensor MAKES NO
// REPRESENTATIONS OR WARRANTIES OF MERCHANTABILITY OR FITNESS FOR ANY
// PARTICULAR PURPOSE OR THAT THE USE OF THE LICENSED SOFTWARE COMPONENTS
// OR DOCUMENTATION WILL NOT INFRINGE ANY PATENTS, COPYRIGHTS, TRADEMARKS
// OR OTHER RIGHTS.
//=======================================================================
#ifndef BOOST_SMALLEST_LAST_VERTEX_ORDERING_HPP
#define BOOST_SMALLEST_LAST_VERTEX_ORDERING_HPP
/*
The smallest-last ordering is defined for the loopless graph G with
vertices a(j), j = 1,2,...,n where a(j) is the j-th column of A and
with edge (a(i),a(j)) if and only if columns i and j have a
non-zero in the same row position. The smallest-last ordering is
determined recursively by letting list(k), k = n,...,1 be a column
with least degree in the subgraph spanned by the un-ordered
columns.
*/
#include <vector>
#include <algorithm>
#include <boost/config.hpp>
#include <boost/graph/graph_traits.hpp>
#include <boost/pending/bucket_sorter.hpp>
namespace boost {
template <class VertexListGraph, class Order, class Degree, class Marker>
void
smallest_last_vertex_ordering(const VertexListGraph& G, Order order,
Degree degree, Marker marker) {
typedef typename graph_traits<VertexListGraph> GraphTraits;
typedef typename GraphTraits::vertex_descriptor Vertex;
//typedef typename GraphTraits::size_type size_type;
typedef std::size_t size_type;
const size_type num = num_vertices(G);
typedef typename vertex_property_map<VertexListGraph, vertex_index_t>::type ID;
typedef bucket_sorter<size_type, Vertex, Degree, ID> BucketSorter;
BucketSorter degree_bucket_sorter(num, num, degree,
get_vertex_property(G, vertex_index));
smallest_last_vertex_ordering(G, order, degree, marker, degree_bucket_sorter);
}
template <class VertexListGraph, class Order, class Degree,
class Marker, class BucketSorter>
void
smallest_last_vertex_ordering(const VertexListGraph& G, Order order,
Degree degree, Marker marker,
BucketSorter& degree_buckets) {
typedef typename graph_traits<VertexListGraph> GraphTraits;
typedef typename GraphTraits::vertex_descriptor Vertex;
//typedef typename GraphTraits::size_type size_type;
typedef std::size_t size_type;
const size_type num = num_vertices(G);
typename GraphTraits::vertex_iterator v, vend;
for (boost::tie(v, vend) = vertices(G); v != vend; ++v) {
put(marker, *v, num);
put(degree, *v, out_degree(*v, G));
degree_buckets.push(*v);
}
size_type minimum_degree = 1;
size_type current_order = num - 1;
while ( 1 ) {
typedef typename BucketSorter::stack MDStack;
MDStack minimum_degree_stack = degree_buckets[minimum_degree];
while (minimum_degree_stack.empty())
minimum_degree_stack = degree_buckets[++minimum_degree];
Vertex node = minimum_degree_stack.top();
put(order, current_order, node);
if ( current_order == 0 ) //find all vertices
break;
minimum_degree_stack.pop();
put(marker, node, 0); //node has been ordered.
typename GraphTraits::adjacency_iterator v, vend;
for (boost::tie(v,vend) = adjacent_vertices(node, G); v != vend; ++v)
if ( get(marker,*v) > current_order ) { //*v is unordered vertex
put(marker, *v, current_order); //mark the columns adjacent to node
//It is possible minimum degree goes down
//Here we keep tracking it.
put(degree, *v, get(degree, *v) - 1);
BOOST_USING_STD_MIN();
minimum_degree = min BOOST_PREVENT_MACRO_SUBSTITUTION(minimum_degree, get(degree, *v));
//update the position of *v in the bucket sorter
degree_buckets.update(*v);
}
current_order--;
}
//at this point, order[i] = v_i;
}
}
#endif

View File

@@ -1,581 +0,0 @@
//=======================================================================
// Copyright 1997-2001 University of Notre Dame.
// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek
//
// This file is part of the Boost Graph Library
//
// You should have received a copy of the License Agreement for the
// Boost Graph Library along with the software; see the file LICENSE.
// If not, contact Office of Research, University of Notre Dame, Notre
// Dame, IN 46556.
//
// Permission to modify the code and to distribute modified code is
// granted, provided the text of this NOTICE is retained, a notice that
// the code was modified is included with the above COPYRIGHT NOTICE and
// with the COPYRIGHT NOTICE in the LICENSE file, and that the LICENSE
// file is distributed with the modified code.
//
// LICENSOR MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED.
// By way of example, but not limitation, Licensor MAKES NO
// REPRESENTATIONS OR WARRANTIES OF MERCHANTABILITY OR FITNESS FOR ANY
// PARTICULAR PURPOSE OR THAT THE USE OF THE LICENSED SOFTWARE COMPONENTS
// OR DOCUMENTATION WILL NOT INFRINGE ANY PATENTS, COPYRIGHTS, TRADEMARKS
// OR OTHER RIGHTS.
//=======================================================================
#ifndef BOOST_GRAPH_SGB_GRAPH_HPP
#define BOOST_GRAPH_SGB_GRAPH_HPP
#include <boost/config.hpp>
#include <boost/iterator.hpp>
#include <boost/operators.hpp>
#include <boost/property_map.hpp>
#include <boost/graph/graph_traits.hpp>
#include <boost/graph/properties.hpp>
// Thanks to Andreas Scherer for numerous suggestions and fixes!
// This file adapts a Stanford GraphBase (SGB) Graph pointer into a
// VertexListGraph. Note that a graph adaptor class is not needed,
// SGB's Graph* is used as is. The VertexListGraph concept is fulfilled by
// defining the appropriate non-member functions for Graph*.
//
// The PROTOTYPES change file extensions to SGB must be applied so
// that the SGB functions have real prototypes which are necessary for
// the C++ compiler. To apply the PROTOTYPES extensions, before you do
// "make tests install" for SGB do "ln -s PROTOTYPES/* ." to the SGB
// root directory (or just copy all the files from the PROTOTYPES
// directory to the SGB root directory).
//
extern "C" {
// We include all global definitions for the general stuff
// of The Stanford GraphBase and its various graph generator
// functions by reading all SGB headerfiles as in section 2 of
// the "test_sample" program.
#include <gb_graph.h> /* SGB data structures */
#include <gb_io.h> /* SGB input/output routines */
#include <gb_flip.h> /* random number generator */
#include <gb_dijk.h> /* routines for shortest paths */
#include <gb_basic.h> /* the basic graph operations */
#undef empty /* avoid name clash with C++ standard library */
inline Graph* empty( long n ) /* and provide workaround */
{ return board(n,0L,0L,0L,2L,0L,0L); }
#include <gb_books.h> /* graphs based on literature */
#include <gb_econ.h> /* graphs based on economic data */
#include <gb_games.h> /* graphs based on football scores */
#include <gb_gates.h> /* graphs based on logic circuits */
#undef val /* avoid name clash with g++ headerfile stl_tempbuf.h */
// val ==> Vertex::x.I
#include <gb_lisa.h> /* graphs based on Mona Lisa */
#include <gb_miles.h> /* graphs based on mileage data */
#include <gb_plane.h> /* planar graphs */
#include <gb_raman.h> /* Ramanujan graphs */
#include <gb_rand.h> /* random graphs */
#include <gb_roget.h> /* graphs based on Roget's Thesaurus */
#include <gb_save.h> /* we save results in ASCII format */
#include <gb_words.h> /* five-letter-word graphs */
#undef weight /* avoid name clash with BGL parameter */
// weight ==> Vertex::u.I
}
namespace boost {
class sgb_edge;
}
class sgb_out_edge_iterator;
class sgb_adj_iterator;
class sgb_vertex_iterator;
namespace boost {
typedef Graph* sgb_graph_ptr;
typedef const Graph* sgb_const_graph_ptr;
struct sgb_traversal_tag :
public virtual vertex_list_graph_tag,
public virtual incidence_graph_tag,
public virtual adjacency_graph_tag { };
template <> struct graph_traits<sgb_graph_ptr> {
typedef Vertex* vertex_descriptor;
typedef boost::sgb_edge edge_descriptor;
typedef sgb_out_edge_iterator out_edge_iterator;
typedef void in_edge_iterator;
typedef sgb_adj_iterator adjacency_iterator;
typedef sgb_vertex_iterator vertex_iterator;
typedef void edge_iterator;
typedef long vertices_size_type;
typedef long edge_size_type;
typedef long degree_size_type;
typedef directed_tag directed_category;
typedef sgb_traversal_tag traversal_category;
typedef allow_parallel_edge_tag edge_parallel_category;
};
template <> struct graph_traits<sgb_const_graph_ptr> {
typedef Vertex* vertex_descriptor;
typedef boost::sgb_edge edge_descriptor;
typedef sgb_out_edge_iterator out_edge_iterator;
typedef void in_edge_iterator;
typedef sgb_adj_iterator adjacency_iterator;
typedef sgb_vertex_iterator vertex_iterator;
typedef void edge_iterator;
typedef long vertices_size_type;
typedef long edge_size_type;
typedef long degree_size_type;
typedef directed_tag directed_category;
typedef sgb_traversal_tag traversal_category;
typedef allow_parallel_edge_tag edge_parallel_category;
};
}
namespace boost {
struct edge_length_t {
typedef edge_property_tag kind;
};
// We could just use Arc* as the edge descriptor type, but
// we want to add the source(e,g) function which requires
// that we carry along a pointer to the source vertex.
class sgb_edge {
typedef sgb_edge self;
public:
sgb_edge() : _arc(0), _src(0) { }
sgb_edge(Arc* a, Vertex* s) : _arc(a), _src(s) { }
friend Vertex* source(self e, sgb_const_graph_ptr) { return e._src; }
friend Vertex* target(self e, sgb_const_graph_ptr) { return e._arc->tip; }
friend bool operator==(const self& a, const self& b) {
return a._arc == b._arc; }
friend bool operator!=(const self& a, const self& b) {
return a._arc != b._arc; }
#if !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS)
template <class Ref> friend class sgb_edge_length_map;
template <class Tag, class Ref> friend class sgb_edge_util_map;
friend long get(edge_length_t, const sgb_graph_ptr&, const sgb_edge& key);
friend long get(edge_length_t, const sgb_const_graph_ptr&, const sgb_edge& key);
friend void put(edge_length_t, sgb_graph_ptr&, const sgb_edge& key, long value);
protected:
#endif
Arc* _arc;
Vertex* _src;
};
} // namespace boost
class sgb_out_edge_iterator
: public boost::forward_iterator_helper<
sgb_out_edge_iterator, boost::sgb_edge,
std::ptrdiff_t, boost::sgb_edge*, boost::sgb_edge>
{
typedef sgb_out_edge_iterator self;
public:
sgb_out_edge_iterator() : _src(0), _arc(0) {}
sgb_out_edge_iterator(Vertex* s, Arc* d) : _src(s), _arc(d) {}
boost::sgb_edge operator*() { return boost::sgb_edge(_arc, _src); }
self& operator++() { _arc = _arc->next; return *this; }
friend bool operator==(const self& x, const self& y) {
return x._arc == y._arc; }
protected:
Vertex* _src;
Arc* _arc;
};
class sgb_adj_iterator
: public boost::forward_iterator_helper<
sgb_adj_iterator, Vertex*, std::ptrdiff_t, Vertex**,Vertex*>
{
typedef sgb_adj_iterator self;
public:
sgb_adj_iterator() : _arc(0) {}
sgb_adj_iterator(Arc* d) : _arc(d) {}
Vertex* operator*() { return _arc->tip; }
self& operator++() { _arc = _arc->next; return *this; }
friend bool operator==(const self& x, const self& y) {
return x._arc == y._arc; }
protected:
Arc* _arc;
};
// The reason we have this instead of just using Vertex* is that we
// want to use Vertex* as the vertex_descriptor instead of just
// Vertex, which avoids problems with boost passing vertex descriptors
// by value and how that interacts with the sgb_vertex_id_map.
class sgb_vertex_iterator
: public boost::forward_iterator_helper<
sgb_vertex_iterator, Vertex*, std::ptrdiff_t, Vertex**, Vertex*>
{
typedef sgb_vertex_iterator self;
public:
sgb_vertex_iterator() : _v(0) { }
sgb_vertex_iterator(Vertex* v) : _v(v) { }
Vertex* operator*() { return _v; }
self& operator++() { ++_v; return *this; }
friend bool operator==(const self& x, const self& y) {
return x._v == y._v; }
protected:
Vertex* _v;
};
namespace boost {
inline std::pair<sgb_vertex_iterator,sgb_vertex_iterator>
vertices(sgb_const_graph_ptr g)
{
return std::make_pair(sgb_vertex_iterator(g->vertices),
sgb_vertex_iterator(g->vertices + g->n));
}
inline std::pair<sgb_out_edge_iterator,sgb_out_edge_iterator>
out_edges(Vertex* u, sgb_const_graph_ptr)
{
return std::make_pair( sgb_out_edge_iterator(u, u->arcs),
sgb_out_edge_iterator(u, 0) );
}
inline boost::graph_traits<sgb_graph_ptr>::degree_size_type
out_degree(Vertex* u, sgb_const_graph_ptr g)
{
boost::graph_traits<sgb_graph_ptr>::out_edge_iterator i, i_end;
boost::tie(i, i_end) = out_edges(u, g);
return std::distance(i, i_end);
}
// in_edges?
inline std::pair<sgb_adj_iterator,sgb_adj_iterator>
adjacent_vertices(Vertex* u, sgb_const_graph_ptr)
{
return std::make_pair( sgb_adj_iterator(u->arcs),
sgb_adj_iterator(0) );
}
inline long num_vertices(sgb_const_graph_ptr g) { return g->n; }
inline long num_edges(sgb_const_graph_ptr g) { return g->m; }
inline Vertex* vertex(long v, sgb_const_graph_ptr g)
{ return g->vertices + v; }
// Various Property Maps
// Vertex ID
class sgb_vertex_id_map
: public boost::put_get_helper<long, sgb_vertex_id_map>
{
public:
typedef boost::readable_property_map_tag category;
typedef long value_type;
typedef long reference;
typedef Vertex* key_type;
sgb_vertex_id_map() : _g(0) { }
sgb_vertex_id_map(sgb_graph_ptr g) : _g(g) { }
long operator[](Vertex* v) const { return v - _g->vertices; }
protected:
sgb_graph_ptr _g;
};
inline sgb_vertex_id_map get(vertex_index_t, sgb_graph_ptr g) {
return sgb_vertex_id_map(g);
}
// Vertex Name
class sgb_vertex_name_map
: public boost::put_get_helper<char*, sgb_vertex_name_map>
{
public:
typedef boost::readable_property_map_tag category;
typedef char* value_type;
typedef char* reference;
typedef Vertex* key_type;
char* operator[](Vertex* v) const { return v->name; }
};
inline sgb_vertex_name_map get(vertex_name_t, sgb_graph_ptr) {
return sgb_vertex_name_map();
}
// Vertex Property Tags
#define SGB_PROPERTY_TAG(KIND,TAG) \
template <class T> struct TAG##_property { \
typedef KIND##_property_tag kind; \
typedef T type; \
};
SGB_PROPERTY_TAG(vertex, u)
SGB_PROPERTY_TAG(vertex, v)
SGB_PROPERTY_TAG(vertex, w)
SGB_PROPERTY_TAG(vertex, x)
SGB_PROPERTY_TAG(vertex, y)
SGB_PROPERTY_TAG(vertex, z)
// Edge Property Tags
SGB_PROPERTY_TAG(edge, a)
SGB_PROPERTY_TAG(edge, b)
// Various Utility Maps
// helpers
inline Vertex*& get_util(util& u, Vertex*) { return u.V; }
inline Arc*& get_util(util& u, Arc*) { return u.A; }
inline sgb_graph_ptr& get_util(util& u, sgb_graph_ptr) { return u.G; }
inline char*& get_util(util& u, char*) { return u.S; }
inline long& get_util(util& u, long) { return u.I; }
#define SGB_GET_UTIL_FIELD(KIND,X) \
template <class T> \
inline T& get_util_field(KIND* k, X##_property<T>) { \
return get_util(k->X, T()); }
SGB_GET_UTIL_FIELD(Vertex, u)
SGB_GET_UTIL_FIELD(Vertex, v)
SGB_GET_UTIL_FIELD(Vertex, w)
SGB_GET_UTIL_FIELD(Vertex, x)
SGB_GET_UTIL_FIELD(Vertex, y)
SGB_GET_UTIL_FIELD(Vertex, z)
SGB_GET_UTIL_FIELD(Arc, a)
SGB_GET_UTIL_FIELD(Arc, b)
// Vertex Utility Map
template <class Tag, class Ref>
class sgb_vertex_util_map
: public boost::put_get_helper<Ref, sgb_vertex_util_map<Tag, Ref> >
{
public:
typedef boost::lvalue_property_map_tag category;
typedef typename Tag::type value_type;
typedef Vertex* key_type;
typedef Ref reference;
reference operator[](Vertex* v) const {
return get_util_field(v, Tag());
}
};
// Edge Utility Map
template <class Tag, class Ref>
class sgb_edge_util_map
: public boost::put_get_helper<Ref, sgb_edge_util_map<Tag, Ref> >
{
public:
typedef boost::lvalue_property_map_tag category;
typedef typename Tag::type value_type;
typedef Vertex* key_type;
typedef Ref reference;
reference operator[](const sgb_edge& e) const {
return get_util_field(e._arc, Tag());
}
};
#if !defined BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
template <class Tag>
inline sgb_vertex_util_map<Tag, const typename Tag::type&>
get_property_map(Tag, const sgb_graph_ptr& g, vertex_property_tag) {
return sgb_vertex_util_map<Tag, const typename Tag::type&>();
}
template <class Tag>
inline sgb_vertex_util_map<Tag, typename Tag::type&>
get_property_map(Tag, sgb_graph_ptr& g, vertex_property_tag) {
return sgb_vertex_util_map<Tag, typename Tag::type&>();
}
template <class Tag>
inline sgb_edge_util_map<Tag, const typename Tag::type&>
get_property_map(Tag, const sgb_graph_ptr& g, edge_property_tag) {
return sgb_edge_util_map<Tag, const typename Tag::type&>();
}
template <class Tag>
inline sgb_edge_util_map<Tag, typename Tag::type&>
get_property_map(Tag, sgb_graph_ptr& g, edge_property_tag) {
return sgb_edge_util_map<Tag, typename Tag::type&>();
}
#endif // ! BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
// Edge Length Access
template <class Ref>
class sgb_edge_length_map
: public boost::put_get_helper<Ref, sgb_edge_length_map<Ref> >
{
public:
typedef boost::lvalue_property_map_tag category;
typedef long value_type;
typedef sgb_edge key_type;
typedef Ref reference;
reference operator[](const sgb_edge& e) const {
return e._arc->len;
}
};
inline sgb_edge_length_map<const long&>
get(edge_length_t, const sgb_graph_ptr&) {
return sgb_edge_length_map<const long&>();
}
inline sgb_edge_length_map<const long&>
get(edge_length_t, const sgb_const_graph_ptr&) {
return sgb_edge_length_map<const long&>();
}
inline sgb_edge_length_map<long&>
get(edge_length_t, sgb_graph_ptr&) {
return sgb_edge_length_map<long&>();
}
inline long
get(edge_length_t, const sgb_graph_ptr&, const sgb_edge& key) {
return key._arc->len;
}
inline long
get(edge_length_t, const sgb_const_graph_ptr&, const sgb_edge& key) {
return key._arc->len;
}
inline void
put(edge_length_t, sgb_graph_ptr&, const sgb_edge& key, long value)
{
key._arc->len = value;
}
// Property Map Traits Classes
template <>
struct property_map<sgb_graph_ptr, edge_length_t> {
typedef sgb_edge_length_map<long&> type;
typedef sgb_edge_length_map<const long&> const_type;
};
template <>
struct property_map<sgb_graph_ptr, vertex_index_t> {
typedef sgb_vertex_id_map type;
typedef sgb_vertex_id_map const_type;
};
template <>
struct property_map<sgb_graph_ptr, vertex_name_t> {
typedef sgb_vertex_name_map type;
typedef sgb_vertex_name_map const_type;
};
template <>
struct property_map<sgb_const_graph_ptr, edge_length_t> {
typedef sgb_edge_length_map<const long&> const_type;
};
template <>
struct property_map<sgb_const_graph_ptr, vertex_index_t> {
typedef sgb_vertex_id_map const_type;
};
template <>
struct property_map<sgb_const_graph_ptr, vertex_name_t> {
typedef sgb_vertex_name_map const_type;
};
#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
namespace detail {
template <class Kind, class PropertyTag>
struct sgb_choose_property_map { };
template <class PropertyTag>
struct sgb_choose_property_map<vertex_property_tag, PropertyTag> {
typedef typename PropertyTag::type value_type;
typedef sgb_vertex_util_map<PropertyTag, value_type&> type;
typedef sgb_vertex_util_map<PropertyTag, const value_type&> const_type;
};
template <class PropertyTag>
struct sgb_choose_property_map<edge_property_tag, PropertyTag> {
typedef typename PropertyTag::type value_type;
typedef sgb_edge_util_map<PropertyTag, value_type&> type;
typedef sgb_edge_util_map<PropertyTag, const value_type&> const_type;
};
} // namespace detail
template <class PropertyTag>
struct property_map<sgb_graph_ptr, PropertyTag> {
typedef typename property_kind<PropertyTag>::type Kind;
typedef detail::sgb_choose_property_map<Kind, PropertyTag> Choice;
typedef typename Choice::type type;
typedef typename Choice::const_type const_type;
};
template <class PropertyTag>
struct property_map<sgb_const_graph_ptr, PropertyTag> {
typedef typename property_kind<PropertyTag>::type Kind;
typedef detail::sgb_choose_property_map<Kind, PropertyTag> Choice;
typedef typename Choice::const_type const_type;
};
#define SGB_UTIL_ACCESSOR(KIND,X) \
template <class T> \
inline sgb_##KIND##_util_map< X##_property<T>, T&> \
get(X##_property<T>, sgb_graph_ptr&) { \
return sgb_##KIND##_util_map< X##_property<T>, T&>(); \
} \
template <class T> \
inline sgb_##KIND##_util_map< X##_property<T>, const T&> \
get(X##_property<T>, const sgb_graph_ptr&) { \
return sgb_##KIND##_util_map< X##_property<T>, const T&>(); \
} \
template <class T> \
inline sgb_##KIND##_util_map< X##_property<T>, const T&> \
get(X##_property<T>, const sgb_const_graph_ptr&) { \
return sgb_##KIND##_util_map< X##_property<T>, const T&>(); \
} \
template <class T, class Key> \
inline typename \
sgb_##KIND##_util_map< X##_property<T>, const T&>::value_type \
get(X##_property<T>, const sgb_graph_ptr&, const Key& key) { \
return sgb_##KIND##_util_map< X##_property<T>, const T&>()[key]; \
} \
template <class T, class Key> \
inline typename \
sgb_##KIND##_util_map< X##_property<T>, const T&>::value_type \
get(X##_property<T>, const sgb_const_graph_ptr&, const Key& key) { \
return sgb_##KIND##_util_map< X##_property<T>, const T&>()[key]; \
} \
template <class T, class Key, class Value> \
inline void \
put(X##_property<T>, sgb_graph_ptr&, const Key& key, const Value& value) { \
sgb_##KIND##_util_map< X##_property<T>, T&>()[key] = value; \
}
#else // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
#define SGB_UTIL_ACCESSOR_TYPE(KIND,TAG,TYPE) \
inline sgb_##KIND##_util_map< TAG<TYPE>, TYPE& > \
get(TAG<TYPE>, sgb_graph_ptr&) { \
return sgb_##KIND##_util_map< TAG<TYPE>, TYPE& >(); \
} \
inline sgb_##KIND##_util_map< TAG<TYPE>, const TYPE& > \
get(TAG<TYPE>, const sgb_graph_ptr&) { \
return sgb_##KIND##_util_map< TAG<TYPE>, const TYPE& >(); \
} \
inline sgb_##KIND##_util_map< TAG<TYPE>, const TYPE& > \
get(TAG<TYPE>, const sgb_const_graph_ptr&) { \
return sgb_##KIND##_util_map< TAG<TYPE>, const TYPE& >(); \
} \
template <class Key> \
inline typename sgb_##KIND##_util_map< TAG<TYPE>, const TYPE& >::value_type \
get(TAG<TYPE>, const sgb_graph_ptr&, const Key& key) { \
return sgb_##KIND##_util_map< TAG<TYPE>, const TYPE& >()[key]; \
} \
template <class Key> \
inline typename sgb_##KIND##_util_map< TAG<TYPE>, const TYPE& >::value_type \
get(TAG<TYPE>, const sgb_const_graph_ptr&, const Key& key) { \
return sgb_##KIND##_util_map< TAG<TYPE>, const TYPE& >()[key]; \
} \
template <class Key, class Value> \
inline void \
put(TAG<TYPE>, sgb_graph_ptr&, const Key& key, const Value& value) { \
sgb_##KIND##_util_map< TAG<TYPE>, TYPE& >()[key] = value; \
} \
template <> struct property_map<sgb_graph_ptr, TAG<TYPE> > { \
typedef sgb_##KIND##_util_map< TAG<TYPE>, TYPE&> type; \
typedef sgb_##KIND##_util_map< TAG<TYPE>, const TYPE&> const_type; \
}
#define SGB_UTIL_ACCESSOR(KIND,TAG) \
SGB_UTIL_ACCESSOR_TYPE(KIND, TAG##_property, Vertex*); \
SGB_UTIL_ACCESSOR_TYPE(KIND, TAG##_property, Arc*); \
SGB_UTIL_ACCESSOR_TYPE(KIND, TAG##_property, sgb_graph_ptr); \
SGB_UTIL_ACCESSOR_TYPE(KIND, TAG##_property, long); \
SGB_UTIL_ACCESSOR_TYPE(KIND, TAG##_property, char*);
#endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
SGB_UTIL_ACCESSOR(vertex, u)
SGB_UTIL_ACCESSOR(vertex, v)
SGB_UTIL_ACCESSOR(vertex, w)
SGB_UTIL_ACCESSOR(vertex, x)
SGB_UTIL_ACCESSOR(vertex, y)
SGB_UTIL_ACCESSOR(vertex, z)
SGB_UTIL_ACCESSOR(edge, a)
SGB_UTIL_ACCESSOR(edge, b)
} // namespace boost
#endif // BOOST_GRAPH_SGB_GRAPH_HPP

View File

@@ -1,350 +0,0 @@
//
//=======================================================================
// Copyright 1997, 1998, 1999, 2000 University of Notre Dame.
// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek
//
// This file is part of the Boost Graph Library
//
// You should have received a copy of the License Agreement for the
// Boost Graph Library along with the software; see the file LICENSE.
// If not, contact Office of Research, University of Notre Dame, Notre
// Dame, IN 46556.
//
// Permission to modify the code and to distribute modified code is
// granted, provided the text of this NOTICE is retained, a notice that
// the code was modified is included with the above COPYRIGHT NOTICE and
// with the COPYRIGHT NOTICE in the LICENSE file, and that the LICENSE
// file is distributed with the modified code.
//
// LICENSOR MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED.
// By way of example, but not limitation, Licensor MAKES NO
// REPRESENTATIONS OR WARRANTIES OF MERCHANTABILITY OR FITNESS FOR ANY
// PARTICULAR PURPOSE OR THAT THE USE OF THE LICENSED SOFTWARE COMPONENTS
// OR DOCUMENTATION WILL NOT INFRINGE ANY PATENTS, COPYRIGHTS, TRADEMARKS
// OR OTHER RIGHTS.
//=======================================================================
//
#ifndef BOOST_GRAPH_STRONG_COMPONENTS_HPP
#define BOOST_GRAPH_STRONG_COMPONENTS_HPP
#include <stack>
#include <boost/config.hpp>
#include <boost/graph/depth_first_search.hpp>
#include <boost/type_traits/conversion_traits.hpp>
#include <boost/static_assert.hpp>
namespace boost {
//==========================================================================
// This is Tarjan's algorithm for strongly connected components
// from his paper "Depth first search and linear graph algorithms".
// It calculates the components in a single application of DFS.
// We implement the algorithm as a dfs-visitor.
namespace detail {
template <typename ComponentMap, typename RootMap, typename DiscoverTime,
typename Stack>
class tarjan_scc_visitor : public dfs_visitor<>
{
typedef typename property_traits<ComponentMap>::value_type comp_type;
typedef typename property_traits<DiscoverTime>::value_type time_type;
public:
tarjan_scc_visitor(ComponentMap comp_map, RootMap r, DiscoverTime d,
comp_type& c_, Stack& s_)
: c(c_), comp(comp_map), root(r), discover_time(d),
dfs_time(time_type()), s(s_) { }
template <typename Graph>
void discover_vertex(typename graph_traits<Graph>::vertex_descriptor v,
const Graph&) {
put(root, v, v);
put(comp, v, (std::numeric_limits<comp_type>::max)());
put(discover_time, v, dfs_time++);
s.push(v);
}
template <typename Graph>
void finish_vertex(typename graph_traits<Graph>::vertex_descriptor v,
const Graph& g) {
typename graph_traits<Graph>::vertex_descriptor w;
typename graph_traits<Graph>::out_edge_iterator ei, ei_end;
for (tie(ei, ei_end) = out_edges(v, g); ei != ei_end; ++ei) {
w = target(*ei, g);
if (get(comp, w) == (std::numeric_limits<comp_type>::max)())
put(root, v, this->min_discover_time(get(root,v), get(root,w)));
}
if (get(root, v) == v) {
do {
w = s.top(); s.pop();
put(comp, w, c);
} while (w != v);
++c;
}
}
private:
template <typename Vertex>
Vertex min_discover_time(Vertex u, Vertex v) {
return get(discover_time, u) < get(discover_time,v) ? u : v;
}
comp_type& c;
ComponentMap comp;
RootMap root;
DiscoverTime discover_time;
time_type dfs_time;
Stack& s;
};
template <class Graph, class ComponentMap, class RootMap,
class DiscoverTime, class P, class T, class R>
typename property_traits<ComponentMap>::value_type
strong_components_impl
(const Graph& g, // Input
ComponentMap comp, // Output
// Internal record keeping
RootMap root,
DiscoverTime discover_time,
const bgl_named_params<P, T, R>& params)
{
typedef typename graph_traits<Graph>::vertex_descriptor Vertex;
function_requires< ReadWritePropertyMapConcept<ComponentMap, Vertex> >();
function_requires< ReadWritePropertyMapConcept<RootMap, Vertex> >();
typedef typename property_traits<RootMap>::value_type RootV;
function_requires< ConvertibleConcept<RootV, Vertex> >();
function_requires< ReadWritePropertyMapConcept<DiscoverTime, Vertex> >();
typename property_traits<ComponentMap>::value_type total = 0;
std::stack<Vertex> s;
detail::tarjan_scc_visitor<ComponentMap, RootMap, DiscoverTime,
std::stack<Vertex> >
vis(comp, root, discover_time, total, s);
depth_first_search(g, params.visitor(vis));
return total;
}
//-------------------------------------------------------------------------
// The dispatch functions handle the defaults for the rank and discover
// time property maps.
// dispatch with class specialization to avoid VC++ bug
template <class DiscoverTimeMap>
struct strong_comp_dispatch2 {
template <class Graph, class ComponentMap, class RootMap, class P, class T, class R>
inline static typename property_traits<ComponentMap>::value_type
apply(const Graph& g,
ComponentMap comp,
RootMap r_map,
const bgl_named_params<P, T, R>& params,
DiscoverTimeMap time_map)
{
return strong_components_impl(g, comp, r_map, time_map, params);
}
};
template <>
struct strong_comp_dispatch2<detail::error_property_not_found> {
template <class Graph, class ComponentMap, class RootMap,
class P, class T, class R>
inline static typename property_traits<ComponentMap>::value_type
apply(const Graph& g,
ComponentMap comp,
RootMap r_map,
const bgl_named_params<P, T, R>& params,
detail::error_property_not_found)
{
typedef typename graph_traits<Graph>::vertices_size_type size_type;
size_type n = num_vertices(g) > 0 ? num_vertices(g) : 1;
std::vector<size_type> time_vec(n);
return strong_components_impl
(g, comp, r_map,
make_iterator_property_map(time_vec.begin(), choose_const_pmap
(get_param(params, vertex_index),
g, vertex_index), time_vec[0]),
params);
}
};
template <class Graph, class ComponentMap, class RootMap,
class P, class T, class R, class DiscoverTimeMap>
inline typename property_traits<ComponentMap>::value_type
scc_helper2(const Graph& g,
ComponentMap comp,
RootMap r_map,
const bgl_named_params<P, T, R>& params,
DiscoverTimeMap time_map)
{
return strong_comp_dispatch2<DiscoverTimeMap>::apply(g, comp, r_map, params, time_map);
}
template <class RootMap>
struct strong_comp_dispatch1 {
template <class Graph, class ComponentMap, class P, class T, class R>
inline static typename property_traits<ComponentMap>::value_type
apply(const Graph& g,
ComponentMap comp,
const bgl_named_params<P, T, R>& params,
RootMap r_map)
{
return scc_helper2(g, comp, r_map, params, get_param(params, vertex_discover_time));
}
};
template <>
struct strong_comp_dispatch1<detail::error_property_not_found> {
template <class Graph, class ComponentMap,
class P, class T, class R>
inline static typename property_traits<ComponentMap>::value_type
apply(const Graph& g,
ComponentMap comp,
const bgl_named_params<P, T, R>& params,
detail::error_property_not_found)
{
typedef typename graph_traits<Graph>::vertex_descriptor Vertex;
typename std::vector<Vertex>::size_type
n = num_vertices(g) > 0 ? num_vertices(g) : 1;
std::vector<Vertex> root_vec(n);
return scc_helper2
(g, comp,
make_iterator_property_map(root_vec.begin(), choose_const_pmap
(get_param(params, vertex_index),
g, vertex_index), root_vec[0]),
params,
get_param(params, vertex_discover_time));
}
};
template <class Graph, class ComponentMap, class RootMap,
class P, class T, class R>
inline typename property_traits<ComponentMap>::value_type
scc_helper1(const Graph& g,
ComponentMap comp,
const bgl_named_params<P, T, R>& params,
RootMap r_map)
{
return detail::strong_comp_dispatch1<RootMap>::apply(g, comp, params,
r_map);
}
} // namespace detail
template <class Graph, class ComponentMap,
class P, class T, class R>
inline typename property_traits<ComponentMap>::value_type
strong_components(const Graph& g, ComponentMap comp,
const bgl_named_params<P, T, R>& params)
{
typedef typename graph_traits<Graph>::directed_category DirCat;
BOOST_STATIC_ASSERT((is_convertible<DirCat*, directed_tag*>::value == true));
return detail::scc_helper1(g, comp, params,
get_param(params, vertex_root_t()));
}
template <class Graph, class ComponentMap>
inline typename property_traits<ComponentMap>::value_type
strong_components(const Graph& g, ComponentMap comp)
{
typedef typename graph_traits<Graph>::directed_category DirCat;
BOOST_STATIC_ASSERT((is_convertible<DirCat*, directed_tag*>::value == true));
bgl_named_params<int, int> params(0);
return strong_components(g, comp, params);
}
template <typename Graph, typename ComponentMap, typename ComponentLists>
void build_component_lists
(const Graph& g,
typename graph_traits<Graph>::vertices_size_type num_scc,
ComponentMap component_number,
ComponentLists& components)
{
components.resize(num_scc);
typename graph_traits<Graph>::vertex_iterator vi, vi_end;
for (tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi)
components[component_number[*vi]].push_back(*vi);
}
} // namespace boost
#include <queue>
#include <vector>
#include <boost/graph/transpose_graph.hpp>
#include <boost/pending/indirect_cmp.hpp>
#include <boost/graph/connected_components.hpp> // for components_recorder
namespace boost {
//==========================================================================
// This is the version of strongly connected components from
// "Intro. to Algorithms" by Cormen, Leiserson, Rivest, which was
// adapted from "Data Structure and Algorithms" by Aho, Hopcroft,
// and Ullman, who credit the algorithm to S.R. Kosaraju and M. Sharir.
// The algorithm is based on computing DFS forests the graph
// and its transpose.
// This algorithm is slower than Tarjan's by a constant factor, uses
// more memory, and puts more requirements on the graph type.
template <class Graph, class DFSVisitor, class ComponentsMap,
class DiscoverTime, class FinishTime,
class ColorMap>
typename property_traits<ComponentsMap>::value_type
kosaraju_strong_components(Graph& G, ComponentsMap c,
FinishTime finish_time, ColorMap color)
{
function_requires< MutableGraphConcept<Graph> >();
// ...
typedef typename graph_traits<Graph>::vertex_descriptor Vertex;
typedef typename property_traits<ColorMap>::value_type ColorValue;
typedef color_traits<ColorValue> Color;
typename property_traits<FinishTime>::value_type time = 0;
depth_first_search
(G, make_dfs_visitor(stamp_times(finish_time, time, on_finish_vertex())),
color);
Graph G_T(num_vertices(G));
transpose_graph(G, G_T);
typedef typename property_traits<ComponentsMap>::value_type count_type;
count_type c_count(0);
detail::components_recorder<ComponentsMap>
vis(c, c_count);
// initialize G_T
typename graph_traits<Graph>::vertex_iterator ui, ui_end;
for (tie(ui, ui_end) = vertices(G_T); ui != ui_end; ++ui)
put(color, *ui, Color::white());
typedef typename property_traits<FinishTime>::value_type D;
typedef indirect_cmp< FinishTime, std::less<D> > Compare;
Compare fl(finish_time);
std::priority_queue<Vertex, std::vector<Vertex>, Compare > Q(fl);
typename graph_traits<Graph>::vertex_iterator i, j, iend, jend;
tie(i, iend) = vertices(G_T);
tie(j, jend) = vertices(G);
for ( ; i != iend; ++i, ++j) {
put(finish_time, *i, get(finish_time, *j));
Q.push(*i);
}
while ( !Q.empty() ) {
Vertex u = Q.top();
Q.pop();
if (get(color, u) == Color::white()) {
depth_first_visit(G_T, u, vis, color);
++c_count;
}
}
return c_count;
}
} // namespace boost
#endif // BOOST_GRAPH_STRONG_COMPONENTS_HPP

View File

@@ -1,861 +0,0 @@
//=======================================================================
// Copyright 2001 University of Notre Dame.
// Authors: Jeremy G. Siek and Lie-Quan Lee
//
// This file is part of the Boost Graph Library
//
// You should have received a copy of the License Agreement for the
// Boost Graph Library along with the software; see the file LICENSE.
// If not, contact Office of Research, University of Notre Dame, Notre
// Dame, IN 46556.
//
// Permission to modify the code and to distribute modified code is
// granted, provided the text of this NOTICE is retained, a notice that
// the code was modified is included with the above COPYRIGHT NOTICE and
// with the COPYRIGHT NOTICE in the LICENSE file, and that the LICENSE
// file is distributed with the modified code.
//
// LICENSOR MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED.
// By way of example, but not limitation, Licensor MAKES NO
// REPRESENTATIONS OR WARRANTIES OF MERCHANTABILITY OR FITNESS FOR ANY
// PARTICULAR PURPOSE OR THAT THE USE OF THE LICENSED SOFTWARE COMPONENTS
// OR DOCUMENTATION WILL NOT INFRINGE ANY PATENTS, COPYRIGHTS, TRADEMARKS
// OR OTHER RIGHTS.
//=======================================================================
#ifndef BOOST_SUBGRAPH_HPP
#define BOOST_SUBGRAPH_HPP
// UNDER CONSTRUCTION
#include <boost/config.hpp>
#include <list>
#include <vector>
#include <map>
#include <cassert>
#include <boost/graph/graph_traits.hpp>
#include <boost/graph/properties.hpp>
#include <boost/iterator/indirect_iterator.hpp>
#include <boost/static_assert.hpp>
#include <boost/type_traits/is_same.hpp>
namespace boost {
struct subgraph_tag { };
// Invariants of an induced subgraph:
// - If vertex u is in subgraph g, then u must be in g.parent().
// - If edge e is in subgraph g, then e must be in g.parent().
// - If edge e=(u,v) is in the root graph, then edge e
// is also in any subgraph that contains both vertex u and v.
// The Graph template parameter must have a vertex_index
// and edge_index internal property. It is assumed that
// the vertex indices are assigned automatically by the
// graph during a call to add_vertex(). It is not
// assumed that the edge vertices are assigned automatically,
// they are explicitly assigned here.
template <typename Graph>
class subgraph {
typedef graph_traits<Graph> Traits;
typedef std::list<subgraph<Graph>*> ChildrenList;
public:
// Graph requirements
typedef typename Traits::vertex_descriptor vertex_descriptor;
typedef typename Traits::edge_descriptor edge_descriptor;
typedef typename Traits::directed_category directed_category;
typedef typename Traits::edge_parallel_category edge_parallel_category;
typedef typename Traits::traversal_category traversal_category;
static vertex_descriptor null_vertex()
{
return Traits::null_vertex();
}
// IncidenceGraph requirements
typedef typename Traits::out_edge_iterator out_edge_iterator;
typedef typename Traits::degree_size_type degree_size_type;
// AdjacencyGraph requirements
typedef typename Traits::adjacency_iterator adjacency_iterator;
// VertexListGraph requirements
typedef typename Traits::vertex_iterator vertex_iterator;
typedef typename Traits::vertices_size_type vertices_size_type;
// EdgeListGraph requirements
typedef typename Traits::edge_iterator edge_iterator;
typedef typename Traits::edges_size_type edges_size_type;
typedef typename Traits::in_edge_iterator in_edge_iterator;
typedef typename Graph::edge_property_type edge_property_type;
typedef typename Graph::vertex_property_type vertex_property_type;
typedef subgraph_tag graph_tag;
typedef Graph graph_type;
typedef typename Graph::graph_property_type graph_property_type;
// Constructors
// Create the main graph, the root of the subgraph tree
subgraph()
: m_parent(0), m_edge_counter(0)
{ }
subgraph(const graph_property_type& p)
: m_graph(p), m_parent(0), m_edge_counter(0)
{ }
subgraph(vertices_size_type n,
const graph_property_type& p = graph_property_type())
: m_graph(n, p), m_parent(0), m_edge_counter(0), m_global_vertex(n)
{
typename Graph::vertex_iterator v, v_end;
vertices_size_type i = 0;
for (tie(v, v_end) = vertices(m_graph); v != v_end; ++v)
m_global_vertex[i++] = *v;
}
// copy constructor
subgraph(const subgraph& x)
: m_graph(x.m_graph), m_parent(x.m_parent),
m_edge_counter(x.m_edge_counter),
m_global_vertex(x.m_global_vertex),
m_global_edge(x.m_global_edge)
{
// Do a deep copy
for (typename ChildrenList::const_iterator i = x.m_children.begin();
i != x.m_children.end(); ++i)
m_children.push_back(new subgraph<Graph>( **i ));
}
~subgraph() {
for (typename ChildrenList::iterator i = m_children.begin();
i != m_children.end(); ++i)
delete *i;
}
// Create a subgraph
subgraph<Graph>& create_subgraph() {
m_children.push_back(new subgraph<Graph>());
m_children.back()->m_parent = this;
return *m_children.back();
}
// Create a subgraph with the specified vertex set.
template <typename VertexIterator>
subgraph<Graph>& create_subgraph(VertexIterator first,
VertexIterator last)
{
m_children.push_back(new subgraph<Graph>());
m_children.back()->m_parent = this;
for (; first != last; ++first)
add_vertex(*first, *m_children.back());
return *m_children.back();
}
// local <-> global descriptor conversion functions
vertex_descriptor local_to_global(vertex_descriptor u_local) const
{
return m_global_vertex[u_local];
}
vertex_descriptor global_to_local(vertex_descriptor u_global) const
{
vertex_descriptor u_local; bool in_subgraph;
tie(u_local, in_subgraph) = this->find_vertex(u_global);
assert(in_subgraph == true);
return u_local;
}
edge_descriptor local_to_global(edge_descriptor e_local) const
{
return m_global_edge[get(get(edge_index, m_graph), e_local)];
}
edge_descriptor global_to_local(edge_descriptor e_global) const
{
return
(*m_local_edge.find(get(get(edge_index, root().m_graph), e_global))).second;
}
// Is vertex u (of the root graph) contained in this subgraph?
// If so, return the matching local vertex.
std::pair<vertex_descriptor, bool>
find_vertex(vertex_descriptor u_global) const
{
typename std::map<vertex_descriptor, vertex_descriptor>::const_iterator
i = m_local_vertex.find(u_global);
bool valid = i != m_local_vertex.end();
return std::make_pair((valid ? (*i).second : null_vertex()), valid);
}
// Return the parent graph.
subgraph& parent() { return *m_parent; }
const subgraph& parent() const { return *m_parent; }
bool is_root() const { return m_parent == 0; }
// Return the root graph of the subgraph tree.
subgraph& root() {
if (this->is_root())
return *this;
else
return m_parent->root();
}
const subgraph& root() const {
if (this->is_root())
return *this;
else
return m_parent->root();
}
// Return the children subgraphs of this graph/subgraph.
// Use a list of pointers because the VC++ std::list doesn't like
// storing incomplete type.
typedef indirect_iterator<
typename ChildrenList::const_iterator
, subgraph<Graph>
, std::bidirectional_iterator_tag
>
children_iterator;
typedef indirect_iterator<
typename ChildrenList::const_iterator
, subgraph<Graph> const
, std::bidirectional_iterator_tag
>
const_children_iterator;
std::pair<const_children_iterator, const_children_iterator>
children() const
{
return std::make_pair(const_children_iterator(m_children.begin()),
const_children_iterator(m_children.end()));
}
std::pair<children_iterator, children_iterator>
children()
{
return std::make_pair(children_iterator(m_children.begin()),
children_iterator(m_children.end()));
}
std::size_t num_children() const { return m_children.size(); }
// private:
typedef typename property_map<Graph, edge_index_t>::type EdgeIndexMap;
typedef typename property_traits<EdgeIndexMap>::value_type edge_index_type;
BOOST_STATIC_ASSERT((!is_same<edge_index_type,
boost::detail::error_property_not_found>::value));
Graph m_graph;
subgraph<Graph>* m_parent;
edge_index_type m_edge_counter; // for generating unique edge indices
ChildrenList m_children;
std::vector<vertex_descriptor> m_global_vertex; // local -> global
std::map<vertex_descriptor, vertex_descriptor> m_local_vertex; // global -> local
std::vector<edge_descriptor> m_global_edge; // local -> global
std::map<edge_index_type, edge_descriptor> m_local_edge; // global -> local
edge_descriptor
local_add_edge(vertex_descriptor u_local, vertex_descriptor v_local,
edge_descriptor e_global)
{
edge_descriptor e_local;
bool inserted;
tie(e_local, inserted) = add_edge(u_local, v_local, m_graph);
put(edge_index, m_graph, e_local, m_edge_counter++);
m_global_edge.push_back(e_global);
m_local_edge[get(get(edge_index, this->root()), e_global)] = e_local;
return e_local;
}
};
//===========================================================================
// Functions special to the Subgraph Class
template <typename G>
typename subgraph<G>::vertex_descriptor
add_vertex(typename subgraph<G>::vertex_descriptor u_global,
subgraph<G>& g)
{
assert(!g.is_root());
typename subgraph<G>::vertex_descriptor u_local, v_global, uu_global;
typename subgraph<G>::edge_descriptor e_global;
u_local = add_vertex(g.m_graph);
g.m_global_vertex.push_back(u_global);
g.m_local_vertex[u_global] = u_local;
subgraph<G>& r = g.root();
// remember edge global and local maps
{
typename subgraph<G>::out_edge_iterator ei, ei_end;
for (tie(ei, ei_end) = out_edges(u_global, r);
ei != ei_end; ++ei) {
e_global = *ei;
v_global = target(e_global, r);
if (g.find_vertex(v_global).second == true)
g.local_add_edge(u_local, g.global_to_local(v_global), e_global);
}
}
if (is_directed(g)) { // not necessary for undirected graph
typename subgraph<G>::vertex_iterator vi, vi_end;
typename subgraph<G>::out_edge_iterator ei, ei_end;
for (tie(vi, vi_end) = vertices(r); vi != vi_end; ++vi) {
v_global = *vi;
if (g.find_vertex(v_global).second)
for (tie(ei, ei_end) = out_edges(*vi, r); ei != ei_end; ++ei) {
e_global = *ei;
uu_global = target(e_global, r);
if (uu_global == u_global && g.find_vertex(v_global).second)
g.local_add_edge(g.global_to_local(v_global), u_local, e_global);
}
}
}
return u_local;
}
//===========================================================================
// Functions required by the IncidenceGraph concept
template <typename G>
std::pair<typename graph_traits<G>::out_edge_iterator,
typename graph_traits<G>::out_edge_iterator>
out_edges(typename graph_traits<G>::vertex_descriptor u_local,
const subgraph<G>& g)
{ return out_edges(u_local, g.m_graph); }
template <typename G>
typename graph_traits<G>::degree_size_type
out_degree(typename graph_traits<G>::vertex_descriptor u_local,
const subgraph<G>& g)
{ return out_degree(u_local, g.m_graph); }
template <typename G>
typename graph_traits<G>::vertex_descriptor
source(typename graph_traits<G>::edge_descriptor e_local,
const subgraph<G>& g)
{ return source(e_local, g.m_graph); }
template <typename G>
typename graph_traits<G>::vertex_descriptor
target(typename graph_traits<G>::edge_descriptor e_local,
const subgraph<G>& g)
{ return target(e_local, g.m_graph); }
//===========================================================================
// Functions required by the BidirectionalGraph concept
template <typename G>
std::pair<typename graph_traits<G>::in_edge_iterator,
typename graph_traits<G>::in_edge_iterator>
in_edges(typename graph_traits<G>::vertex_descriptor u_local,
const subgraph<G>& g)
{ return in_edges(u_local, g.m_graph); }
template <typename G>
typename graph_traits<G>::degree_size_type
in_degree(typename graph_traits<G>::vertex_descriptor u_local,
const subgraph<G>& g)
{ return in_degree(u_local, g.m_graph); }
template <typename G>
typename graph_traits<G>::degree_size_type
degree(typename graph_traits<G>::vertex_descriptor u_local,
const subgraph<G>& g)
{ return degree(u_local, g.m_graph); }
//===========================================================================
// Functions required by the AdjacencyGraph concept
template <typename G>
std::pair<typename subgraph<G>::adjacency_iterator,
typename subgraph<G>::adjacency_iterator>
adjacent_vertices(typename subgraph<G>::vertex_descriptor u_local,
const subgraph<G>& g)
{ return adjacent_vertices(u_local, g.m_graph); }
//===========================================================================
// Functions required by the VertexListGraph concept
template <typename G>
std::pair<typename subgraph<G>::vertex_iterator,
typename subgraph<G>::vertex_iterator>
vertices(const subgraph<G>& g)
{ return vertices(g.m_graph); }
template <typename G>
typename subgraph<G>::vertices_size_type
num_vertices(const subgraph<G>& g)
{ return num_vertices(g.m_graph); }
//===========================================================================
// Functions required by the EdgeListGraph concept
template <typename G>
std::pair<typename subgraph<G>::edge_iterator,
typename subgraph<G>::edge_iterator>
edges(const subgraph<G>& g)
{ return edges(g.m_graph); }
template <typename G>
typename subgraph<G>::edges_size_type
num_edges(const subgraph<G>& g)
{ return num_edges(g.m_graph); }
//===========================================================================
// Functions required by the AdjacencyMatrix concept
template <typename G>
std::pair<typename subgraph<G>::edge_descriptor, bool>
edge(typename subgraph<G>::vertex_descriptor u_local,
typename subgraph<G>::vertex_descriptor v_local,
const subgraph<G>& g)
{
return edge(u_local, v_local, g.m_graph);
}
//===========================================================================
// Functions required by the MutableGraph concept
namespace detail {
template <typename Vertex, typename Edge, typename Graph>
void add_edge_recur_down
(Vertex u_global, Vertex v_global, Edge e_global, subgraph<Graph>& g);
template <typename Vertex, typename Edge, typename Children, typename G>
void children_add_edge(Vertex u_global, Vertex v_global, Edge e_global,
Children& c, subgraph<G>* orig)
{
for (typename Children::iterator i = c.begin(); i != c.end(); ++i)
if ((*i)->find_vertex(u_global).second
&& (*i)->find_vertex(v_global).second)
add_edge_recur_down(u_global, v_global, e_global, **i, orig);
}
template <typename Vertex, typename Edge, typename Graph>
void add_edge_recur_down
(Vertex u_global, Vertex v_global, Edge e_global, subgraph<Graph>& g,
subgraph<Graph>* orig)
{
if (&g != orig ) {
// add local edge only if u_global and v_global are in subgraph g
Vertex u_local, v_local;
bool u_in_subgraph, v_in_subgraph;
tie(u_local, u_in_subgraph) = g.find_vertex(u_global);
tie(v_local, v_in_subgraph) = g.find_vertex(v_global);
if (u_in_subgraph && v_in_subgraph)
g.local_add_edge(u_local, v_local, e_global);
}
children_add_edge(u_global, v_global, e_global, g.m_children, orig);
}
template <typename Vertex, typename Graph>
std::pair<typename subgraph<Graph>::edge_descriptor, bool>
add_edge_recur_up(Vertex u_global, Vertex v_global,
const typename Graph::edge_property_type& ep,
subgraph<Graph>& g, subgraph<Graph>* orig)
{
if (g.is_root()) {
typename subgraph<Graph>::edge_descriptor e_global;
bool inserted;
tie(e_global, inserted) = add_edge(u_global, v_global, ep, g.m_graph);
put(edge_index, g.m_graph, e_global, g.m_edge_counter++);
g.m_global_edge.push_back(e_global);
children_add_edge(u_global, v_global, e_global, g.m_children, orig);
return std::make_pair(e_global, inserted);
} else
return add_edge_recur_up(u_global, v_global, ep, *g.m_parent, orig);
}
} // namespace detail
// Add an edge to the subgraph g, specified by the local vertex
// descriptors u and v. In addition, the edge will be added to any
// other subgraphs which contain vertex descriptors u and v.
template <typename G>
std::pair<typename subgraph<G>::edge_descriptor, bool>
add_edge(typename subgraph<G>::vertex_descriptor u_local,
typename subgraph<G>::vertex_descriptor v_local,
const typename G::edge_property_type& ep,
subgraph<G>& g)
{
if (g.is_root()) // u_local and v_local are really global
return detail::add_edge_recur_up(u_local, v_local, ep, g, &g);
else {
typename subgraph<G>::edge_descriptor e_local, e_global;
bool inserted;
tie(e_global, inserted) = detail::add_edge_recur_up
(g.local_to_global(u_local), g.local_to_global(v_local), ep, g, &g);
e_local = g.local_add_edge(u_local, v_local, e_global);
return std::make_pair(e_local, inserted);
}
}
template <typename G>
std::pair<typename subgraph<G>::edge_descriptor, bool>
add_edge(typename subgraph<G>::vertex_descriptor u,
typename subgraph<G>::vertex_descriptor v,
subgraph<G>& g)
{
typename G::edge_property_type ep;
return add_edge(u, v, ep, g);
}
namespace detail {
//-------------------------------------------------------------------------
// implementation of remove_edge(u,v,g)
template <typename Vertex, typename Graph>
void remove_edge_recur_down(Vertex u_global, Vertex v_global,
subgraph<Graph>& g);
template <typename Vertex, typename Children>
void children_remove_edge(Vertex u_global, Vertex v_global,
Children& c)
{
for (typename Children::iterator i = c.begin(); i != c.end(); ++i)
if ((*i)->find_vertex(u_global).second
&& (*i)->find_vertex(v_global).second)
remove_edge_recur_down(u_global, v_global, **i);
}
template <typename Vertex, typename Graph>
void remove_edge_recur_down(Vertex u_global, Vertex v_global,
subgraph<Graph>& g)
{
Vertex u_local, v_local;
u_local = g.m_local_vertex[u_global];
v_local = g.m_local_vertex[v_global];
remove_edge(u_local, v_local, g.m_graph);
children_remove_edge(u_global, v_global, g.m_children);
}
template <typename Vertex, typename Graph>
void remove_edge_recur_up(Vertex u_global, Vertex v_global,
subgraph<Graph>& g)
{
if (g.is_root()) {
remove_edge(u_global, v_global, g.m_graph);
children_remove_edge(u_global, v_global, g.m_children);
} else
remove_edge_recur_up(u_global, v_global, *g.m_parent);
}
//-------------------------------------------------------------------------
// implementation of remove_edge(e,g)
template <typename Edge, typename Graph>
void remove_edge_recur_down(Edge e_global, subgraph<Graph>& g);
template <typename Edge, typename Children>
void children_remove_edge(Edge e_global, Children& c)
{
for (typename Children::iterator i = c.begin(); i != c.end(); ++i)
if ((*i)->find_vertex(source(e_global, **i)).second
&& (*i)->find_vertex(target(e_global, **i)).second)
remove_edge_recur_down(source(e_global, **i),
target(e_global, **i), **i);
}
template <typename Edge, typename Graph>
void remove_edge_recur_down(Edge e_global, subgraph<Graph>& g)
{
remove_edge(g.global_to_local(e_global), g.m_graph);
children_remove_edge(e_global, g.m_children);
}
template <typename Edge, typename Graph>
void remove_edge_recur_up(Edge e_global, subgraph<Graph>& g)
{
if (g.is_root()) {
remove_edge(e_global, g.m_graph);
children_remove_edge(e_global, g.m_children);
} else
remove_edge_recur_up(e_global, *g.m_parent);
}
} // namespace detail
template <typename G>
void
remove_edge(typename subgraph<G>::vertex_descriptor u_local,
typename subgraph<G>::vertex_descriptor v_local,
subgraph<G>& g)
{
if (g.is_root())
detail::remove_edge_recur_up(u_local, v_local, g);
else
detail::remove_edge_recur_up(g.local_to_global(u_local),
g.local_to_global(v_local), g);
}
template <typename G>
void
remove_edge(typename subgraph<G>::edge_descriptor e_local,
subgraph<G>& g)
{
if (g.is_root())
detail::remove_edge_recur_up(e_local, g);
else
detail::remove_edge_recur_up(g.local_to_global(e_local), g);
}
template <typename Predicate, typename G>
void
remove_edge_if(Predicate p, subgraph<G>& g)
{
// This is wrong...
remove_edge_if(p, g.m_graph);
}
template <typename G>
void
clear_vertex(typename subgraph<G>::vertex_descriptor v_local,
subgraph<G>& g)
{
// this is wrong...
clear_vertex(v_local, g.m_graph);
}
namespace detail {
template <typename G>
typename subgraph<G>::vertex_descriptor
add_vertex_recur_up(subgraph<G>& g)
{
typename subgraph<G>::vertex_descriptor u_local, u_global;
if (g.is_root()) {
u_global = add_vertex(g.m_graph);
g.m_global_vertex.push_back(u_global);
} else {
u_global = add_vertex_recur_up(*g.m_parent);
u_local = add_vertex(g.m_graph);
g.m_global_vertex.push_back(u_global);
g.m_local_vertex[u_global] = u_local;
}
return u_global;
}
} // namespace detail
template <typename G>
typename subgraph<G>::vertex_descriptor
add_vertex(subgraph<G>& g)
{
typename subgraph<G>::vertex_descriptor u_local, u_global;
if (g.is_root()) {
u_global = add_vertex(g.m_graph);
g.m_global_vertex.push_back(u_global);
u_local = u_global;
} else {
u_global = detail::add_vertex_recur_up(g.parent());
u_local = add_vertex(g.m_graph);
g.m_global_vertex.push_back(u_global);
g.m_local_vertex[u_global] = u_local;
}
return u_local;
}
template <typename G>
void remove_vertex(typename subgraph<G>::vertex_descriptor u,
subgraph<G>& g)
{
// UNDER CONSTRUCTION
assert(false);
}
//===========================================================================
// Functions required by the PropertyGraph concept
template <typename GraphPtr, typename PropertyMap, typename Tag>
class subgraph_global_property_map
: public put_get_helper<
typename property_traits<PropertyMap>::reference,
subgraph_global_property_map<GraphPtr, PropertyMap, Tag> >
{
typedef property_traits<PropertyMap> Traits;
public:
typedef typename Traits::category category;
typedef typename Traits::value_type value_type;
typedef typename Traits::key_type key_type;
typedef typename Traits::reference reference;
subgraph_global_property_map() { }
subgraph_global_property_map(GraphPtr g)
: m_g(g) { }
inline reference operator[](key_type e_local) const {
PropertyMap pmap = get(Tag(), m_g->root().m_graph);
if (m_g->m_parent == 0)
return pmap[e_local];
else
return pmap[m_g->local_to_global(e_local)];
}
GraphPtr m_g;
};
template <typename GraphPtr, typename PropertyMap, typename Tag>
class subgraph_local_property_map
: public put_get_helper<
typename property_traits<PropertyMap>::reference,
subgraph_local_property_map<GraphPtr, PropertyMap, Tag> >
{
typedef property_traits<PropertyMap> Traits;
public:
typedef typename Traits::category category;
typedef typename Traits::value_type value_type;
typedef typename Traits::key_type key_type;
typedef typename Traits::reference reference;
subgraph_local_property_map() { }
subgraph_local_property_map(GraphPtr g)
: m_g(g) { }
inline reference operator[](key_type e_local) const {
PropertyMap pmap = get(Tag(), *m_g);
return pmap[e_local];
}
GraphPtr m_g;
};
namespace detail {
struct subgraph_any_pmap {
template <class Tag, class SubGraph, class Property>
class bind_ {
typedef typename SubGraph::graph_type Graph;
typedef SubGraph* SubGraphPtr;
typedef const SubGraph* const_SubGraphPtr;
typedef typename property_map<Graph, Tag>::type PMap;
typedef typename property_map<Graph, Tag>::const_type const_PMap;
public:
typedef subgraph_global_property_map<SubGraphPtr, PMap, Tag> type;
typedef subgraph_global_property_map<const_SubGraphPtr, const_PMap, Tag>
const_type;
};
};
struct subgraph_id_pmap {
template <class Tag, class SubGraph, class Property>
struct bind_ {
typedef typename SubGraph::graph_type Graph;
typedef SubGraph* SubGraphPtr;
typedef const SubGraph* const_SubGraphPtr;
typedef typename property_map<Graph, Tag>::type PMap;
typedef typename property_map<Graph, Tag>::const_type const_PMap;
public:
typedef subgraph_local_property_map<SubGraphPtr, PMap, Tag> type;
typedef subgraph_local_property_map<const_SubGraphPtr, const_PMap, Tag>
const_type;
};
};
template <class Tag>
struct subgraph_choose_pmap_helper {
typedef subgraph_any_pmap type;
};
template <>
struct subgraph_choose_pmap_helper<vertex_index_t> {
typedef subgraph_id_pmap type;
};
template <class Tag, class Graph, class Property>
struct subgraph_choose_pmap {
typedef typename subgraph_choose_pmap_helper<Tag>::type Helper;
typedef typename Helper::template bind_<Tag, Graph, Property> Bind;
typedef typename Bind::type type;
typedef typename Bind::const_type const_type;
};
struct subgraph_property_generator {
template <class SubGraph, class Property, class Tag>
struct bind_ {
typedef subgraph_choose_pmap<Tag, SubGraph, Property> Choice;
typedef typename Choice::type type;
typedef typename Choice::const_type const_type;
};
};
} // namespace detail
template <>
struct vertex_property_selector<subgraph_tag> {
typedef detail::subgraph_property_generator type;
};
template <>
struct edge_property_selector<subgraph_tag> {
typedef detail::subgraph_property_generator type;
};
template <typename G, typename Property>
typename property_map< subgraph<G>, Property>::type
get(Property, subgraph<G>& g)
{
typedef typename property_map< subgraph<G>, Property>::type PMap;
return PMap(&g);
}
template <typename G, typename Property>
typename property_map< subgraph<G>, Property>::const_type
get(Property, const subgraph<G>& g)
{
typedef typename property_map< subgraph<G>, Property>::const_type PMap;
return PMap(&g);
}
template <typename G, typename Property, typename Key>
typename property_traits<
typename property_map< subgraph<G>, Property>::const_type
>::value_type
get(Property, const subgraph<G>& g, const Key& k)
{
typedef typename property_map< subgraph<G>, Property>::const_type PMap;
PMap pmap(&g);
return pmap[k];
}
template <typename G, typename Property, typename Key, typename Value>
void
put(Property, subgraph<G>& g, const Key& k, const Value& val)
{
typedef typename property_map< subgraph<G>, Property>::type PMap;
PMap pmap(&g);
pmap[k] = val;
}
template <typename G, typename Tag>
inline
typename graph_property<G, Tag>::type&
get_property(subgraph<G>& g, Tag tag) {
return get_property(g.root().m_graph, tag);
}
template <typename G, typename Tag>
inline
const typename graph_property<G, Tag>::type&
get_property(const subgraph<G>& g, Tag tag) {
return get_property(g.root().m_graph, tag);
}
//===========================================================================
// Miscellaneous Functions
template <typename G>
typename subgraph<G>::vertex_descriptor
vertex(typename subgraph<G>::vertices_size_type n, const subgraph<G>& g)
{
return vertex(n, g.m_graph);
}
} // namespace boost
#endif // BOOST_SUBGRAPH_HPP

View File

@@ -1,92 +0,0 @@
//
//=======================================================================
// Copyright 1997, 1998, 1999, 2000 University of Notre Dame.
// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek
//
// This file is part of the Boost Graph Library
//
// You should have received a copy of the License Agreement for the
// Boost Graph Library along with the software; see the file LICENSE.
// If not, contact Office of Research, University of Notre Dame, Notre
// Dame, IN 46556.
//
// Permission to modify the code and to distribute modified code is
// granted, provided the text of this NOTICE is retained, a notice that
// the code was modified is included with the above COPYRIGHT NOTICE and
// with the COPYRIGHT NOTICE in the LICENSE file, and that the LICENSE
// file is distributed with the modified code.
//
// LICENSOR MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED.
// By way of example, but not limitation, Licensor MAKES NO
// REPRESENTATIONS OR WARRANTIES OF MERCHANTABILITY OR FITNESS FOR ANY
// PARTICULAR PURPOSE OR THAT THE USE OF THE LICENSED SOFTWARE COMPONENTS
// OR DOCUMENTATION WILL NOT INFRINGE ANY PATENTS, COPYRIGHTS, TRADEMARKS
// OR OTHER RIGHTS.
//=======================================================================
//
#ifndef BOOST_GRAPH_TOPOLOGICAL_SORT_HPP
#define BOOST_GRAPH_TOPOLOGICAL_SORT_HPP
#include <boost/config.hpp>
#include <boost/property_map.hpp>
#include <boost/graph/depth_first_search.hpp>
#include <boost/graph/visitors.hpp>
#include <boost/graph/exception.hpp>
namespace boost {
// Topological sort visitor
//
// This visitor merely writes the linear ordering into an
// OutputIterator. The OutputIterator could be something like an
// ostream_iterator, or it could be a back/front_insert_iterator.
// Note that if it is a back_insert_iterator, the recorded order is
// the reverse topological order. On the other hand, if it is a
// front_insert_iterator, the recorded order is the topological
// order.
//
template <typename OutputIterator>
struct topo_sort_visitor : public dfs_visitor<>
{
topo_sort_visitor(OutputIterator _iter)
: m_iter(_iter) { }
template <typename Edge, typename Graph>
void back_edge(const Edge& u, Graph&) { throw not_a_dag(); }
template <typename Vertex, typename Graph>
void finish_vertex(const Vertex& u, Graph&) { *m_iter++ = u; }
OutputIterator m_iter;
};
// Topological Sort
//
// The topological sort algorithm creates a linear ordering
// of the vertices such that if edge (u,v) appears in the graph,
// then u comes before v in the ordering. The graph must
// be a directed acyclic graph (DAG). The implementation
// consists mainly of a call to depth-first search.
//
template <typename VertexListGraph, typename OutputIterator,
typename P, typename T, typename R>
void topological_sort(VertexListGraph& g, OutputIterator result,
const bgl_named_params<P, T, R>& params)
{
typedef topo_sort_visitor<OutputIterator> TopoVisitor;
depth_first_search(g, params.visitor(TopoVisitor(result)));
}
template <typename VertexListGraph, typename OutputIterator>
void topological_sort(VertexListGraph& g, OutputIterator result)
{
topological_sort(g, result,
bgl_named_params<int, buffer_param_t>(0)); // bogus
}
} // namespace boost
#endif /*BOOST_GRAPH_TOPOLOGICAL_SORT_H*/

View File

@@ -1,370 +0,0 @@
// Copyright (C) 2001 Vladimir Prus <ghost@cs.msu.su>
// Copyright (C) 2001 Jeremy Siek <jsiek@cs.indiana.edu>
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// NOTE: this final is generated by libs/graph/doc/transitive_closure.w
#ifndef BOOST_GRAPH_TRANSITIVE_CLOSURE_HPP
#define BOOST_GRAPH_TRANSITIVE_CLOSURE_HPP
#include <vector>
#include <algorithm> // for std::min and std::max
#include <functional>
#include <boost/config.hpp>
#include <boost/bind.hpp>
#include <boost/graph/vector_as_graph.hpp>
#include <boost/graph/strong_components.hpp>
#include <boost/graph/topological_sort.hpp>
#include <boost/graph/graph_concepts.hpp>
#include <boost/graph/named_function_params.hpp>
namespace boost
{
namespace detail
{
inline void
union_successor_sets(const std::vector < std::size_t > &s1,
const std::vector < std::size_t > &s2,
std::vector < std::size_t > &s3)
{
BOOST_USING_STD_MIN();
for (std::size_t k = 0; k < s1.size(); ++k)
s3[k] = min BOOST_PREVENT_MACRO_SUBSTITUTION(s1[k], s2[k]);
}
} // namespace detail
namespace detail
{
template < typename Container, typename ST = std::size_t,
typename VT = typename Container::value_type >
struct subscript_t:public std::unary_function < ST, VT >
{
typedef VT& result_type;
subscript_t(Container & c):container(&c)
{
}
VT & operator() (const ST & i) const
{
return (*container)[i];
}
protected:
Container * container;
};
template < typename Container >
subscript_t < Container > subscript(Container & c) {
return subscript_t < Container > (c);
}
} // namespace detail
template < typename Graph, typename GraphTC,
typename G_to_TC_VertexMap,
typename VertexIndexMap >
void transitive_closure(const Graph & g, GraphTC & tc,
G_to_TC_VertexMap g_to_tc_map,
VertexIndexMap index_map)
{
if (num_vertices(g) == 0)
return;
typedef typename graph_traits < Graph >::vertex_descriptor vertex;
typedef typename graph_traits < Graph >::edge_descriptor edge;
typedef typename graph_traits < Graph >::vertex_iterator vertex_iterator;
typedef typename property_traits < VertexIndexMap >::value_type size_type;
typedef typename graph_traits <
Graph >::adjacency_iterator adjacency_iterator;
function_requires < VertexListGraphConcept < Graph > >();
function_requires < AdjacencyGraphConcept < Graph > >();
function_requires < VertexMutableGraphConcept < GraphTC > >();
function_requires < EdgeMutableGraphConcept < GraphTC > >();
function_requires < ReadablePropertyMapConcept < VertexIndexMap,
vertex > >();
typedef size_type cg_vertex;
std::vector < cg_vertex > component_number_vec(num_vertices(g));
iterator_property_map < cg_vertex *, VertexIndexMap, cg_vertex, cg_vertex& >
component_number(&component_number_vec[0], index_map);
int num_scc = strong_components(g, component_number,
vertex_index_map(index_map));
std::vector < std::vector < vertex > >components;
build_component_lists(g, num_scc, component_number, components);
typedef std::vector<std::vector<cg_vertex> > CG_t;
CG_t CG(num_scc);
for (cg_vertex s = 0; s < components.size(); ++s) {
std::vector < cg_vertex > adj;
for (size_type i = 0; i < components[s].size(); ++i) {
vertex u = components[s][i];
adjacency_iterator v, v_end;
for (tie(v, v_end) = adjacent_vertices(u, g); v != v_end; ++v) {
cg_vertex t = component_number[*v];
if (s != t) // Avoid loops in the condensation graph
adj.push_back(t);
}
}
std::sort(adj.begin(), adj.end());
typename std::vector<cg_vertex>::iterator di =
std::unique(adj.begin(), adj.end());
if (di != adj.end())
adj.erase(di, adj.end());
CG[s] = adj;
}
std::vector<cg_vertex> topo_order;
std::vector<cg_vertex> topo_number(num_vertices(CG));
topological_sort(CG, std::back_inserter(topo_order),
vertex_index_map(identity_property_map()));
std::reverse(topo_order.begin(), topo_order.end());
size_type n = 0;
for (typename std::vector<cg_vertex>::iterator iter = topo_order.begin();
iter != topo_order.end(); ++iter)
topo_number[*iter] = n++;
for (size_type i = 0; i < num_vertices(CG); ++i)
std::sort(CG[i].begin(), CG[i].end(),
boost::bind(std::less<cg_vertex>(),
boost::bind(detail::subscript(topo_number), _1),
boost::bind(detail::subscript(topo_number), _2)));
std::vector<std::vector<cg_vertex> > chains;
{
std::vector<cg_vertex> in_a_chain(num_vertices(CG));
for (typename std::vector<cg_vertex>::iterator i = topo_order.begin();
i != topo_order.end(); ++i) {
cg_vertex v = *i;
if (!in_a_chain[v]) {
chains.resize(chains.size() + 1);
std::vector<cg_vertex>& chain = chains.back();
for (;;) {
chain.push_back(v);
in_a_chain[v] = true;
typename graph_traits<CG_t>::adjacency_iterator adj_first, adj_last;
tie(adj_first, adj_last) = adjacent_vertices(v, CG);
typename graph_traits<CG_t>::adjacency_iterator next
= std::find_if(adj_first, adj_last,
not1(detail::subscript(in_a_chain)));
if (next != adj_last)
v = *next;
else
break; // end of chain, dead-end
}
}
}
}
std::vector<size_type> chain_number(num_vertices(CG));
std::vector<size_type> pos_in_chain(num_vertices(CG));
for (size_type i = 0; i < chains.size(); ++i)
for (size_type j = 0; j < chains[i].size(); ++j) {
cg_vertex v = chains[i][j];
chain_number[v] = i;
pos_in_chain[v] = j;
}
cg_vertex inf = (std::numeric_limits< cg_vertex >::max)();
std::vector<std::vector<cg_vertex> > successors(num_vertices(CG),
std::vector<cg_vertex>
(chains.size(), inf));
for (typename std::vector<cg_vertex>::reverse_iterator
i = topo_order.rbegin(); i != topo_order.rend(); ++i) {
cg_vertex u = *i;
typename graph_traits<CG_t>::adjacency_iterator adj, adj_last;
for (tie(adj, adj_last) = adjacent_vertices(u, CG);
adj != adj_last; ++adj) {
cg_vertex v = *adj;
if (topo_number[v] < successors[u][chain_number[v]]) {
// Succ(u) = Succ(u) U Succ(v)
detail::union_successor_sets(successors[u], successors[v],
successors[u]);
// Succ(u) = Succ(u) U {v}
successors[u][chain_number[v]] = topo_number[v];
}
}
}
for (size_type i = 0; i < CG.size(); ++i)
CG[i].clear();
for (size_type i = 0; i < CG.size(); ++i)
for (size_type j = 0; j < chains.size(); ++j) {
size_type topo_num = successors[i][j];
if (topo_num < inf) {
cg_vertex v = topo_order[topo_num];
for (size_type k = pos_in_chain[v]; k < chains[j].size(); ++k)
CG[i].push_back(chains[j][k]);
}
}
// Add vertices to the transitive closure graph
typedef typename graph_traits < GraphTC >::vertex_descriptor tc_vertex;
{
vertex_iterator i, i_end;
for (tie(i, i_end) = vertices(g); i != i_end; ++i)
g_to_tc_map[*i] = add_vertex(tc);
}
// Add edges between all the vertices in two adjacent SCCs
typename graph_traits<CG_t>::vertex_iterator si, si_end;
for (tie(si, si_end) = vertices(CG); si != si_end; ++si) {
cg_vertex s = *si;
typename graph_traits<CG_t>::adjacency_iterator i, i_end;
for (tie(i, i_end) = adjacent_vertices(s, CG); i != i_end; ++i) {
cg_vertex t = *i;
for (size_type k = 0; k < components[s].size(); ++k)
for (size_type l = 0; l < components[t].size(); ++l)
add_edge(g_to_tc_map[components[s][k]],
g_to_tc_map[components[t][l]], tc);
}
}
// Add edges connecting all vertices in a SCC
for (size_type i = 0; i < components.size(); ++i)
if (components[i].size() > 1)
for (size_type k = 0; k < components[i].size(); ++k)
for (size_type l = 0; l < components[i].size(); ++l) {
vertex u = components[i][k], v = components[i][l];
add_edge(g_to_tc_map[u], g_to_tc_map[v], tc);
}
// Find loopbacks in the original graph.
// Need to add it to transitive closure.
{
vertex_iterator i, i_end;
for (tie(i, i_end) = vertices(g); i != i_end; ++i)
{
adjacency_iterator ab, ae;
for (boost::tie(ab, ae) = adjacent_vertices(*i, g); ab != ae; ++ab)
{
if (*ab == *i)
if (components[component_number[*i]].size() == 1)
add_edge(g_to_tc_map[*i], g_to_tc_map[*i], tc);
}
}
}
}
template <typename Graph, typename GraphTC>
void transitive_closure(const Graph & g, GraphTC & tc)
{
if (num_vertices(g) == 0)
return;
typedef typename property_map<Graph, vertex_index_t>::const_type
VertexIndexMap;
VertexIndexMap index_map = get(vertex_index, g);
typedef typename graph_traits<GraphTC>::vertex_descriptor tc_vertex;
std::vector<tc_vertex> to_tc_vec(num_vertices(g));
iterator_property_map < tc_vertex *, VertexIndexMap, tc_vertex, tc_vertex&>
g_to_tc_map(&to_tc_vec[0], index_map);
transitive_closure(g, tc, g_to_tc_map, index_map);
}
namespace detail
{
template < typename Graph, typename GraphTC, typename G_to_TC_VertexMap,
typename VertexIndexMap>
void transitive_closure_dispatch
(const Graph & g, GraphTC & tc,
G_to_TC_VertexMap g_to_tc_map, VertexIndexMap index_map)
{
typedef typename graph_traits < GraphTC >::vertex_descriptor tc_vertex;
typename std::vector < tc_vertex >::size_type
n = is_default_param(g_to_tc_map) ? num_vertices(g) : 1;
std::vector < tc_vertex > to_tc_vec(n);
transitive_closure
(g, tc,
choose_param(g_to_tc_map, make_iterator_property_map
(to_tc_vec.begin(), index_map, to_tc_vec[0])),
index_map);
}
} // namespace detail
template < typename Graph, typename GraphTC,
typename P, typename T, typename R >
void transitive_closure(const Graph & g, GraphTC & tc,
const bgl_named_params < P, T, R > &params)
{
if (num_vertices(g) == 0)
return;
detail::transitive_closure_dispatch
(g, tc, get_param(params, orig_to_copy_t()),
choose_const_pmap(get_param(params, vertex_index), g, vertex_index) );
}
template < typename G > void warshall_transitive_closure(G & g)
{
typedef typename graph_traits < G >::vertex_descriptor vertex;
typedef typename graph_traits < G >::vertex_iterator vertex_iterator;
function_requires < AdjacencyMatrixConcept < G > >();
function_requires < EdgeMutableGraphConcept < G > >();
// Matrix form:
// for k
// for i
// if A[i,k]
// for j
// A[i,j] = A[i,j] | A[k,j]
vertex_iterator ki, ke, ii, ie, ji, je;
for (tie(ki, ke) = vertices(g); ki != ke; ++ki)
for (tie(ii, ie) = vertices(g); ii != ie; ++ii)
if (edge(*ii, *ki, g).second)
for (tie(ji, je) = vertices(g); ji != je; ++ji)
if (!edge(*ii, *ji, g).second && edge(*ki, *ji, g).second) {
add_edge(*ii, *ji, g);
}
}
template < typename G > void warren_transitive_closure(G & g)
{
using namespace boost;
typedef typename graph_traits < G >::vertex_descriptor vertex;
typedef typename graph_traits < G >::vertex_iterator vertex_iterator;
function_requires < AdjacencyMatrixConcept < G > >();
function_requires < EdgeMutableGraphConcept < G > >();
// Make sure second loop will work
if (num_vertices(g) == 0)
return;
// for i = 2 to n
// for k = 1 to i - 1
// if A[i,k]
// for j = 1 to n
// A[i,j] = A[i,j] | A[k,j]
vertex_iterator ic, ie, jc, je, kc, ke;
for (tie(ic, ie) = vertices(g), ++ic; ic != ie; ++ic)
for (tie(kc, ke) = vertices(g); *kc != *ic; ++kc)
if (edge(*ic, *kc, g).second)
for (tie(jc, je) = vertices(g); jc != je; ++jc)
if (!edge(*ic, *jc, g).second && edge(*kc, *jc, g).second) {
add_edge(*ic, *jc, g);
}
// for i = 1 to n - 1
// for k = i + 1 to n
// if A[i,k]
// for j = 1 to n
// A[i,j] = A[i,j] | A[k,j]
for (tie(ic, ie) = vertices(g), --ie; ic != ie; ++ic)
for (kc = ic, ke = ie, ++kc; kc != ke; ++kc)
if (edge(*ic, *kc, g).second)
for (tie(jc, je) = vertices(g); jc != je; ++jc)
if (!edge(*ic, *jc, g).second && edge(*kc, *jc, g).second) {
add_edge(*ic, *jc, g);
}
}
} // namespace boost
#endif // BOOST_GRAPH_TRANSITIVE_CLOSURE_HPP

View File

@@ -1,56 +0,0 @@
//
//=======================================================================
// Copyright 1997, 1998, 1999, 2000 University of Notre Dame.
// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek
//
// This file is part of the Boost Graph Library
//
// You should have received a copy of the License Agreement for the
// Boost Graph Library along with the software; see the file LICENSE.
// If not, contact Office of Research, University of Notre Dame, Notre
// Dame, IN 46556.
//
// Permission to modify the code and to distribute modified code is
// granted, provided the text of this NOTICE is retained, a notice that
// the code was modified is included with the above COPYRIGHT NOTICE and
// with the COPYRIGHT NOTICE in the LICENSE file, and that the LICENSE
// file is distributed with the modified code.
//
// LICENSOR MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED.
// By way of example, but not limitation, Licensor MAKES NO
// REPRESENTATIONS OR WARRANTIES OF MERCHANTABILITY OR FITNESS FOR ANY
// PARTICULAR PURPOSE OR THAT THE USE OF THE LICENSED SOFTWARE COMPONENTS
// OR DOCUMENTATION WILL NOT INFRINGE ANY PATENTS, COPYRIGHTS, TRADEMARKS
// OR OTHER RIGHTS.
//=======================================================================
//
#ifndef BOOST_GRAPH_TRANSPOSE_HPP
#define BOOST_GRAPH_TRANSPOSE_HPP
#include <boost/config.hpp>
#include <boost/graph/graph_traits.hpp>
#include <boost/graph/reverse_graph.hpp>
#include <boost/graph/copy.hpp>
namespace boost {
template <class VertexListGraph, class MutableGraph>
void transpose_graph(const VertexListGraph& G, MutableGraph& G_T)
{
reverse_graph<VertexListGraph> R(G);
copy_graph(R, G_T);
}
template <class VertexListGraph, class MutableGraph,
class P, class T, class R>
void transpose_graph(const VertexListGraph& G, MutableGraph& G_T,
const bgl_named_params<P, T, R>& params)
{
reverse_graph<VertexListGraph> Rev(G);
copy_graph(Rev, G_T, params);
}
} // namespace boost
#endif // BOOST_GRAPH_TRANSPOSE_HPP

View File

@@ -1,43 +0,0 @@
// (C) Copyright Jeremy Siek 1999.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_TREE_STRUCTURE_HPP
#define BOOST_TREE_STRUCTURE_HPP
namespace boost {
template <class T>
struct tree_traits {
typedef typename T::node_descriptor node_descriptor;
typedef typename T::children_iterator children_iterator;
};
template <class Tree, class TreeVisitor>
void traverse_tree(typename tree_traits<Tree>::node_descriptor v,
Tree& t, TreeVisitor visitor)
{
visitor.preorder(v, t);
typename tree_traits<Tree>::children_iterator i, end;
tie(i, end) = children(v, t);
if (i != end) {
traverse_tree(*i++, t, visitor);
visitor.inorder(v, t);
while (i != end)
traverse_tree(*i++, t, visitor);
} else
visitor.inorder(v, t);
visitor.postorder(v, t);
}
struct null_tree_visitor {
template <typename Node, typename Tree> void preorder(Node, Tree&) { }
template <typename Node, typename Tree> void inorder(Node, Tree&) { }
template <typename Node, typename Tree> void postorder(Node, Tree&) { }
};
} /* namespace boost */
#endif /* BOOST_TREE_STRUCTURE_HPP */

View File

@@ -1,195 +0,0 @@
//
//=======================================================================
// Copyright 1997, 1998, 1999, 2000 University of Notre Dame.
// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek
//
// This file is part of the Boost Graph Library
//
// You should have received a copy of the License Agreement for the
// Boost Graph Library along with the software; see the file LICENSE.
// If not, contact Office of Research, University of Notre Dame, Notre
// Dame, IN 46556.
//
// Permission to modify the code and to distribute modified code is
// granted, provided the text of this NOTICE is retained, a notice that
// the code was modified is included with the above COPYRIGHT NOTICE and
// with the COPYRIGHT NOTICE in the LICENSE file, and that the LICENSE
// file is distributed with the modified code.
//
// LICENSOR MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED.
// By way of example, but not limitation, Licensor MAKES NO
// REPRESENTATIONS OR WARRANTIES OF MERCHANTABILITY OR FITNESS FOR ANY
// PARTICULAR PURPOSE OR THAT THE USE OF THE LICENSED SOFTWARE COMPONENTS
// OR DOCUMENTATION WILL NOT INFRINGE ANY PATENTS, COPYRIGHTS, TRADEMARKS
// OR OTHER RIGHTS.
//=======================================================================
//
#ifndef BOOST_GRAPH_UNDIRECTED_DFS_HPP
#define BOOST_GRAPH_UNDIRECTED_DFS_HPP
#include <boost/graph/depth_first_search.hpp>
namespace boost {
namespace detail {
template <typename IncidenceGraph, typename DFSVisitor,
typename VertexColorMap, typename EdgeColorMap>
void undir_dfv_impl
(const IncidenceGraph& g,
typename graph_traits<IncidenceGraph>::vertex_descriptor u,
DFSVisitor& vis, // pass-by-reference here, important!
VertexColorMap vertex_color,
EdgeColorMap edge_color)
{
function_requires<IncidenceGraphConcept<IncidenceGraph> >();
function_requires<DFSVisitorConcept<DFSVisitor, IncidenceGraph> >();
typedef typename graph_traits<IncidenceGraph>::vertex_descriptor Vertex;
typedef typename graph_traits<IncidenceGraph>::edge_descriptor Edge;
function_requires<ReadWritePropertyMapConcept<VertexColorMap,Vertex> >();
function_requires<ReadWritePropertyMapConcept<EdgeColorMap,Edge> >();
typedef typename property_traits<VertexColorMap>::value_type ColorValue;
typedef typename property_traits<EdgeColorMap>::value_type EColorValue;
function_requires< ColorValueConcept<ColorValue> >();
function_requires< ColorValueConcept<EColorValue> >();
typedef color_traits<ColorValue> Color;
typedef color_traits<EColorValue> EColor;
typename graph_traits<IncidenceGraph>::out_edge_iterator ei, ei_end;
put(vertex_color, u, Color::gray()); vis.discover_vertex(u, g);
for (tie(ei, ei_end) = out_edges(u, g); ei != ei_end; ++ei) {
Vertex v = target(*ei, g); vis.examine_edge(*ei, g);
ColorValue v_color = get(vertex_color, v);
EColorValue uv_color = get(edge_color, *ei);
put(edge_color, *ei, EColor::black());
if (v_color == Color::white()) { vis.tree_edge(*ei, g);
undir_dfv_impl(g, v, vis, vertex_color, edge_color);
} else if (v_color == Color::gray() && uv_color == EColor::white())
vis.back_edge(*ei, g);
}
put(vertex_color, u, Color::black()); vis.finish_vertex(u, g);
}
} // namespace detail
template <typename Graph, typename DFSVisitor,
typename VertexColorMap, typename EdgeColorMap,
typename Vertex>
void
undirected_dfs(const Graph& g, DFSVisitor vis,
VertexColorMap vertex_color, EdgeColorMap edge_color,
Vertex start_vertex)
{
function_requires<DFSVisitorConcept<DFSVisitor, Graph> >();
function_requires<EdgeListGraphConcept<Graph> >();
typedef typename property_traits<VertexColorMap>::value_type ColorValue;
typedef color_traits<ColorValue> Color;
typename graph_traits<Graph>::vertex_iterator ui, ui_end;
for (tie(ui, ui_end) = vertices(g); ui != ui_end; ++ui) {
put(vertex_color, *ui, Color::white()); vis.initialize_vertex(*ui, g);
}
typename graph_traits<Graph>::edge_iterator ei, ei_end;
for (tie(ei, ei_end) = edges(g); ei != ei_end; ++ei)
put(edge_color, *ei, Color::white());
if (start_vertex != *vertices(g).first){ vis.start_vertex(start_vertex, g);
detail::undir_dfv_impl(g, start_vertex, vis, vertex_color, edge_color);
}
for (tie(ui, ui_end) = vertices(g); ui != ui_end; ++ui) {
ColorValue u_color = get(vertex_color, *ui);
if (u_color == Color::white()) { vis.start_vertex(*ui, g);
detail::undir_dfv_impl(g, *ui, vis, vertex_color, edge_color);
}
}
}
template <typename Graph, typename DFSVisitor, typename VertexColorMap,
typename EdgeColorMap>
void
undirected_dfs(const Graph& g, DFSVisitor vis,
VertexColorMap vertex_color, EdgeColorMap edge_color)
{
undirected_dfs(g, vis, vertex_color, edge_color, *vertices(g).first);
}
namespace detail {
template <typename VertexColorMap>
struct udfs_dispatch {
template <typename Graph, typename Vertex,
typename DFSVisitor, typename EdgeColorMap,
typename P, typename T, typename R>
static void
apply(const Graph& g, DFSVisitor vis, Vertex start_vertex,
const bgl_named_params<P, T, R>&,
EdgeColorMap edge_color,
VertexColorMap vertex_color)
{
undirected_dfs(g, vis, vertex_color, edge_color, start_vertex);
}
};
template <>
struct udfs_dispatch<detail::error_property_not_found> {
template <typename Graph, typename Vertex, typename DFSVisitor,
typename EdgeColorMap,
typename P, typename T, typename R>
static void
apply(const Graph& g, DFSVisitor vis, Vertex start_vertex,
const bgl_named_params<P, T, R>& params,
EdgeColorMap edge_color,
detail::error_property_not_found)
{
std::vector<default_color_type> color_vec(num_vertices(g));
default_color_type c = white_color; // avoid warning about un-init
undirected_dfs
(g, vis, make_iterator_property_map
(color_vec.begin(),
choose_const_pmap(get_param(params, vertex_index),
g, vertex_index), c),
edge_color,
start_vertex);
}
};
} // namespace detail
// Named Parameter Variant
template <typename Graph, typename P, typename T, typename R>
void
undirected_dfs(const Graph& g,
const bgl_named_params<P, T, R>& params)
{
typedef typename property_value< bgl_named_params<P, T, R>,
vertex_color_t>::type C;
detail::udfs_dispatch<C>::apply
(g,
choose_param(get_param(params, graph_visitor),
make_dfs_visitor(null_visitor())),
choose_param(get_param(params, root_vertex_t()),
*vertices(g).first),
params,
get_param(params, edge_color),
get_param(params, vertex_color)
);
}
template <typename IncidenceGraph, typename DFSVisitor,
typename VertexColorMap, typename EdgeColorMap>
void undirected_depth_first_visit
(const IncidenceGraph& g,
typename graph_traits<IncidenceGraph>::vertex_descriptor u,
DFSVisitor vis, VertexColorMap vertex_color, EdgeColorMap edge_color)
{
detail::undir_dfv_impl(g, u, vis, vertex_color, edge_color);
}
} // namespace boost
#endif

View File

@@ -1,331 +0,0 @@
//=======================================================================
// Copyright 1997, 1998, 1999, 2000 University of Notre Dame.
// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek
//
// This file is part of the Boost Graph Library
//
// You should have received a copy of the License Agreement for the
// Boost Graph Library along with the software; see the file LICENSE.
// If not, contact Office of Research, University of Notre Dame, Notre
// Dame, IN 46556.
//
// Permission to modify the code and to distribute modified code is
// granted, provided the text of this NOTICE is retained, a notice that
// the code was modified is included with the above COPYRIGHT NOTICE and
// with the COPYRIGHT NOTICE in the LICENSE file, and that the LICENSE
// file is distributed with the modified code.
//
// LICENSOR MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED.
// By way of example, but not limitation, Licensor MAKES NO
// REPRESENTATIONS OR WARRANTIES OF MERCHANTABILITY OR FITNESS FOR ANY
// PARTICULAR PURPOSE OR THAT THE USE OF THE LICENSED SOFTWARE COMPONENTS
// OR DOCUMENTATION WILL NOT INFRINGE ANY PATENTS, COPYRIGHTS, TRADEMARKS
// OR OTHER RIGHTS.
//=======================================================================
// The mutating functions (add_edge, etc.) were added by Vladimir Prus.
// Copyright (C) 2001 Vladimir Prus <ghost@cs.msu.su>
// Permission to copy, use, modify, sell and distribute this software is
// granted, provided this copyright notice appears in all copies and
// modified version are clearly marked as such. This software is provided
// "as is" without express or implied warranty, and with no claim as to its
// suitability for any purpose.
#ifndef BOOST_VECTOR_AS_GRAPH_HPP
#define BOOST_VECTOR_AS_GRAPH_HPP
#include <cassert>
#include <utility>
#include <vector>
#include <cstddef>
#include <boost/iterator.hpp>
#include <boost/graph/graph_traits.hpp>
#include <boost/pending/integer_range.hpp>
#include <algorithm>
/*
This module implements the VertexListGraph concept using a
std::vector as the "back-bone" of the graph (the vector *is* the
graph object). The edge-lists type of the graph is templated, so the
user can choose any STL container, so long as the value_type of the
container is convertible to the size_type of the vector. For now any
graph properties must be stored seperately.
This module requires the C++ compiler to support partial
specialization for the graph_traits class, so this is not portable
to VC++.
*/
#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
#error The vector-as-graph module requires a compiler that supports partial specialization
#endif
namespace boost {
namespace detail {
template <class EdgeList> struct val_out_edge_ret;
template <class EdgeList> struct val_out_edge_iter;
template <class EdgeList> struct val_edge;
}
}
#if !defined BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
namespace boost {
struct vector_as_graph_traversal_tag
: public vertex_list_graph_tag,
public adjacency_graph_tag,
public incidence_graph_tag { };
template <class EdgeList>
struct graph_traits< std::vector<EdgeList> >
{
typedef typename EdgeList::value_type V;
typedef V vertex_descriptor;
typedef typename detail::val_edge<EdgeList>::type edge_descriptor;
typedef typename EdgeList::const_iterator adjacency_iterator;
typedef typename detail::val_out_edge_iter<EdgeList>::type
out_edge_iterator;
typedef void in_edge_iterator;
typedef void edge_iterator;
typedef typename integer_range<V>::iterator vertex_iterator;
typedef directed_tag directed_category;
typedef allow_parallel_edge_tag edge_parallel_category;
typedef vector_as_graph_traversal_tag traversal_category;
typedef typename std::vector<EdgeList>::size_type vertices_size_type;
typedef void edges_size_type;
typedef typename EdgeList::size_type degree_size_type;
};
template <class EdgeList>
struct edge_property_type< std::vector<EdgeList> >
{
typedef void type;
};
template <class EdgeList>
struct vertex_property_type< std::vector<EdgeList> >
{
typedef void type;
};
template <class EdgeList>
struct graph_property_type< std::vector<EdgeList> >
{
typedef void type;
};
}
#endif
namespace boost {
namespace detail {
// "val" is short for Vector Adjacency List
template <class EdgeList>
struct val_edge
{
typedef typename EdgeList::value_type V;
typedef std::pair<V,V> type;
};
// need rewrite this using boost::iterator_adaptor
template <class V, class Iter>
class val_out_edge_iterator
: public boost::iterator<std::input_iterator_tag, std::pair<V,V>,
std::ptrdiff_t, std::pair<V,V>*, const std::pair<V,V> >
{
typedef val_out_edge_iterator self;
typedef std::pair<V,V> Edge;
public:
val_out_edge_iterator() { }
val_out_edge_iterator(V s, Iter i) : _source(s), _iter(i) { }
Edge operator*() const { return Edge(_source, *_iter); }
self& operator++() { ++_iter; return *this; }
self operator++(int) { self t = *this; ++_iter; return t; }
bool operator==(const self& x) const { return _iter == x._iter; }
bool operator!=(const self& x) const { return _iter != x._iter; }
protected:
V _source;
Iter _iter;
};
template <class EdgeList>
struct val_out_edge_iter
{
typedef typename EdgeList::value_type V;
typedef typename EdgeList::const_iterator Iter;
typedef val_out_edge_iterator<V,Iter> type;
};
template <class EdgeList>
struct val_out_edge_ret
{
typedef typename val_out_edge_iter<EdgeList>::type IncIter;
typedef std::pair<IncIter,IncIter> type;
};
} // namesapce detail
template <class EdgeList, class Alloc>
typename detail::val_out_edge_ret<EdgeList>::type
out_edges(typename EdgeList::value_type v,
const std::vector<EdgeList, Alloc>& g)
{
typedef typename detail::val_out_edge_iter<EdgeList>::type Iter;
typedef typename detail::val_out_edge_ret<EdgeList>::type return_type;
return return_type(Iter(v, g[v].begin()), Iter(v, g[v].end()));
}
template <class EdgeList, class Alloc>
typename EdgeList::size_type
out_degree(typename EdgeList::value_type v,
const std::vector<EdgeList, Alloc>& g)
{
return g[v].size();
}
template <class EdgeList, class Alloc>
std::pair<typename EdgeList::const_iterator,
typename EdgeList::const_iterator>
adjacent_vertices(typename EdgeList::value_type v,
const std::vector<EdgeList, Alloc>& g)
{
return std::make_pair(g[v].begin(), g[v].end());
}
// source() and target() already provided for pairs in graph_traits.hpp
template <class EdgeList, class Alloc>
std::pair<typename boost::integer_range<typename EdgeList::value_type>
::iterator,
typename boost::integer_range<typename EdgeList::value_type>
::iterator >
vertices(const std::vector<EdgeList, Alloc>& v)
{
typedef typename boost::integer_range<typename EdgeList::value_type>
::iterator Iter;
return std::make_pair(Iter(0), Iter(v.size()));
}
template <class EdgeList, class Alloc>
typename std::vector<EdgeList, Alloc>::size_type
num_vertices(const std::vector<EdgeList, Alloc>& v)
{
return v.size();
}
template<class EdgeList, class Allocator>
typename std::pair<typename detail::val_edge<EdgeList>::type, bool>
add_edge(typename EdgeList::value_type u, typename EdgeList::value_type v,
std::vector<EdgeList, Allocator>& g)
{
typedef typename detail::val_edge<EdgeList>::type edge_type;
g[u].insert(g[u].end(), v);
return std::make_pair(edge_type(u, v), true);
}
template<class EdgeList, class Allocator>
typename std::pair<typename detail::val_edge<EdgeList>::type, bool>
edge(typename EdgeList::value_type u, typename EdgeList::value_type v,
std::vector<EdgeList, Allocator>& g)
{
typedef typename detail::val_edge<EdgeList>::type edge_type;
typename EdgeList::iterator i = g[u].begin(), end = g[u].end();
for (; i != end; ++i)
if (*i == v)
return std::make_pair(edge_type(u, v), true);
return std::make_pair(edge_type(), false);
}
template<class EdgeList, class Allocator>
void
remove_edge(typename EdgeList::value_type u, typename EdgeList::value_type v,
std::vector<EdgeList, Allocator>& g)
{
typename EdgeList::iterator i = std::remove(g[u].begin(), g[u].end(), v);
if (i != g[u].end())
g[u].erase(i, g[u].end());
}
template<class EdgeList, class Allocator>
void
remove_edge(typename detail::val_edge<EdgeList>::type e,
std::vector<EdgeList, Allocator>& g)
{
typename EdgeList::value_type u, v;
u = e.first;
v = e.second;
// FIXME: edge type does not fully specify the edge to be deleted
typename EdgeList::iterator i = std::remove(g[u].begin(), g[u].end(), v);
if (i != g[u].end())
g[u].erase(i, g[u].end());
}
template<class EdgeList, class Allocator, class Predicate>
void
remove_edge_if(Predicate p,
std::vector<EdgeList, Allocator>& g)
{
for (std::size_t u = 0; u < g.size(); ++u) {
// Oops! gcc gets internal compiler error on compose_.......
typedef typename EdgeList::iterator iterator;
iterator b = g[u].begin(), e = g[u].end();
if (!g[u].empty()) {
for(; b != e;) {
if (p(std::make_pair(u, *b))) {
--e;
if (b == e)
break;
else
iter_swap(b, e);
} else {
++b;
}
}
}
if (e != g[u].end())
g[u].erase(e, g[u].end());
}
}
template<class EdgeList, class Allocator>
typename EdgeList::value_type
add_vertex(std::vector<EdgeList, Allocator>& g)
{
g.resize(g.size()+1);
return g.size()-1;
}
template<class EdgeList, class Allocator>
void
clear_vertex(typename EdgeList::value_type u,
std::vector<EdgeList, Allocator>& g)
{
g[u].clear();
for (std::size_t i = 0; i < g.size(); ++i)
remove_edge(i, u, g);
}
template<class EdgeList, class Allocator>
void
remove_vertex(typename EdgeList::value_type u,
std::vector<EdgeList, Allocator>& g)
{
typedef typename EdgeList::iterator iterator;
clear_vertex(u, g);
g.erase(g.begin() + u);
for (std::size_t i = 0; i < g.size(); ++i)
for ( iterator it = g[i].begin(); it != g[i].end(); ++it )
// after clear_vertex *it is never equal to u
if ( *it > u )
--*it;
}
} // namespace boost
#endif // BOOST_VECTOR_AS_GRAPH_HPP

View File

@@ -1,285 +0,0 @@
//=======================================================================
// Copyright 1997, 1998, 1999, 2000 University of Notre Dame.
// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek
//
// This file is part of the Boost Graph Library
//
// You should have received a copy of the License Agreement for the
// Boost Graph Library along with the software; see the file LICENSE.
// If not, contact Office of Research, University of Notre Dame, Notre
// Dame, IN 46556.
//
// Permission to modify the code and to distribute modified code is
// granted, provided the text of this NOTICE is retained, a notice that
// the code was modified is included with the above COPYRIGHT NOTICE and
// with the COPYRIGHT NOTICE in the LICENSE file, and that the LICENSE
// file is distributed with the modified code.
//
// LICENSOR MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED.
// By way of example, but not limitation, Licensor MAKES NO
// REPRESENTATIONS OR WARRANTIES OF MERCHANTABILITY OR FITNESS FOR ANY
// PARTICULAR PURPOSE OR THAT THE USE OF THE LICENSED SOFTWARE COMPONENTS
// OR DOCUMENTATION WILL NOT INFRINGE ANY PATENTS, COPYRIGHTS, TRADEMARKS
// OR OTHER RIGHTS.
//=======================================================================
//
// Revision History:
// 01 April 2001: Modified to use new <boost/limits.hpp> header. (JMaddock)
//
#ifndef BOOST_GRAPH_GRAPH_SEARCH_VISITORS_HPP
#define BOOST_GRAPH_GRAPH_SEARCH_VISITORS_HPP
#include <iosfwd>
#include <boost/config.hpp>
#include <boost/property_map.hpp>
#include <boost/graph/graph_traits.hpp>
#include <boost/limits.hpp>
#include <boost/graph/detail/is_same.hpp>
namespace boost {
// This is a bit more convenient than std::numeric_limits because
// you don't have to explicitly provide type T.
template <class T>
inline T numeric_limits_max(T) { return (std::numeric_limits<T>::max)(); }
//========================================================================
// Event Tags
namespace detail {
// For partial specialization workaround
enum event_visitor_enum
{ on_no_event_num,
on_initialize_vertex_num, on_start_vertex_num,
on_discover_vertex_num, on_finish_vertex_num, on_examine_vertex_num,
on_examine_edge_num, on_tree_edge_num, on_non_tree_edge_num,
on_gray_target_num, on_black_target_num,
on_forward_or_cross_edge_num, on_back_edge_num,
on_edge_relaxed_num, on_edge_not_relaxed_num,
on_edge_minimized_num, on_edge_not_minimized_num
};
template<typename Event, typename Visitor>
struct functor_to_visitor : Visitor
{
typedef Event event_filter;
functor_to_visitor(const Visitor& visitor) : Visitor(visitor) {}
};
} // namespace detail
struct on_no_event { enum { num = detail::on_no_event_num }; };
struct on_initialize_vertex {
enum { num = detail::on_initialize_vertex_num }; };
struct on_start_vertex { enum { num = detail::on_start_vertex_num }; };
struct on_discover_vertex { enum { num = detail::on_discover_vertex_num }; };
struct on_examine_vertex { enum { num = detail::on_examine_vertex_num }; };
struct on_finish_vertex { enum { num = detail::on_finish_vertex_num }; };
struct on_examine_edge { enum { num = detail::on_examine_edge_num }; };
struct on_tree_edge { enum { num = detail::on_tree_edge_num }; };
struct on_non_tree_edge { enum { num = detail::on_non_tree_edge_num }; };
struct on_gray_target { enum { num = detail::on_gray_target_num }; };
struct on_black_target { enum { num = detail::on_black_target_num }; };
struct on_forward_or_cross_edge {
enum { num = detail::on_forward_or_cross_edge_num }; };
struct on_back_edge { enum { num = detail::on_back_edge_num }; };
struct on_edge_relaxed { enum { num = detail::on_edge_relaxed_num }; };
struct on_edge_not_relaxed {
enum { num = detail::on_edge_not_relaxed_num }; };
struct on_edge_minimized { enum { num = detail::on_edge_minimized_num }; };
struct on_edge_not_minimized {
enum { num = detail::on_edge_not_minimized_num }; };
struct true_tag { enum { num = true }; };
struct false_tag { enum { num = false }; };
//========================================================================
// base_visitor and null_visitor
// needed for MSVC workaround
template <class Visitor>
struct base_visitor {
typedef on_no_event event_filter;
template <class T, class Graph>
void operator()(T, Graph&) { }
};
struct null_visitor : public base_visitor<null_visitor> {
typedef on_no_event event_filter;
template <class T, class Graph>
void operator()(T, Graph&) { }
};
//========================================================================
// The invoke_visitors() function
namespace detail {
template <class Visitor, class T, class Graph>
inline void
invoke_dispatch(Visitor& v, T x, Graph& g, true_tag) {
v(x, g);
}
template <class Visitor, class T, class Graph>
inline void
invoke_dispatch(Visitor&, T, Graph&, false_tag) { }
} // namespace detail
template <class Visitor, class Rest, class T, class Graph, class Tag>
inline void
invoke_visitors(std::pair<Visitor, Rest>& vlist, T x, Graph& g, Tag tag) {
typedef typename Visitor::event_filter Category;
typedef typename graph_detail::is_same<Category, Tag>::is_same_tag
IsSameTag;
detail::invoke_dispatch(vlist.first, x, g, IsSameTag());
invoke_visitors(vlist.second, x, g, tag);
}
#if defined(BOOST_MSVC) && BOOST_MSVC <= 1300
template <class Visitor, class T, class Graph, class Tag>
inline void
invoke_visitors(base_visitor<Visitor>& vis, T x, Graph& g, Tag) {
typedef typename Visitor::event_filter Category;
typedef typename graph_detail::is_same<Category, Tag>::is_same_tag
IsSameTag;
Visitor& v = static_cast<Visitor&>(vis);
detail::invoke_dispatch(v, x, g, IsSameTag());
}
#else
template <class Visitor, class T, class Graph, class Tag>
inline void
invoke_visitors(Visitor& v, T x, Graph& g, Tag) {
typedef typename Visitor::event_filter Category;
typedef typename graph_detail::is_same<Category, Tag>::is_same_tag
IsSameTag;
detail::invoke_dispatch(v, x, g, IsSameTag());
}
#endif
//========================================================================
// predecessor_recorder
template <class PredecessorMap, class Tag>
struct predecessor_recorder
: public base_visitor<predecessor_recorder<PredecessorMap, Tag> >
{
typedef Tag event_filter;
predecessor_recorder(PredecessorMap pa) : m_predecessor(pa) { }
template <class Edge, class Graph>
void operator()(Edge e, const Graph& g) {
put(m_predecessor, target(e, g), source(e, g));
}
PredecessorMap m_predecessor;
};
template <class PredecessorMap, class Tag>
predecessor_recorder<PredecessorMap, Tag>
record_predecessors(PredecessorMap pa, Tag) {
return predecessor_recorder<PredecessorMap, Tag> (pa);
}
//========================================================================
// edge_predecessor_recorder
template <class PredEdgeMap, class Tag>
struct edge_predecessor_recorder
: public base_visitor<edge_predecessor_recorder<PredEdgeMap, Tag> >
{
typedef Tag event_filter;
edge_predecessor_recorder(PredEdgeMap pa) : m_predecessor(pa) { }
template <class Edge, class Graph>
void operator()(Edge e, const Graph& g) {
put(m_predecessor, target(e, g), e);
}
PredEdgeMap m_predecessor;
};
template <class PredEdgeMap, class Tag>
edge_predecessor_recorder<PredEdgeMap, Tag>
record_edge_predecessors(PredEdgeMap pa, Tag) {
return edge_predecessor_recorder<PredEdgeMap, Tag> (pa);
}
//========================================================================
// distance_recorder
template <class DistanceMap, class Tag>
struct distance_recorder
: public base_visitor<distance_recorder<DistanceMap, Tag> >
{
typedef Tag event_filter;
distance_recorder(DistanceMap pa) : m_distance(pa) { }
template <class Edge, class Graph>
void operator()(Edge e, const Graph& g) {
typename graph_traits<Graph>::vertex_descriptor
u = source(e, g), v = target(e, g);
put(m_distance, v, get(m_distance, u) + 1);
}
DistanceMap m_distance;
};
template <class DistanceMap, class Tag>
distance_recorder<DistanceMap, Tag>
record_distances(DistanceMap pa, Tag) {
return distance_recorder<DistanceMap, Tag> (pa);
}
//========================================================================
// time_stamper
template <class TimeMap, class TimeT, class Tag>
struct time_stamper
: public base_visitor<time_stamper<TimeMap, TimeT, Tag> >
{
typedef Tag event_filter;
time_stamper(TimeMap pa, TimeT& t) : m_time_pa(pa), m_time(t) { }
template <class Vertex, class Graph>
void operator()(Vertex u, const Graph&) {
put(m_time_pa, u, ++m_time);
}
TimeMap m_time_pa;
TimeT& m_time;
};
template <class TimeMap, class TimeT, class Tag>
time_stamper<TimeMap, TimeT, Tag>
stamp_times(TimeMap pa, TimeT& time_counter, Tag) {
return time_stamper<TimeMap, TimeT, Tag>(pa, time_counter);
}
//========================================================================
// property_writer
template <class PA, class OutputIterator, class Tag>
struct property_writer
: public base_visitor<property_writer<PA, OutputIterator, Tag> >
{
typedef Tag event_filter;
property_writer(PA pa, OutputIterator out) : m_pa(pa), m_out(out) { }
template <class T, class Graph>
void operator()(T x, Graph&) { *m_out++ = get(m_pa, x); }
PA m_pa;
OutputIterator m_out;
};
template <class PA, class OutputIterator, class Tag>
property_writer<PA, OutputIterator, Tag>
write_property(PA pa, OutputIterator out, Tag) {
return property_writer<PA, OutputIterator, Tag>(pa, out);
}
#define BOOST_GRAPH_EVENT_STUB(Event,Kind) \
typedef ::boost::Event Event##_type; \
template<typename Visitor> \
Kind##_visitor<std::pair<detail::functor_to_visitor<Event##_type, \
Visitor>, Visitors> > \
do_##Event(Visitor visitor) \
{ \
typedef std::pair<detail::functor_to_visitor<Event##_type, Visitor>, \
Visitors> visitor_list; \
typedef Kind##_visitor<visitor_list> result_type; \
return result_type(visitor_list(visitor, m_vis)); \
}
} /* namespace boost */
#endif

View File

@@ -1,151 +0,0 @@
//
//=======================================================================
// Copyright 2002 Marc Wintermantel (wintermantel@imes.mavt.ethz.ch)
// ETH Zurich, Center of Structure Technologies (www.imes.ethz.ch/st)
//
// This file is part of the Boost Graph Library
//
// You should have received a copy of the License Agreement for the
// Boost Graph Library along with the software; see the file LICENSE.
// If not, contact Office of Research, University of Notre Dame, Notre
// Dame, IN 46556.
//
// Permission to modify the code and to distribute modified code is
// granted, provided the text of this NOTICE is retained, a notice that
// the code was modified is included with the above COPYRIGHT NOTICE and
// with the COPYRIGHT NOTICE in the LICENSE file, and that the LICENSE
// file is distributed with the modified code.
//
// LICENSOR MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED.
// By way of example, but not limitation, Licensor MAKES NO
// REPRESENTATIONS OR WARRANTIES OF MERCHANTABILITY OR FITNESS FOR ANY
// PARTICULAR PURPOSE OR THAT THE USE OF THE LICENSED SOFTWARE COMPONENTS
// OR DOCUMENTATION WILL NOT INFRINGE ANY PATENTS, COPYRIGHTS, TRADEMARKS
// OR OTHER RIGHTS.
//=======================================================================
//
#ifndef BOOST_GRAPH_WAVEFRONT_HPP
#define BOOST_GRAPH_WAVEFRONT_HPP
#include <boost/config.hpp>
#include <boost/graph/graph_traits.hpp>
#include <boost/detail/numeric_traits.hpp>
#include <boost/graph/bandwidth.hpp>
#include <cmath>
#include <vector>
#include <algorithm> // for std::min and std::max
namespace boost {
template <typename Graph, typename VertexIndexMap>
typename graph_traits<Graph>::vertices_size_type
ith_wavefront(typename graph_traits<Graph>::vertex_descriptor i,
const Graph& g,
VertexIndexMap index)
{
typename graph_traits<Graph>::vertex_descriptor v, w;
typename graph_traits<Graph>::vertices_size_type b = 1;
typename graph_traits<Graph>::out_edge_iterator edge_it2, edge_it2_end;
typename graph_traits<Graph>::vertices_size_type index_i = index[i];
std::vector<bool> rows_active(num_vertices(g), false);
rows_active[index_i] = true;
typename graph_traits<Graph>::vertex_iterator ui, ui_end;
for (tie(ui, ui_end) = vertices(g); ui != ui_end; ++ui)
{
v = *ui;
if(index[v] <= index_i)
{
for (tie(edge_it2, edge_it2_end) = out_edges(v, g); edge_it2 != edge_it2_end; ++edge_it2)
{
w = target(*edge_it2, g);
if( (index[w] >= index_i) && (!rows_active[index[w]]) )
{
b++;
rows_active[index[w]] = true;
}
}
}
}
return b;
}
template <typename Graph>
typename graph_traits<Graph>::vertices_size_type
ith_wavefront(typename graph_traits<Graph>::vertex_descriptor i,
const Graph& g)
{
return ith_wavefront(i, g, get(vertex_index, g));
}
template <typename Graph, typename VertexIndexMap>
typename graph_traits<Graph>::vertices_size_type
max_wavefront(const Graph& g, VertexIndexMap index)
{
BOOST_USING_STD_MAX();
typename graph_traits<Graph>::vertices_size_type b = 0;
typename graph_traits<Graph>::vertex_iterator i, end;
for (tie(i, end) = vertices(g); i != end; ++i)
b = max BOOST_PREVENT_MACRO_SUBSTITUTION(b, ith_wavefront(*i, g, index));
return b;
}
template <typename Graph>
typename graph_traits<Graph>::vertices_size_type
max_wavefront(const Graph& g)
{
return max_wavefront(g, get(vertex_index, g));
}
template <typename Graph, typename VertexIndexMap>
double
aver_wavefront(const Graph& g, VertexIndexMap index)
{
double b = 0;
typename graph_traits<Graph>::vertex_iterator i, end;
for (tie(i, end) = vertices(g); i != end; ++i)
b += ith_wavefront(*i, g, index);
b /= num_vertices(g);
return b;
}
template <typename Graph>
double
aver_wavefront(const Graph& g)
{
return aver_wavefront(g, get(vertex_index, g));
}
template <typename Graph, typename VertexIndexMap>
double
rms_wavefront(const Graph& g, VertexIndexMap index)
{
double b = 0;
typename graph_traits<Graph>::vertex_iterator i, end;
for (tie(i, end) = vertices(g); i != end; ++i)
b += std::pow(double ( ith_wavefront(*i, g, index) ), 2.0);
b /= num_vertices(g);
return std::sqrt(b);
}
template <typename Graph>
double
rms_wavefront(const Graph& g)
{
return rms_wavefront(g, get(vertex_index, g));
}
} // namespace boost
#endif // BOOST_GRAPH_WAVEFRONT_HPP

View File

@@ -21,8 +21,6 @@ test-suite graph :
[ compile bfs_cc.cpp : <sysinclude>$(BOOST_ROOT) ]
[ run brandes_betweenness_centrality_test.cpp ]
[ run dfs.cpp <lib>../../test/build/boost_test_exec_monitor
: : : <sysinclude>$(BOOST_ROOT) ]
@@ -38,8 +36,6 @@ test-suite graph :
[ compile graph_concepts.cpp : <sysinclude>$(BOOST_ROOT) ]
[ run layout_test.cpp ]
[ compile reverse_graph_cc.cpp : <sysinclude>$(BOOST_ROOT) ]
[ run subgraph.cpp <lib>../../test/build/boost_test_exec_monitor

View File

@@ -1,3 +1,11 @@
// Copyright 2004 The Trustees of Indiana University.
// Use, modification and distribution is subject to the Boost Software
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// Authors: Douglas Gregor
// Andrew Lumsdaine
#include <boost/graph/brandes_betweenness_centrality.hpp>
#include <boost/graph/adjacency_list.hpp>
@@ -6,8 +14,8 @@
#include <queue>
#include <boost/property_map.hpp>
#include <boost/test/minimal.hpp>
#include <stdlib.h>
#include <math.h>
#include <boost/random/uniform_01.hpp>
#include <boost/random/linear_congruential.hpp>
using namespace boost;
@@ -133,7 +141,8 @@ run_unweighted_test(Graph*, int V, unweighted_edge edge_init[], int E,
double relative_error =
correct_centrality[v] == 0.0? centrality[v]
: fabs(centrality[v] - correct_centrality[v]) / correct_centrality[v];
: (centrality[v] - correct_centrality[v]) / correct_centrality[v];
if (relative_error < 0) relative_error = -relative_error;
BOOST_TEST(relative_error < error_tolerance);
}
@@ -144,8 +153,9 @@ run_unweighted_test(Graph*, int V, unweighted_edge edge_init[], int E,
if (correct_edge_centrality) {
double relative_error =
correct_edge_centrality[e] == 0.0? edge_centrality1[e]
: fabs(edge_centrality1[e] - correct_edge_centrality[e])
: (edge_centrality1[e] - correct_edge_centrality[e])
/ correct_edge_centrality[e];
if (relative_error < 0) relative_error = -relative_error;
BOOST_TEST(relative_error < error_tolerance);
if (relative_error >= error_tolerance) {
@@ -219,6 +229,9 @@ void randomly_add_edges(MutableGraph& g, double edge_probability)
const bool is_undirected =
is_same<directed_category, undirected_tag>::value;
minstd_rand gen;
uniform_01<minstd_rand, double> rand_gen(gen);
typedef typename graph_traits<MutableGraph>::vertex_descriptor vertex;
typename graph_traits<MutableGraph>::vertex_iterator vi, vi_end;
for (tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi) {
@@ -228,7 +241,7 @@ void randomly_add_edges(MutableGraph& g, double edge_probability)
while (wi != vi_end) {
vertex w = *wi++;
if (v != w) {
if (drand48() < edge_probability) add_edge(v, w, g);
if (rand_gen() < edge_probability) add_edge(v, w, g);
}
}
}
@@ -459,11 +472,6 @@ int test_main(int, char*[])
run_wheel_test((Graph*)0, 15);
long seed = time(0);
std::cout << "Random seed = " << seed << std::endl;
srand48(seed);
random_unweighted_test((Graph*)0, 500);
return 0;

View File

@@ -112,9 +112,10 @@ struct kamada_kawai_done
bool global)
{
if (global) {
double diff = fabs(last_delta - delta_p);
double diff = last_delta - delta_p;
if (diff < 0) diff = -diff;
last_delta = delta_p;
return fabs(diff) < 0.01;
return diff < 0.01;
} else {
return delta_p < 0.01;
}