Changes between Initial Version and Version 1 of soc/2007/UserFriendlyGraphDesignThree


Ignore:
Timestamp:
May 14, 2007, 4:21:45 PM (15 years ago)
Author:
Andrew Sutton
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • soc/2007/UserFriendlyGraphDesignThree

    v1 v1  
     1After working on some documentation for the library (porting to quickbook), I have been rethinking many of the requirements of these new classes. Although this design
     2is not radically different than that of [wiki:soc/2007/UserFriendlyGraphDesignTwo my second iteration], it somewhat more refined, targeting a very specific set of
     3criteria: specifically, usability.  The basic outline follows:
     4
     5{{{
     6#!cpp
     7namespace boost {
     8  template <class VP, class EP, class GP>
     9  class undirected_graph
     10  {
     11    typedef adjacency_list<vecS, vecS, undirectedS, VP, EP, GP, listS> graph_type;
     12    graph_type g;
     13
     14  public:
     15    // ...
     16
     17    inline graph_type& impl()
     18    { return g; }
     19
     20    inline const graph_type& impl() const
     21    { return g; }
     22  };
     23
     24  // the add_edge method...
     25  template <class VP, class EP, class GP>
     26  inline std::pair<undirected_graph<VP,EP,GP>::edge_descriptor, bool>
     27  add_edge(undirected_graph<VP,EP,GP> &g
     28           undirected_graph<VP,EP,GP>::vertex_descriptor u,
     29           undirected_graph<VP,EP,GP>::vertex_desrciptor v)
     30  {
     31    return boost::add_edge(g.impl(), u, v);
     32  }
     33}
     34}}}
     35
     36Note that an alterntative to exposing an `impl()` method would be to have the class host all of common operations as member variables and have free functions call those. This would completely hide the underlying `adjacency_list` from the user. For example,
     37
     38{{{
     39#!cpp
     40namespace boost {
     41  template <class VP, class EP, class GP>
     42  class undirected_graph
     43  {
     44    typedef adjacency_list<vecS, vecS, undirectedS, VP, EP, GP, listS> graph_type;
     45    graph_type g;
     46
     47  public:
     48    // ...
     49
     50    inline std::pair<edge_descriptor, bool>
     51    add_edge(vertex_descriptor u, vertex_descriptor v)
     52    { return boost::add_edge(u, v, g);
     53  };
     54
     55  // the add_edge method...
     56  template <class VP, class EP, class GP>
     57  inline std::pair<undirected_graph<VP,EP,GP>::edge_descriptor, bool>
     58  add_edge(undirected_graph<VP,EP,GP> &g
     59           undirected_graph<VP,EP,GP>::vertex_descriptor u,
     60           undirected_graph<VP,EP,GP>::vertex_desrciptor v)
     61  {
     62    return g.add_edge(u, v);
     63  }
     64}}}
     65
     66== Rationale ==
     67This is a much, much simpler template interface to a graph class than presented by `adjacency_list` class. Essentially, we remove almost all of the decision making requirements out of the class by using default arguments for the underlying implementation. Here, the intent is to make get the user working with a graph class (any graph class) as fast as possible. The user really only needs to worry about substituting different containers when performance becomes a requirement. At this point, the user can "simply" redefine the type of thier graphs to an `adjacency_list` as more of an "advanced" feature of the library.  Moreover, by selecting `vecS` for both the vertex list and out edge list, we guarantee reasonable performance for a number of common graph problems.
     68
     69We do however, leave the property templates in place so users can experiment with adding new properties to vertices and edges and using them with property maps (which isn't very well documented).
     70
     71This design, when coupled with improved documentation, should provide
     72 1. a clear starting point for new users,
     73 2. a migration from basic, general functionality to advanced and customizable functionality,
     74 3. and the guarantees type and performance required by the orignal Boost.Graph concepts.
     75
     76It might also be worth noticing the re-ordering of parameters to the `add_edge()` method. This aligns with the more convential style of putting the target object fist in the parameter list.
     77
     78== Remarks ==
     79I'm actually very fond of this approach since it reduces the interface so much. However, this does leave questions about the `directed_graph`. Specifically, should its directional selection be `directedS` or `bidirectionalS`? My best guess is the latter since it provides more functionality at the expense of space efficiency, but it also makes it more applicable to a wider range of problems.