Graphs

Todo:
Write a new Graphs page. I think it should be contain the Graph, UGraph and BpUGraph concept. It should be describe the iterators and the basic functions and the differences of the implementations.

Some cross-refs are wrong.

The primary data structures of LEMON are the graph classes. They all provide a node list - edge list interface, i.e. they have functionalities to list the nodes and the edges of the graph as well as incoming and outgoing edges of a given node.

Each graph should meet the Graph concept. This concept does not make it possible to change the graph (i.e. it is not possible to add or delete edges or nodes). Most of the graph algorithms will run on these graphs.

In case of graphs meeting the full feature ErasableGraph concept you can also erase individual edges and nodes in arbitrary order.

The implemented graph structures are the following.

Todo:
Don't we need SmartNodeSet and SmartEdgeSet?
The graph structures themselves can not store data attached to the edges and nodes. However they all provide map classes to dynamically attach data the to graph components.

The following program demonstrates the basic features of LEMON's graph structures.

#include <iostream>
#include <lemon/list_graph.h>

using namespace lemon;

int main()
{
  typedef ListGraph Graph;

ListGraph is one of LEMON's graph classes. It is based on linked lists, therefore iterating throuh its edges and nodes is fast.

  typedef Graph::Edge Edge;
  typedef Graph::InEdgeIt InEdgeIt;
  typedef Graph::OutEdgeIt OutEdgeIt;
  typedef Graph::EdgeIt EdgeIt;
  typedef Graph::Node Node;
  typedef Graph::NodeIt NodeIt;

  Graph g;
  
  for (int i = 0; i < 3; i++)
    g.addNode();
  
  for (NodeIt i(g); i!=INVALID; ++i)
    for (NodeIt j(g); j!=INVALID; ++j)
      if (i != j) g.addEdge(i, j);

After some convenient typedefs we create a graph and add three nodes to it. Then we add edges to it to form a complete graph.

  std::cout << "Nodes:";
  for (NodeIt i(g); i!=INVALID; ++i)
    std::cout << " " << g.id(i);
  std::cout << std::endl;

Here we iterate through all nodes of the graph. We use a constructor of the node iterator to initialize it to the first node. The operator++ is used to step to the next node. Using operator++ on the iterator pointing to the last node invalidates the iterator i.e. sets its value to INVALID. This is what we exploit in the stop condition.

The previous code fragment prints out the following:

Nodes: 2 1 0

  std::cout << "Edges:";
  for (EdgeIt i(g); i!=INVALID; ++i)
    std::cout << " (" << g.id(g.source(i)) << "," << g.id(g.target(i)) << ")";
  std::cout << std::endl;

Edges: (0,2) (1,2) (0,1) (2,1) (1,0) (2,0)

We can also iterate through all edges of the graph very similarly. The target and source member functions can be used to access the endpoints of an edge.

  NodeIt first_node(g);

  std::cout << "Out-edges of node " << g.id(first_node) << ":";
  for (OutEdgeIt i(g, first_node); i!=INVALID; ++i)
    std::cout << " (" << g.id(g.source(i)) << "," << g.id(g.target(i)) << ")"; 
  std::cout << std::endl;

  std::cout << "In-edges of node " << g.id(first_node) << ":";
  for (InEdgeIt i(g, first_node); i!=INVALID; ++i)
    std::cout << " (" << g.id(g.source(i)) << "," << g.id(g.target(i)) << ")"; 
  std::cout << std::endl;

Out-edges of node 2: (2,0) (2,1)
In-edges of node 2: (0,2) (1,2)

We can also iterate through the in and out-edges of a node. In the above example we print out the in and out-edges of the first node of the graph.

  Graph::EdgeMap<int> m(g);

  for (EdgeIt e(g); e!=INVALID; ++e)
    m.set(e, 10 - g.id(e));
  
  std::cout << "Id Edge  Value" << std::endl;
  for (EdgeIt e(g); e!=INVALID; ++e)
    std::cout << g.id(e) << "  (" << g.id(g.source(e)) << "," << g.id(g.target(e))
      << ") " << m[e] << std::endl;

Id Edge  Value
4  (0,2) 6
2  (1,2) 8
5  (0,1) 5
0  (2,1) 10
3  (1,0) 7
1  (2,0) 9

As we mentioned above, graphs are not containers rather incidence structures which are iterable in many ways. LEMON introduces concepts that allow us to attach containers to graphs. These containers are called maps.

In the example above we create an EdgeMap which assigns an integer value to all edges of the graph. We use the set member function of the map to write values into the map and the operator[] to retrieve them.

Here we used the maps provided by the ListGraph class, but you can also write your own maps. You can read more about using maps here.


Generated on Thu Jun 4 04:03:12 2009 for LEMON by  doxygen 1.5.9