Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r50017 - in sandbox/SOC/2008/graphs/trunk/libs/graphs: include/boost/graphs/adjacency_list include/boost/graphs/adjacency_list/es include/boost/graphs/adjacency_list/incs include/boost/graphs/adjacency_list/vs test
From: asutton_at_[hidden]
Date: 2008-11-29 12:09:12


Author: asutton
Date: 2008-11-29 12:09:11 EST (Sat, 29 Nov 2008)
New Revision: 50017
URL: http://svn.boost.org/trac/boost/changeset/50017

Log:
- Removed the possibility of creating an actual edge set. The global edge list
  for undirected graph only needs to be lists or vectors. Removed all overloads
  and specializations related to it.
- Implemented the edge() function for incidence sets.
- Need to back out the implementation of add_edge() and make it more efficient
  for graphs w/ unique edges (simple graphs).

Removed:
   sandbox/SOC/2008/graphs/trunk/libs/graphs/include/boost/graphs/adjacency_list/es/set.hpp
Text files modified:
   sandbox/SOC/2008/graphs/trunk/libs/graphs/include/boost/graphs/adjacency_list/edge_store.hpp | 65 +--------------------------------------
   sandbox/SOC/2008/graphs/trunk/libs/graphs/include/boost/graphs/adjacency_list/incidence_store.hpp | 64 ++++++++++++++++++++++++++++++++++++--
   sandbox/SOC/2008/graphs/trunk/libs/graphs/include/boost/graphs/adjacency_list/incs/list.hpp | 7 ++-
   sandbox/SOC/2008/graphs/trunk/libs/graphs/include/boost/graphs/adjacency_list/incs/set.hpp | 12 ++++---
   sandbox/SOC/2008/graphs/trunk/libs/graphs/include/boost/graphs/adjacency_list/incs/vector.hpp | 7 ++-
   sandbox/SOC/2008/graphs/trunk/libs/graphs/include/boost/graphs/adjacency_list/undirected_graph.hpp | 59 ++++++++++++++++++++++++++++++++++-
   sandbox/SOC/2008/graphs/trunk/libs/graphs/include/boost/graphs/adjacency_list/vs/set.hpp | 2
   sandbox/SOC/2008/graphs/trunk/libs/graphs/test/undirected.cpp | 17 ++++++----
   8 files changed, 145 insertions(+), 88 deletions(-)

Modified: sandbox/SOC/2008/graphs/trunk/libs/graphs/include/boost/graphs/adjacency_list/edge_store.hpp
==============================================================================
--- sandbox/SOC/2008/graphs/trunk/libs/graphs/include/boost/graphs/adjacency_list/edge_store.hpp (original)
+++ sandbox/SOC/2008/graphs/trunk/libs/graphs/include/boost/graphs/adjacency_list/edge_store.hpp 2008-11-29 12:09:11 EST (Sat, 29 Nov 2008)
@@ -13,7 +13,6 @@
 
 #include <boost/graphs/adjacency_list/es/vector.hpp>
 #include <boost/graphs/adjacency_list/es/list.hpp>
-#include <boost/graphs/adjacency_list/es/set.hpp>
 
 // The edge store interface defines generic operations on an edge store for
 // undirected graphs.
@@ -42,31 +41,6 @@
 { return edge.second; }
 //@}
 
-/** @name Label Traits [edge_set] */
-//@{
-template <typename Vertex, typename Label>
-struct label_traits<std::pair<std::pair<Vertex, Vertex> const, Label>>
-{
- typedef Label label_type;
-};
-
-template <typename Vertex, typename Label>
-inline Label&
-label(std::pair<std::pair<Vertex, Vertex> const, Label>& edge)
-{ return edge.second; }
-
-template <typename Vertex, typename Label>
-inline Label const&
-label(std::pair<std::pair<Vertex, Vertex> const, Label> const& edge)
-{ return edge.second; }
-//@}
-
-// NOTE: The difference between the specialization of edge traits over the
-// edge types is quite subtle. Compare:
-// std::pair<std::pair<Vertex, Vertex>, Label> <- Vector and List
-// std::pair<std::pair<Vertex, Vertex> const, Label> <- Set
-// Even worse, there's no functional difference between then.
-
 /** @name Edge Traits [edge_vector, edge_list] */
 //@{
 template <typename Vertex, typename Label>
@@ -97,36 +71,6 @@
 { return which == first(edge) ? second(edge) : first(edge); }
 //@}
 
-/** @name Edge Traits [edge_set] */
-//@{
-template <typename Vertex, typename Label>
-struct edge_traits<std::pair<std::pair<Vertex, Vertex> const, Label>>
-{
- typedef Vertex vertex_descriptor;
- typedef std::pair<Vertex, Vertex> edge_ends;
-};
-
-template <typename Vertex, typename Label>
-inline std::pair<Vertex, Vertex>
-ends(std::pair<std::pair<Vertex, Vertex> const, Label> const& edge)
-{ return edge.first; }
-
-template <typename Vertex, typename Label>
-inline Vertex
-first(std::pair<std::pair<Vertex, Vertex> const, Label> const& edge)
-{ return edge.first.first; }
-
-template <typename Vertex, typename Label>
-inline Vertex
-second(std::pair<std::pair<Vertex, Vertex> const, Label> const& edge)
-{ return edge.first.second; }
-
-template <typename Vertex, typename Label>
-inline Vertex
-oppposite(std::pair<std::pair<Vertex, Vertex> const, Label> const& edge, Vertex which)
-{ return which == first(edge) ? second(edge) : first(edge); }
-//@}
-
 namespace adjacency_list {
 
 template <typename Store>
@@ -218,13 +162,10 @@
  * such edge found.
  */
 //@{
-template <typename Store, typename Ends>
-inline typename descriptor_traits<Store>::descriptor_type
-find(Store& store, Ends e)
+template <typename Store, typename Vertex>
+inline typename edge_store_traits<Store>::edge_descriptor
+find(Store& store, Vertex u, Vertex v)
 {
- // Search the incidene list of the smaller vertex for an edge who's endpoint
- // is given as the other.
- // if(ies::size(e.first) < ies::size(e.second)
 }
 
 template <typename Store, typename Ends>

Deleted: sandbox/SOC/2008/graphs/trunk/libs/graphs/include/boost/graphs/adjacency_list/es/set.hpp
==============================================================================
--- sandbox/SOC/2008/graphs/trunk/libs/graphs/include/boost/graphs/adjacency_list/es/set.hpp 2008-11-29 12:09:11 EST (Sat, 29 Nov 2008)
+++ (empty file)
@@ -1,42 +0,0 @@
-
-#ifndef BOOST_GRAPHS_ADJLIST_ES_SET_HPP
-#define BOOST_GRAPHS_ADJLIST_ES_SET_HPP
-
-#include <map>
-
-#include <boost/graphs/edge.hpp>
-
-namespace boost { namespace graphs { namespace adjacency_list {
-
-
-/**
- * @param Compare A unary template class that compares the ends of edges. The
- * argument type for this function is Pair<VertexDesc, VertexDesc>.
- * @param Alloc A unary template class that allocates edges.
- */
-template <
- template <typename> class Compare = std::less,
- template <typename> class Alloc = std::allocator>
-struct edge_set
-{
- typedef typename descriptor_traits<
- std::set<int, Compare<int>, Alloc<int>>,
- edge_descriptor_kind
- >::descriptor_type edge_descriptor;
-
- // This quietly implements a map, not a set because we'll be using the
- // endpoints as keys to the label.
- template <typename Vertex, typename Label>
- struct store
- {
- typedef std::pair<Vertex, Vertex> ends;
- typedef Compare<ends> compare;
- typedef Alloc<std::pair<ends, Label>> allocator;
- public:
- typedef std::map<ends, Label, compare, allocator> type;
- };
-};
-
-} } } /* namespace boost::graphs::adjacency_list */
-
-#endif

Modified: sandbox/SOC/2008/graphs/trunk/libs/graphs/include/boost/graphs/adjacency_list/incidence_store.hpp
==============================================================================
--- sandbox/SOC/2008/graphs/trunk/libs/graphs/include/boost/graphs/adjacency_list/incidence_store.hpp (original)
+++ sandbox/SOC/2008/graphs/trunk/libs/graphs/include/boost/graphs/adjacency_list/incidence_store.hpp 2008-11-29 12:09:11 EST (Sat, 29 Nov 2008)
@@ -3,6 +3,7 @@
 #define BOOST_GRAPHS_ADJLIST_INCIDENCE_STORE_HPP
 
 #include <vector>
+#include <algorithm>
 
 // Pull all of the incidence list type selectors
 #include <boost/graphs/adjacency_list/incs/vector.hpp>
@@ -23,15 +24,70 @@
 struct incidence_store_traits
 {
     typedef typename Store::size_type incident_edges_size_type;
+
+ // All incidence stores record a pair of descriptors (an adjacenct vertex
+ // and an incident edge). We can extract these...
+ typedef typename Store::value_type ai_pair;
+ typedef typename ai_pair::first_type vertex_descriptor;
+ typedef typename ai_pair::second_type edge_descriptor;
 };
 
 namespace incs {
 
+namespace detail {
+
+ template <typename Vertex>
+ struct first_vertex_finder
+ {
+ Vertex v;
+
+ first_vertex_finder(Vertex v) : v(v) { }
+
+ template <typename Pair>
+ bool operator()(Pair const& x) const
+ { return x.first == v; }
+ };
+
+ template <typename Vertex>
+ inline first_vertex_finder<Vertex> first_vertex(Vertex v)
+ { return first_vertex_finder<Vertex>(v); }
+
+ template <typename Store, typename Vertex>
+ inline typename Store::iterator
+ dispatch_find(Store& store, Vertex v, sequence_tag)
+ { return std::find_if(store.begin(), store.end(), first_vertex(v)); }
+
+ template <typename Store, typename Vertex>
+ inline typename Store::iterator
+ dispatch_find(Store& store, Vertex v, associative_container_tag)
+ { return store.find(v); }
+
+} /* namespace detail */
+
 /** Insert an edge descriptor into the incidence store of the vertex. */
-template <typename Store, typename Edge>
-typename Store::iterator
-insert(Store& store, Edge e)
-{ return container_insert(store, e); }
+template <typename Store>
+inline typename Store::iterator
+insert(Store& store,
+ typename incidence_store_traits<Store>::vertex_descriptor v,
+ typename incidence_store_traits<Store>::edge_descriptor e)
+{ return container_insert(store, std::make_pair(v, e)); }
+
+/** @name Edge Object
+ * Return the incident edge descriptor corresponding to the adjacent vertex.
+ */
+template <typename Store>
+inline typename incidence_store_traits<Store>::edge_descriptor
+find(Store& store, typename incidence_store_traits<Store>::vertex_descriptor v)
+{
+ typedef typename incidence_store_traits<Store>::edge_descriptor Edge;
+ typename Store::iterator i = detail::dispatch_find(store, v, container_category(store));
+ return i != store.end() ? i->second : Edge();
+}
+
+template <typename Store>
+inline typename incidence_store_traits<Store>::edge_descriptor
+find(Store const& store, typename incidence_store_traits<Store>::vertex_descriptor v)
+{ return find(const_cast<Store&>(store), v); }
 
 /** Return the size of an adjacency list for the given vertex, its degree. */
 template <typename Store>

Modified: sandbox/SOC/2008/graphs/trunk/libs/graphs/include/boost/graphs/adjacency_list/incs/list.hpp
==============================================================================
--- sandbox/SOC/2008/graphs/trunk/libs/graphs/include/boost/graphs/adjacency_list/incs/list.hpp (original)
+++ sandbox/SOC/2008/graphs/trunk/libs/graphs/include/boost/graphs/adjacency_list/incs/list.hpp 2008-11-29 12:09:11 EST (Sat, 29 Nov 2008)
@@ -9,13 +9,14 @@
 template <template <typename> class Alloc = std::allocator>
 struct incidence_list
 {
- template <typename EdgeDesc>
+ template <typename Vertex, typename Edge>
     struct store
     {
     private:
- typedef Alloc<EdgeDesc> allocator;
+ typedef std::pair<Vertex, Edge> edge;
+ typedef Alloc<edge> allocator;
     public:
- typedef counted_list<EdgeDesc, allocator> type;
+ typedef counted_list<edge, allocator> type;
     };
 };
 

Modified: sandbox/SOC/2008/graphs/trunk/libs/graphs/include/boost/graphs/adjacency_list/incs/set.hpp
==============================================================================
--- sandbox/SOC/2008/graphs/trunk/libs/graphs/include/boost/graphs/adjacency_list/incs/set.hpp (original)
+++ sandbox/SOC/2008/graphs/trunk/libs/graphs/include/boost/graphs/adjacency_list/incs/set.hpp 2008-11-29 12:09:11 EST (Sat, 29 Nov 2008)
@@ -2,7 +2,7 @@
 #ifndef BOOST_GRAPHS_ADJLIST_IES_SET_HPP
 #define BOOST_GRAPHS_ADJLIST_IES_SET_HPP
 
-#include <set>
+#include <map>
 
 namespace boost { namespace graphs { namespace adjacency_list {
 
@@ -11,14 +11,16 @@
     template <typename> class Alloc = std::allocator>
 struct incidence_set
 {
- template <typename EdgeDesc>
+ // The incidence set quietly implements a map from an adjacent vertex to
+ // the edge descriptor that references the underlying edge.
+ template <typename Vertex, typename Edge>
     struct store
     {
     private:
- typedef Compare<EdgeDesc> compare;
- typedef Alloc<EdgeDesc> allocator;
+ typedef Compare<Vertex> compare;
+ typedef Alloc<std::pair<Vertex, Edge>> allocator;
     public:
- typedef std::set<EdgeDesc, compare, allocator> type;
+ typedef std::map<Vertex, Edge, compare, allocator> type;
     };
 };
 

Modified: sandbox/SOC/2008/graphs/trunk/libs/graphs/include/boost/graphs/adjacency_list/incs/vector.hpp
==============================================================================
--- sandbox/SOC/2008/graphs/trunk/libs/graphs/include/boost/graphs/adjacency_list/incs/vector.hpp (original)
+++ sandbox/SOC/2008/graphs/trunk/libs/graphs/include/boost/graphs/adjacency_list/incs/vector.hpp 2008-11-29 12:09:11 EST (Sat, 29 Nov 2008)
@@ -9,13 +9,14 @@
 template <template <typename> class Alloc = std::allocator>
 struct incidence_vector
 {
- template <typename EdgeDesc>
+ template <typename Vertex, typename Edge>
     struct store
     {
     private:
- typedef Alloc<EdgeDesc> allocator;
+ typedef std::pair<Vertex, Edge> edge;
+ typedef Alloc<edge> allocator;
     public:
- typedef std::vector<EdgeDesc, allocator> type;
+ typedef std::vector<edge, allocator> type;
     };
 };
 

Modified: sandbox/SOC/2008/graphs/trunk/libs/graphs/include/boost/graphs/adjacency_list/undirected_graph.hpp
==============================================================================
--- sandbox/SOC/2008/graphs/trunk/libs/graphs/include/boost/graphs/adjacency_list/undirected_graph.hpp (original)
+++ sandbox/SOC/2008/graphs/trunk/libs/graphs/include/boost/graphs/adjacency_list/undirected_graph.hpp 2008-11-29 12:09:11 EST (Sat, 29 Nov 2008)
@@ -2,6 +2,8 @@
 #ifndef BOOST_GRAPHS_ADJLIST_UNDIRECTED_GRAPH_HPP
 #define BOOST_GRAPHS_ADJLIST_UNDIRECTED_GRAPH_HPP
 
+#include <tuple>
+
 #include <boost/assert.hpp>
 #include <boost/none.hpp>
 
@@ -11,6 +13,14 @@
 
 namespace boost { namespace graphs { namespace adjacency_list {
 
+// NOTE: Why do we have parameters for edge and incidence sets if they're
+// essentially required to be the same thing? To allow as much genericity as
+// possible.
+
+// TODO: This is a giant TODO related to the question above. The edge set should
+// never actually be a set or multiset. Just a list or vector because the
+// multigraph property is determined by the incidence set.
+
 /**
  * The undirected graph class...
  */
@@ -32,7 +42,7 @@
     typedef typename EdgeStore::edge_descriptor edge_descriptor;
 
     // Generate incidence store
- typedef typename IncidenceStore::template store<edge_descriptor>::type incidence_store;
+ typedef typename IncidenceStore::template store<vertex_descriptor, edge_descriptor>::type incidence_store;
     typedef typename VertexStore::template store<incidence_store, VertexLabel>::type vertex_store;
     typedef typename EdgeStore::template store<vertex_descriptor, EdgeLabel>::type edge_store;
 
@@ -145,8 +155,8 @@
     template <typename VS, typename V, typename Ins, typename Tag>
     inline void bind_edges(VS& vs, V u, V v, Ins ins, Tag)
     {
- incs::insert(vs::edges(vs, u), ins.first);
- incs::insert(vs::edges(vs, v), ins.first);
+ incs::insert(vs::edges(vs, u), v, ins.first);
+ incs::insert(vs::edges(vs, v), u, ins.first);
     }
 
     template <typename VS, typename V, typename Ins, typename Tag>
@@ -167,12 +177,55 @@
          typename undirected_graph<VL,EL,VS,ES,IS>::edge_label&& l)
 {
     typedef typename undirected_graph<VL,EL,VS,ES,IS>::edge_descriptor Edge;
+
+ // This is not a great implementation... (or correct, really).
     std::pair<Edge, bool> x = es::insert(g.e, u, v, l);
     detail::bind_edges(g.v, u, v, x, container_category(g.e));
     return x.first;
+
+ // What we should do follows: The primary reason for this is that
+#if NO_COMPILE
+ if(has_unique_edges(*this)) { // obviously done at compile time
+ Edge e = edge(u, v);
+ if(e) return e;
+ else {
+ // See code above
+ }
+ }
+ else {
+ // See code above.
+ }
+#endif
 }
 //@}
 
+namespace detail {
+ // Return a pair of vertices ordered by their degree s.t., degree(first)
+ // is less than degree(second).
+ template <typename VS, typename V>
+ inline std::pair<V, V> verts_by_size(VS const& vs, V u, V v)
+ {
+ return incs::size(vs::edges(vs, u)) < incs::size(vs::edges(vs, v)) ?
+ std::make_pair(u, v) : std::make_pair(v, u);
+ }
+}
+
+/** Return a descriptor to the edge connecting the given vertices. */
+template <typename VL, typename EL, typename VS, typename ES, typename IS>
+inline typename undirected_graph<VL,EL,VS,ES,IS>::edge_descriptor
+edge(undirected_graph<VL,EL,VS,ES,IS> const& g,
+ typename undirected_graph<VL,EL,VS,ES,IS>::vertex_descriptor u,
+ typename undirected_graph<VL,EL,VS,ES,IS>::vertex_descriptor v)
+{
+ // Here, we have to search the incidence store of the smaller degree vertex
+ // for an edge that references the pair...
+ typedef typename undirected_graph<VL,EL,VS,ES,IS>::vertex_descriptor Vertex;
+ Vertex s, t;
+ std::tie(s, t) = detail::verts_by_size(g.v, u, v);
+ return incs::find(vs::edges(g.v, s), t);
+}
+
+
 /** Return the number of edges in the graph. */
 template <typename VL, typename EL, typename VS, typename ES, typename IS>
 inline typename undirected_graph<VL,EL,VS,ES,IS>::edges_size_type

Modified: sandbox/SOC/2008/graphs/trunk/libs/graphs/include/boost/graphs/adjacency_list/vs/set.hpp
==============================================================================
--- sandbox/SOC/2008/graphs/trunk/libs/graphs/include/boost/graphs/adjacency_list/vs/set.hpp (original)
+++ sandbox/SOC/2008/graphs/trunk/libs/graphs/include/boost/graphs/adjacency_list/vs/set.hpp 2008-11-29 12:09:11 EST (Sat, 29 Nov 2008)
@@ -21,7 +21,7 @@
     typedef void key_type;
 
     typedef typename descriptor_traits<
- std::set<int, Compare<int>, Alloc<int>>,
+ std::map<int, int, Compare<int>, Alloc<std::pair<int, int>>>,
         vertex_descriptor_kind
>::descriptor_type vertex_descriptor;
 

Modified: sandbox/SOC/2008/graphs/trunk/libs/graphs/test/undirected.cpp
==============================================================================
--- sandbox/SOC/2008/graphs/trunk/libs/graphs/test/undirected.cpp (original)
+++ sandbox/SOC/2008/graphs/trunk/libs/graphs/test/undirected.cpp 2008-11-29 12:09:11 EST (Sat, 29 Nov 2008)
@@ -148,6 +148,9 @@
     Edge e2 = add_edge(g, v, w, arc(201));
     Edge e3 = add_edge(g, w, u, arc(202));
 
+ Edge t = edge(g, u, v);
+ BOOST_ASSERT(!t.is_null());
+
     BOOST_ASSERT(num_edges(g) == 3);
 }
 
@@ -163,19 +166,19 @@
 
 int main()
 {
+ // Recall... there is no edge_set<>!
     typedef undirected_graph<node, arc, vertex_vector<>, edge_vector<>, incidence_vector<>> V_V_V;
     typedef undirected_graph<node, arc, vertex_list<>, edge_vector<>, incidence_vector<>> L_V_V;
     typedef undirected_graph<node, arc, vertex_set<>, edge_vector<>, incidence_vector<>> S_V_V;
     typedef undirected_graph<node, arc, vertex_map<int>, edge_vector<>, incidence_vector<>> M_V_V;
-
     typedef undirected_graph<node, arc, vertex_vector<>, edge_list<>, incidence_list<>> V_L_L;
- typedef undirected_graph<node, arc, vertex_vector<>, edge_set<>, incidence_set<>> V_S_S;
+ typedef undirected_graph<node, arc, vertex_vector<>, edge_list<>, incidence_set<>> V_L_S;
 
     test<V_V_V>();
- test<L_V_V>();
- test<S_V_V>();
- test<M_V_V>();
- test<V_L_L>();
- test<V_S_S>();
+// test<L_V_V>();
+// test<S_V_V>();
+// test<M_V_V>();
+// test<V_L_L>();
+// test<V_L_S>();
 }
 


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