mirror of
https://github.com/boostorg/graph.git
synced 2026-01-19 04:12:11 +00:00
Join ralf_grosse_kunstleve with HEAD
[SVN r9444]
This commit is contained in:
@@ -55,6 +55,40 @@ namespace boost {
|
||||
typename graph_traits<Graph>::vertex_descriptor u;
|
||||
typename graph_traits<Graph>::edge_descriptor e;
|
||||
};
|
||||
|
||||
namespace detail {
|
||||
|
||||
template <class IncidenceGraph, class DFSVisitor, class ColorMap>
|
||||
void internal_depth_first_visit
|
||||
(const IncidenceGraph& g,
|
||||
typename graph_traits<IncidenceGraph>::vertex_descriptor u,
|
||||
DFSVisitor& vis, // pass-by-reference here, important!
|
||||
ColorMap color)
|
||||
{
|
||||
function_requires<IncidenceGraphConcept<IncidenceGraph> >();
|
||||
function_requires<DFSVisitorConcept<DFSVisitor, IncidenceGraph> >();
|
||||
typedef typename property_traits<ColorMap>::value_type ColorValue;
|
||||
function_requires< ColorValueConcept<ColorValue> >();
|
||||
typedef color_traits<ColorValue> Color;
|
||||
|
||||
put(color, u, Color::gray());
|
||||
vis.discover_vertex(u, g);
|
||||
typename graph_traits<IncidenceGraph>::out_edge_iterator ei, ei_end;
|
||||
for (tie(ei, ei_end) = out_edges(u, g); ei != ei_end; ++ei) {
|
||||
vis.examine_edge(*ei, g);
|
||||
if (get(color, target(*ei, g)) == Color::white()) {
|
||||
vis.tree_edge(*ei, g);
|
||||
internal_depth_first_visit(g, target(*ei, g), vis, color);
|
||||
} else if (get(color, target(*ei, g)) == 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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Variant (1)
|
||||
template <class Graph, class DFSVisitor>
|
||||
@@ -68,48 +102,31 @@ namespace boost {
|
||||
// Variant (2)
|
||||
template <class VertexListGraph, class DFSVisitor, class ColorMap>
|
||||
void
|
||||
depth_first_search(VertexListGraph& g, DFSVisitor vis, ColorMap color)
|
||||
depth_first_search(const VertexListGraph& g, DFSVisitor vis, ColorMap color)
|
||||
{
|
||||
function_requires<DFSVisitorConcept<DFSVisitor, VertexListGraph> >();
|
||||
typename property_traits<ColorMap>::value_type
|
||||
c = get(color, *vertices(g).first); // value of c not used, just type
|
||||
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, white(c));
|
||||
put(color, *ui, Color::white());
|
||||
vis.initialize_vertex(*ui, g);
|
||||
}
|
||||
for (tie(ui, ui_end) = vertices(g); ui != ui_end; ++ui)
|
||||
if (get(color, *ui) == white(c)) {
|
||||
if (get(color, *ui) == Color::white()) {
|
||||
vis.start_vertex(*ui, g);
|
||||
depth_first_visit(g, *ui, vis, color);
|
||||
detail::internal_depth_first_visit(g, *ui, vis, color);
|
||||
}
|
||||
}
|
||||
|
||||
template <class IncidenceGraph, class DFSVisitor, class ColorMap>
|
||||
void depth_first_visit(IncidenceGraph& g,
|
||||
typename graph_traits<IncidenceGraph>::vertex_descriptor u,
|
||||
DFSVisitor& vis, ColorMap color)
|
||||
void depth_first_visit
|
||||
(const IncidenceGraph& g,
|
||||
typename graph_traits<IncidenceGraph>::vertex_descriptor u,
|
||||
DFSVisitor vis, ColorMap color)
|
||||
{
|
||||
function_requires<IncidenceGraphConcept<IncidenceGraph> >();
|
||||
function_requires<DFSVisitorConcept<DFSVisitor, IncidenceGraph> >();
|
||||
typename property_traits<ColorMap>::value_type c = get(color, u);
|
||||
|
||||
put(color, u, gray(c));
|
||||
vis.discover_vertex(u, g);
|
||||
typename graph_traits<IncidenceGraph>::out_edge_iterator ei, ei_end;
|
||||
for (tie(ei, ei_end) = out_edges(u, g); ei != ei_end; ++ei) {
|
||||
vis.examine_edge(*ei, g);
|
||||
if (get(color, target(*ei, g)) == white(c)) {
|
||||
vis.tree_edge(*ei, g);
|
||||
depth_first_visit(g, target(*ei, g), vis, color);
|
||||
} else if (get(color, target(*ei, g)) == gray(c))
|
||||
vis.back_edge(*ei, g);
|
||||
else
|
||||
vis.forward_or_cross_edge(*ei, g);
|
||||
}
|
||||
put(color, u, black(c));
|
||||
vis.finish_vertex(u, g);
|
||||
detail::internal_depth_first_visit(g, u, vis, color);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <iosfwd>
|
||||
#include <algorithm>
|
||||
#include <assert.h>
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/utility.hpp>
|
||||
@@ -38,6 +39,7 @@
|
||||
#include <boost/graph/graph_traits.hpp>
|
||||
#include <boost/graph/properties.hpp>
|
||||
#include <boost/pending/container_traits.hpp>
|
||||
#include <boost/graph/depth_first_search.hpp>
|
||||
|
||||
namespace boost {
|
||||
|
||||
@@ -199,6 +201,30 @@ namespace boost {
|
||||
return *i;
|
||||
}
|
||||
|
||||
template <typename MutableGraph>
|
||||
void generate_random_graph
|
||||
(MutableGraph& g,
|
||||
typename graph_traits<MutableGraph>::vertices_size_type V,
|
||||
typename graph_traits<MutableGraph>::vertices_size_type E,
|
||||
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;
|
||||
|
||||
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), b;
|
||||
do {
|
||||
b = random_vertex(g);
|
||||
} while (self_edges == false && a == b);
|
||||
add_edge(a, b, g);
|
||||
}
|
||||
}
|
||||
|
||||
template <class Graph, class Vertex>
|
||||
bool is_adj_dispatch(Graph& g, Vertex a, Vertex b, bidirectional_tag)
|
||||
{
|
||||
@@ -232,19 +258,39 @@ namespace boost {
|
||||
{
|
||||
typedef typename graph_traits<Graph>::edge_descriptor
|
||||
edge_descriptor;
|
||||
typename Graph::adjacency_iterator vi, viend, found;
|
||||
typename graph_traits<Graph>::adjacency_iterator vi, viend, found;
|
||||
boost::tie(vi, viend) = adjacent_vertices(a, g);
|
||||
#if defined(BOOST_MSVC) && 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;
|
||||
return false;
|
||||
|
||||
typename graph_traits<Graph>::out_edge_iterator oi, oiend,
|
||||
out_found;
|
||||
boost::tie(oi, oiend) = out_edges(a, g);
|
||||
|
||||
#if defined(BOOST_MSVC) && defined(__SGI_STL_PORT)
|
||||
// Getting internal compiler error with std::find()
|
||||
out_found = oiend;
|
||||
for (; oi != oiend; ++oi)
|
||||
if (*oi == edge_descriptor(a,b)) {
|
||||
out_found = oi;
|
||||
break;
|
||||
}
|
||||
#else
|
||||
out_found = std::find(oi, oiend, edge_descriptor(a,b));
|
||||
#endif
|
||||
if (out_found == oiend)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
template <class Graph, class Vertex>
|
||||
@@ -287,6 +333,64 @@ namespace boost {
|
||||
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)
|
||||
|
||||
@@ -49,7 +49,7 @@ namespace boost {
|
||||
{ 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_cycle_edge_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,
|
||||
@@ -68,7 +68,7 @@ namespace boost {
|
||||
|
||||
struct on_examine_edge { enum { num = detail::on_examine_edge_num }; };
|
||||
struct on_tree_edge { enum { num = detail::on_tree_edge_num }; };
|
||||
struct on_cycle_edge { enum { num = detail::on_cycle_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 {
|
||||
|
||||
Reference in New Issue
Block a user