doc/graph_orientation.dox
author deba
Mon, 03 Apr 2006 09:45:23 +0000
changeset 2031 080d51024ac5
parent 1715 e71778873dd0
child 2158 0b620ff10e7c
permissions -rw-r--r--
Correcting the structure of the graph's and adaptor's map.
The template assign operators and map iterators can be used for adaptors also.

Some bugfix in the adaptors

New class SwapBpUGraphAdaptor which swaps the two nodeset of the graph.
alpar@1678
     1
namespace lemon {
alpar@1678
     2
/**
alpar@1678
     3
alpar@1678
     4
\ingroup demos
alpar@1678
     5
\file graph_orientation.cc
alpar@1678
     6
\brief Graph orientation with lower bound requirement on the
alpar@1678
     7
in-degree of the nodes.
alpar@1678
     8
alpar@1684
     9
This demo shows an adaptation of the well-known "preflow push" algorithm to
alpar@1684
    10
a simple graph orientation problem.
alpar@1678
    11
alpar@1684
    12
The input of the problem is a(n undirected) graph and an integer value
alpar@1684
    13
<i>f(n)</i> assigned to each node \e n. The task is to find an orientation
alpar@1684
    14
of the edges for which the number of edge arriving to each node \e n is at
alpar@1684
    15
least least <i>f(n)</i>.
alpar@1684
    16
alpar@1684
    17
In fact, the algorithm reads a directed graph and computes a set of edges to
alpar@1684
    18
be reversed in order to achieve the in-degree requirement.
alpar@1684
    19
This input is given using 
alpar@1684
    20
\ref graph-io-page ".lgf (Lemon Graph Format)" file. It should contain
alpar@1684
    21
three node maps. The one called "f" contains the in-degree requirements, while
alpar@1684
    22
"coordinate_x" and "coordinate_y" indicate the position of the nodes. These
alpar@1684
    23
latter ones are used to generate the output, which is a <tt>.eps</tt> file.
alpar@1684
    24
alpar@1684
    25
alpar@1684
    26
\section go-alg-dec The C++ source file
alpar@1684
    27
alpar@1684
    28
Here you find how to solve the problem above using lemon.
alpar@1684
    29
alpar@1684
    30
\subsection go-alg-head Headers and convenience typedefs
alpar@1678
    31
alpar@1678
    32
First we include some important headers.
alpar@1678
    33
alpar@1678
    34
The first one defines \ref lemon::ListGraph "ListGraph",
alpar@1678
    35
the "Swiss army knife" graph implementation.
alpar@1678
    36
\dontinclude graph_orientation.cc
alpar@1678
    37
\skipline list_graph
alpar@1678
    38
alpar@1678
    39
The next is  to read a \ref graph-io-page ".lgf" (Lemon Graph Format) file.
alpar@1678
    40
\skipline reader
alpar@1678
    41
alpar@1678
    42
This provides us with some special purpose graph \ref maps "maps".
alpar@1678
    43
\skipline iterable
alpar@1678
    44
alpar@1678
    45
The following header defines a simple data structure to store and manipulate
alpar@1678
    46
planar coordinates. It will be used to draw the result.
alpar@1678
    47
\skipline xy
alpar@1678
    48
alpar@1678
    49
And finally, this header contains a simple graph drawing utility.
alpar@1678
    50
\skipline eps
alpar@1678
    51
alpar@1678
    52
As we don't want to type in \ref lemon "lemon::" million times, the
alpar@1678
    53
following line seems to be useful.
alpar@1678
    54
\skipline namespace
alpar@1678
    55
alpar@1678
    56
The following <tt>typedef</tt>s will also save a lot of typing.
alpar@1678
    57
\skip typedef
alpar@1678
    58
\until InEdgeIt
alpar@1678
    59
alpar@1684
    60
\subsection go-alg-main The main() function
alpar@1684
    61
alpar@1678
    62
Well, we are ready to start <tt>main()</tt>.
alpar@1678
    63
\skip main
alpar@1678
    64
\until {
alpar@1678
    65
alpar@1953
    66
First we check whether the program is called with exactly one parameter.
alpar@1678
    67
If it isn't, we print a short help message end exit.
alpar@1678
    68
The vast majority of people would probably skip this block.
alpar@1678
    69
\skip if
alpar@1678
    70
\until }
alpar@1678
    71
alpar@1678
    72
Now, we read a graph \c g, and a map \c f containing
alpar@1684
    73
the in-deg requirements from a \ref graph-io-page ".lgf (Lemon Graph Format)"
alpar@1953
    74
file. To generate the output picture, we also read the node titles (\c label)
alpar@1953
    75
and
alpar@1678
    76
coordinates (\c coords).
alpar@1678
    77
So, first we create the graph
alpar@1678
    78
\skipline ListGraph
alpar@1678
    79
and the corresponding NodeMaps.
alpar@1678
    80
\skipline NodeMap
alpar@1678
    81
\until coords
alpar@1678
    82
\note The graph must be given to the maps' constructor.
alpar@1678
    83
alpar@1678
    84
Then, the following block will read these data from the file, or exit if
alpar@1678
    85
the file is missing or corrupt.
alpar@1678
    86
\skip try
alpar@1678
    87
\until }
alpar@1678
    88
\until }
alpar@1678
    89
alpar@1953
    90
The algorithm needs an integer value assigned to each node. We call this "level" and the nodes are on level 0 at the
alpar@1953
    91
beginning of the execution.
alpar@1953
    92
alpar@1678
    93
\skipline level
alpar@1678
    94
alpar@1678
    95
The deficiency (\c def) of a node is the in-degree requirement minus the 
alpar@1678
    96
actual in-degree.
alpar@1678
    97
alpar@1678
    98
\skip def
alpar@1678
    99
\until subMap
alpar@1678
   100
alpar@1678
   101
A node is \e active if its deficiency is positive (i.e. if it doesn't meet
alpar@1678
   102
the degree requirement).
alpar@1678
   103
\skip active
alpar@1678
   104
\until def
alpar@1678
   105
alpar@1953
   106
We also store in a bool map indicating which edges are reverted.
alpar@1953
   107
Actually this map called \c rev is only
alpar@1678
   108
used to draw these edges with different color in the output picture. The
alpar@1953
   109
algorithm updates this map, but will not use it otherwise.
alpar@1678
   110
\skip rev
alpar@1678
   111
\until reversed
alpar@1678
   112
alpar@1678
   113
The variable \c nodeNum will refer to the number of nodes.
alpar@1678
   114
\skipline nodeNum
alpar@1678
   115
alpar@1678
   116
Here comes the algorithms itself. 
alpar@1953
   117
In each iteration we choose an active node (\c act will do it for us).
alpar@1953
   118
If there is
alpar@1678
   119
no such a node, then the orientation is feasible so we are done.
alpar@1678
   120
\skip act
alpar@1678
   121
\until while
alpar@1678
   122
alpar@1678
   123
Then we check if there exists an edge leaving this node that steps down exactly
alpar@1678
   124
one level.
alpar@1678
   125
\skip OutEdge
alpar@1678
   126
\until while
alpar@1678
   127
alpar@1678
   128
If there exists, we decrease the "activity" of the node \c act by reverting
alpar@1678
   129
this egde.
alpar@1678
   130
Fortunately, \ref lemon::ListGraph "ListGraph"
alpar@1678
   131
has a special function \ref lemon::ListGraph::reverseEdge() "reverseEdge()"
alpar@1678
   132
that makes this easy.
alpar@1678
   133
We also have to update the maps \c def and
alpar@1678
   134
\c rev.
alpar@1678
   135
\skipline if
alpar@1678
   136
\skip if
alpar@1678
   137
\until }
alpar@1678
   138
Otherwise (i.e. if there is no edge stepping down one level). We lift up the
alpar@1678
   139
current active node \c act. If it reaches level \c nodeNum, then there
alpar@1678
   140
exists no appropriate orientation so we stop.
alpar@1678
   141
\skipline else
alpar@1678
   142
\skipline if
alpar@1678
   143
\skipline return
alpar@1678
   144
\until }
alpar@1678
   145
\until }
alpar@1678
   146
\until }
alpar@1678
   147
alpar@1678
   148
Believe it or not, this algorithm works and runs fast.
alpar@1678
   149
alpar@1678
   150
Finally, we print the obtained orientation. Note, how the different
alpar@1678
   151
\c bool values of
alpar@1678
   152
\c rev are transformed into different \ref lemon::Color "RGB color"s
alpar@1678
   153
using the class
alpar@1678
   154
\ref lemon::ColorSet "ColorSet"
alpar@1678
   155
and the \ref map_adaptors "map adaptor" called
alpar@1678
   156
\ref lemon::ComposeMap "composeMap".
alpar@1678
   157
alpar@1678
   158
\skip graphToEps
alpar@1678
   159
\until run
alpar@1678
   160
alpar@1678
   161
alpar@1678
   162
\until end of main
alpar@1678
   163
alpar@1678
   164
Finally here are again the list of the used include files (because I can't turn
alpar@1678
   165
this section off.)
alpar@1678
   166
alpar@1678
   167
*/
alpar@1678
   168
alpar@1678
   169
}