|
Boost-Commit : |
From: asutton_at_[hidden]
Date: 2008-06-16 11:01:58
Author: asutton
Date: 2008-06-16 11:01:57 EDT (Mon, 16 Jun 2008)
New Revision: 46426
URL: http://svn.boost.org/trac/boost/changeset/46426
Log:
Implemented an adjacency iterator for undirected graphs.
Added:
sandbox/SOC/2008/graphs/branches/iu/boost/graphs/adjacency_iterator.hpp (contents, props changed)
sandbox/SOC/2008/graphs/branches/iu/boost/graphs/policy.hpp (contents, props changed)
sandbox/SOC/2008/graphs/branches/iu/boost/graphs/traits.hpp (contents, props changed)
Text files modified:
sandbox/SOC/2008/graphs/branches/iu/boost/graphs/incidence_iterator.hpp | 27 ++++++++++--
sandbox/SOC/2008/graphs/branches/iu/boost/graphs/incidence_list.hpp | 32 ++++++++++-----
sandbox/SOC/2008/graphs/branches/iu/boost/graphs/incidence_set.hpp | 16 +++++-
sandbox/SOC/2008/graphs/branches/iu/boost/graphs/undirected_graph.hpp | 82 ++++++++++++++++++++++++++++++++-------
sandbox/SOC/2008/graphs/branches/iu/boost/graphs/vertex.hpp | 17 ++++++++
5 files changed, 139 insertions(+), 35 deletions(-)
Added: sandbox/SOC/2008/graphs/branches/iu/boost/graphs/adjacency_iterator.hpp
==============================================================================
--- (empty file)
+++ sandbox/SOC/2008/graphs/branches/iu/boost/graphs/adjacency_iterator.hpp 2008-06-16 11:01:57 EDT (Mon, 16 Jun 2008)
@@ -0,0 +1,81 @@
+
+#ifndef ADJACENCY_ITERATOR_HPP
+#define ADJACENCY_ITERATOR_HPP
+
+#include <iterator>
+
+/**
+ * The adjacency iterator is an abstraction over incidence iterators (provided
+ * by the incidence store). The adjacency iterator actually provides the same
+ * functionality as the incidence iterator, but simply provides access to the
+ * other vertices rather than the edges.
+ *
+ * @todo Depending on the underlying incidence iterator provided by the graph,
+ * we could actually possibly make this a random access iterator rather than
+ * just a bidirectional iterator. For now, we force it to be a bidi iterator.
+ */
+template <typename Iterator>
+class adjacency_iterator
+{
+ typedef Iterator iterator;
+ typedef typename Iterator::vertex_descriptor vertex_descriptor;
+public:
+
+ typedef std::bidirectional_iterator_tag iterator_category;
+ typedef std::size_t difference_type;
+ typedef vertex_descriptor value_type;
+ typedef vertex_descriptor reference;
+ typedef vertex_descriptor pointer;
+
+ // Constructors
+ inline adjacency_iterator()
+ : _iter()
+ { }
+
+ inline adjacency_iterator(Iterator iter)
+ : _iter(iter)
+ { }
+
+ inline adjacency_iterator& operator=(adjacency_iterator const& x)
+ {
+ _iter = x._iter;
+ return *this;
+ }
+
+ inline adjacency_iterator& operator++()
+ {
+ ++_iter;
+ return *this;
+ }
+
+ inline adjacency_iterator& operator--()
+ {
+ --_iter;
+ return *this;
+ }
+
+ inline bool operator==(adjacency_iterator const& x) const
+ {
+ return _iter == x._iter;
+ }
+
+ inline bool operator!=(adjacency_iterator const& x) const
+ {
+ return _iter != x._iter;
+ }
+
+ reference operator*() const
+ {
+ // Return the opposite vertex referenced by the underlying iterator.
+ // This lets us get away without having to store the source vertex
+ // multiple types in the layered iterator.
+ return _iter.opposite();
+ }
+
+private:
+ iterator _iter;
+};
+
+
+#endif
+
Modified: sandbox/SOC/2008/graphs/branches/iu/boost/graphs/incidence_iterator.hpp
==============================================================================
--- sandbox/SOC/2008/graphs/branches/iu/boost/graphs/incidence_iterator.hpp (original)
+++ sandbox/SOC/2008/graphs/branches/iu/boost/graphs/incidence_iterator.hpp 2008-06-16 11:01:57 EDT (Mon, 16 Jun 2008)
@@ -16,9 +16,10 @@
{
typedef Iter base_iterator;
typedef typename base_iterator::value_type base_value_type;
+public:
typedef typename base_value_type::first_type vertex_descriptor;
typedef typename base_value_type::second_type property_descriptor;
-public:
+
// This is a little misleading. This iterator can be either bidi or random.
// Clearly, we're going to be constraining members using some concept stuff
// when it becomes available.
@@ -47,6 +48,22 @@
: _base(v), _iter(x)
{ }
+ /**
+ * Extended iterator functionality. Return the source vertex of the
+ * iterator. This is the vertex for which the iterator was originally
+ * created.
+ */
+ vertex_descriptor source() const
+ { return _base; }
+
+ /**
+ * Extended iterator functionality. Return the opposite vertex of the
+ * edge indicated by the iterator. This is mostly provided for use by
+ * the adjacency iterator.
+ */
+ vertex_descriptor opposite() const
+ { return _iter->first; }
+
inline incidence_iterator& operator++()
{ ++_iter; return *this; }
@@ -54,18 +71,18 @@
{ --_iter; return *this; }
// Iterators are equivalent if they reference the same edge.
- inline bool operator==(incidence_iterator const& x)
+ inline bool operator==(incidence_iterator const& x) const
{ return **this == *x; }
- inline bool operator!=(incidence_iterator const& x)
+ inline bool operator!=(incidence_iterator const& x) const
{ return !this->operator==(x); }
inline reference operator*() const
{ return reference(_base, _iter->first, _iter->second); }
private:
- vertex_descriptor _base;
- base_iterator _iter;
+ vertex_descriptor _base;
+ base_iterator _iter;
};
Modified: sandbox/SOC/2008/graphs/branches/iu/boost/graphs/incidence_list.hpp
==============================================================================
--- sandbox/SOC/2008/graphs/branches/iu/boost/graphs/incidence_list.hpp (original)
+++ sandbox/SOC/2008/graphs/branches/iu/boost/graphs/incidence_list.hpp 2008-06-16 11:01:57 EDT (Mon, 16 Jun 2008)
@@ -35,12 +35,10 @@
inline iterator find(incidence_pair);
inline const_iterator find(incidence_pair) const;
+ inline void clear();
inline void remove(incidence_pair);
template <typename Eraser> inline void remove(vertex_descriptor, Eraser);
- inline void clear();
-
-
inline size_type size() const
{ return _edges.size(); }
@@ -63,6 +61,20 @@
{ }
/**
+ * Incidence lists always allow the addition of edges, assuming that no policy
+ * conflicts exist. The first element of the return is the end() of the list.
+ *
+ * @complexity O(1)
+ */
+template <BOOST_GRAPH_IL_PARAMS>
+std::pair<typename incidence_list<E,A>::const_iterator, bool>
+incidence_list<E,A>::allow(vertex_descriptor v) const
+{
+ // Since there's no policy, there we must be able to add the edge.
+ return make_pair(_edges.end(), true);
+}
+
+/**
* Add the incident edge to the incidence set.
*
* @complexity O(1)
@@ -75,17 +87,15 @@
}
/**
- * Incidence lists always allow the addition of edges, assuming that no policy
- * conflicts exist. The first element of the return is the end() of the list.
+ * Remove all incident edges from this set.
*
- * @complexity O(1)
+ * @complexity O(d)
*/
-template <BOOST_GRAPH_IL_PARAMS>
-std::pair<typename incidence_list<E,A>::const_iterator, bool>
-incidence_list<E,A>::allow(vertex_descriptor v) const
+template <typename E, typename A>
+void
+incidence_list<E,A>::clear()
{
- // Since there's no policy, there we must be able to add the edge.
- return make_pair(_edges.end(), true);
+ _edges.clear();
}
/**
Modified: sandbox/SOC/2008/graphs/branches/iu/boost/graphs/incidence_set.hpp
==============================================================================
--- sandbox/SOC/2008/graphs/branches/iu/boost/graphs/incidence_set.hpp (original)
+++ sandbox/SOC/2008/graphs/branches/iu/boost/graphs/incidence_set.hpp 2008-06-16 11:01:57 EDT (Mon, 16 Jun 2008)
@@ -43,13 +43,11 @@
inline iterator find(incidence_pair);
inline const_iterator find(incidence_pair) const;
- // Remove the edge.
+ // Remove edges.
+ inline void clear();
inline void remove(incidence_pair);
template <typename Eraser> inline void remove(vertex_descriptor, Eraser);
- // Remove all edges.
- inline void clear();
-
inline size_type size() const
{ return _edges.size(); }
@@ -105,6 +103,16 @@
}
/**
+ * Remove all incident edges from this edge set.
+ */
+template <typename E, typename C, typename A>
+void
+incidence_set<E,C,A>::clear()
+{
+ _edges.clear();
+}
+
+/**
* Remove the incidence pair from the set.
*
* @complexity O(lg(d))
Added: sandbox/SOC/2008/graphs/branches/iu/boost/graphs/policy.hpp
==============================================================================
--- (empty file)
+++ sandbox/SOC/2008/graphs/branches/iu/boost/graphs/policy.hpp 2008-06-16 11:01:57 EDT (Mon, 16 Jun 2008)
@@ -0,0 +1,5 @@
+
+#ifndef POLICY_HPP
+#define POLICY_HPP
+
+#endif
Added: sandbox/SOC/2008/graphs/branches/iu/boost/graphs/traits.hpp
==============================================================================
--- (empty file)
+++ sandbox/SOC/2008/graphs/branches/iu/boost/graphs/traits.hpp 2008-06-16 11:01:57 EDT (Mon, 16 Jun 2008)
@@ -0,0 +1,34 @@
+
+#ifndef TRAITS_HPP
+#define TRAITS_HPP
+
+namespace detail
+{
+ // This isn't quite so simple as it seems. I think we need to have the
+ // catch-all push the query back to a policy object and that policy needs
+ // to be explicit about whether or not it allows multiple edges.
+ template <typename Store>
+ struct is_simple
+ { enum { value = false }; };
+
+ template <typename E, typename C, typename A>
+ struct is_simple< incidence_set<E,C,A> >
+ { enum { value = true }; };
+
+};
+
+/**
+ * This metafunction determines if the graph allows multiple edges.
+ */
+template <typename Graph>
+struct is_simple
+{ enum { value = detail::is_simple<typename Graph::incidence_store>::value }; };
+
+/**
+ * A helper function for the above.
+ */
+template <typename Graph>
+bool is_simple_graph(const Graph& g)
+{ return is_simple<Graph>::value; }
+
+#endif
Modified: sandbox/SOC/2008/graphs/branches/iu/boost/graphs/undirected_graph.hpp
==============================================================================
--- sandbox/SOC/2008/graphs/branches/iu/boost/graphs/undirected_graph.hpp (original)
+++ sandbox/SOC/2008/graphs/branches/iu/boost/graphs/undirected_graph.hpp 2008-06-16 11:01:57 EDT (Mon, 16 Jun 2008)
@@ -30,6 +30,8 @@
#include "edge_list.hpp"
#include "edge_set.hpp"
+#include "adjacency_iterator.hpp"
+
template <
typename VertexProps,
typename EdgeProps,
@@ -68,6 +70,9 @@
typedef incidence_iterator<typename vertex_type::iterator> incident_edge_iterator;
typedef std::pair<incident_edge_iterator, incident_edge_iterator> incident_edge_range;
+ typedef adjacency_iterator<incident_edge_iterator> adjacent_vertex_iterator;
+ typedef std::pair<adjacent_vertex_iterator, adjacent_vertex_iterator> adjacent_vertex_range;
+
// The vertex store and related properties can also be built on the vertex
// type.
typedef typename VertexStore::template store<vertex_type>::type vertex_store;
@@ -87,53 +92,63 @@
// Constructors
undirected_graph();
- // Add vertices
+ /** @name Vertex Set
+ * These functions operate (mostly) on the vertices of the graph. These
+ * functions include the ability to add, disconnect, and remove vertices.
+ */
+ //@{
vertex_descriptor add_vertex();
vertex_descriptor add_vertex(vertex_properties const&);
vertex_descriptor add_vertex(key_type const&, vertex_properties const&);
-
- // Disconnect and Remove vertices
void disconnect_vertex(vertex_descriptor);
void remove_vertex(vertex_descriptor);
+ //@{
- // Add edges
+ /** @name Edge Set
+ * These functions operate on the edges of the graph. This functions
+ * include the ability to add and remove edges.
+ */
+ //@{
edge_descriptor add_edge(vertex_descriptor, vertex_descriptor);
edge_descriptor add_edge(vertex_descriptor, vertex_descriptor, edge_properties const&);
-
void remove_edge(edge_descriptor);
void remove_edges(vertex_descriptor, vertex_descriptor);
+ //@}
/** @name Vertex Iteration
- * These functions allow the iteration over the vertex set.
+ * These functions allow iteration over the vertex set.
*/
//@{
vertex_range vertices() const;
vertex_iterator begin_vertices() const;
vertex_iterator end_vertices() const;
+ vertices_size_type num_vertices() const;
//@}
/** @name Edge Iteration
- * These function allow the iteration over the edge set.
+ * These function allow iteration over the edge set.
*/
//@{
edge_range edges() const;
edge_iterator begin_edges() const;
edge_iterator end_edges() const;
+ edges_size_type num_edges() const;
//@}
- /** @name Graph Size
- * These functions return the number of vertices and edges in the graph.
+ /** @name Incident Edge Iteration
+ * These functions allow iteration over the incident edges of a vertex.
*/
//@{
- vertices_size_type num_vertices() const;
- edges_size_type num_edges() const;
- //@}
-
- // Edge incidence
incident_edge_iterator begin_incident_edges(vertex_descriptor) const;
incident_edge_iterator end_incident_edges(vertex_descriptor) const;
incident_edge_range incident_edges(vertex_descriptor) const;
+
+ adjacent_vertex_iterator begin_adjacent_vertices(vertex_descriptor) const;
+ adjacent_vertex_iterator end_adjacent_vertices(vertex_descriptor) const;
+ adjacent_vertex_range adjacent_vertices(vertex_descriptor) const;
+
incident_edges_size_type degree(vertex_descriptor) const;
+ //@{
// Property accesors
vertex_properties& operator[](vertex_descriptor);
@@ -192,6 +207,11 @@
// Remove all the properties too. Does this make sense here?
_props.remove(e.properties());
}
+
+ // Clear the incident edge set of the vertex. We don't do this in the
+ // previous loop because we'll probably end up invalidating our own
+ // iterators.
+ _verts.vertex(v).disconnect();
}
/**
@@ -284,7 +304,6 @@
src.disconnect(v, p);
tgt.disconnect(u, p);
- std::cout << "removing properties: " << _props.properties(p) << std::endl;
_props.remove(p);
}
@@ -393,6 +412,37 @@
}
/**
+ * Return an iterator to the first adjacent vertex of the the given vertex.
+ */
+template <BOOST_GRAPH_UG_PARAMS>
+typename undirected_graph<VP,EP,VS,ES>::adjacent_vertex_iterator
+undirected_graph<VP,EP,VS,ES>::begin_adjacent_vertices(vertex_descriptor v) const
+{
+ return begin_incident_edges(v);
+}
+
+/**
+ * Return an iterator past the end of the adjacent vertices of the given vertex.
+ */
+template <BOOST_GRAPH_UG_PARAMS>
+typename undirected_graph<VP,EP,VS,ES>::adjacent_vertex_iterator
+undirected_graph<VP,EP,VS,ES>::end_adjacent_vertices(vertex_descriptor v) const
+{
+ return end_incident_edges(v);
+}
+
+/**
+ * Return an iterator range over the adjacent vertices of the given vertex.
+ */
+template <BOOST_GRAPH_UG_PARAMS>
+typename undirected_graph<VP,EP,VS,ES>::adjacent_vertex_range
+undirected_graph<VP,EP,VS,ES>::adjacent_vertices(vertex_descriptor v) const
+{
+ return std::make_pair(begin_adjacent_vertices(v), end_adjacent_vertices(v));
+}
+
+
+/**
* Return the degree (number of incdent edges) of the given vertex.
*/
template <BOOST_GRAPH_UG_PARAMS>
@@ -424,5 +474,7 @@
#undef BOOST_GRAPH_UG_PARAMS
+#include "traits.hpp"
+
#endif
Modified: sandbox/SOC/2008/graphs/branches/iu/boost/graphs/vertex.hpp
==============================================================================
--- sandbox/SOC/2008/graphs/branches/iu/boost/graphs/vertex.hpp (original)
+++ sandbox/SOC/2008/graphs/branches/iu/boost/graphs/vertex.hpp 2008-06-16 11:01:57 EDT (Mon, 16 Jun 2008)
@@ -27,8 +27,14 @@
inline vertex();
inline vertex(vertex_properties const& vp);
+ /** @name Edge Connection and Disconnection
+ * These functions control how edges are added to and removed from the
+ * vertex. The allow() function determines whether or not the edge
+ * connection is allowed and/or already existing.
+ */
inline std::pair<iterator, bool> allow(vertex_descriptor) const;
inline void connect(vertex_descriptor, property_descriptor);
+ inline void disconnect();
inline void disconnect(vertex_descriptor, property_descriptor);
template <typename Eraser> inline void disconnect(vertex_descriptor, Eraser);
@@ -90,6 +96,17 @@
}
/**
+ * Disconect all edges from this vertex. This does not remove the connection
+ * from adjacent vertices to this vertex.
+ */
+template <typename VP, typename IS>
+void
+vertex<VP,IS>::disconnect()
+{
+ _edges.clear();
+}
+
+/**
* Disconnect the incidedent edge given by the vertex v with edge properties p.
*/
template <typename VP, typename IS>
Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk