doc/graph_orientation.dox
author hegyi
Mon, 21 Nov 2005 18:03:20 +0000
changeset 1823 cb082cdf3667
parent 1684 df3820d7989d
child 1953 d4f411003580
permissions -rw-r--r--
NewMapWin has become Dialog instead of Window. Therefore it is created dynamically, when there is need for it, instead of keeping one instance in memory. This solution is slower, but more correct than before.
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@1678
    66
First we check whether the program is called with exactly 1 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@1678
    74
file. To generate the output picture, we also read the node titles (\c id) and
alpar@1678
    75
coordinates (\c coords).
alpar@1678
    76
So, first we create the graph
alpar@1678
    77
\skipline ListGraph
alpar@1678
    78
and the corresponding NodeMaps.
alpar@1678
    79
\skipline NodeMap
alpar@1678
    80
\until coords
alpar@1678
    81
\note The graph must be given to the maps' constructor.
alpar@1678
    82
alpar@1678
    83
Then, the following block will read these data from the file, or exit if
alpar@1678
    84
the file is missing or corrupt.
alpar@1678
    85
\skip try
alpar@1678
    86
\until }
alpar@1678
    87
\until }
alpar@1678
    88
alpar@1678
    89
The algorithm needs a "level" integer value assigned to each node. In the
alpar@1678
    90
beginning, the nodes are on level 0.
alpar@1678
    91
\skipline level
alpar@1678
    92
alpar@1678
    93
The deficiency (\c def) of a node is the in-degree requirement minus the 
alpar@1678
    94
actual in-degree.
alpar@1678
    95
alpar@1678
    96
\skip def
alpar@1678
    97
\until subMap
alpar@1678
    98
alpar@1678
    99
A node is \e active if its deficiency is positive (i.e. if it doesn't meet
alpar@1678
   100
the degree requirement).
alpar@1678
   101
\skip active
alpar@1678
   102
\until def
alpar@1678
   103
alpar@1715
   104
We also store in a bool map indicating which edges are reverted. Actually this is only
alpar@1678
   105
used to draw these edges with different color in the output picture. The
alpar@1678
   106
algorithm will update this map called \c rev, but will not use it otherwise.
alpar@1678
   107
\skip rev
alpar@1678
   108
\until reversed
alpar@1678
   109
alpar@1678
   110
The variable \c nodeNum will refer to the number of nodes.
alpar@1678
   111
\skipline nodeNum
alpar@1678
   112
alpar@1678
   113
Here comes the algorithms itself. 
alpar@1678
   114
In each iteration we choose an active node (\c act will store it). If there is
alpar@1678
   115
no such a node, then the orientation is feasible so we are done.
alpar@1678
   116
\skip act
alpar@1678
   117
\until while
alpar@1678
   118
alpar@1678
   119
Then we check if there exists an edge leaving this node that steps down exactly
alpar@1678
   120
one level.
alpar@1678
   121
\skip OutEdge
alpar@1678
   122
\until while
alpar@1678
   123
alpar@1678
   124
If there exists, we decrease the "activity" of the node \c act by reverting
alpar@1678
   125
this egde.
alpar@1678
   126
Fortunately, \ref lemon::ListGraph "ListGraph"
alpar@1678
   127
has a special function \ref lemon::ListGraph::reverseEdge() "reverseEdge()"
alpar@1678
   128
that makes this easy.
alpar@1678
   129
We also have to update the maps \c def and
alpar@1678
   130
\c rev.
alpar@1678
   131
\skipline if
alpar@1678
   132
\skip if
alpar@1678
   133
\until }
alpar@1678
   134
Otherwise (i.e. if there is no edge stepping down one level). We lift up the
alpar@1678
   135
current active node \c act. If it reaches level \c nodeNum, then there
alpar@1678
   136
exists no appropriate orientation so we stop.
alpar@1678
   137
\skipline else
alpar@1678
   138
\skipline if
alpar@1678
   139
\skipline return
alpar@1678
   140
\until }
alpar@1678
   141
\until }
alpar@1678
   142
\until }
alpar@1678
   143
alpar@1678
   144
Believe it or not, this algorithm works and runs fast.
alpar@1678
   145
alpar@1678
   146
Finally, we print the obtained orientation. Note, how the different
alpar@1678
   147
\c bool values of
alpar@1678
   148
\c rev are transformed into different \ref lemon::Color "RGB color"s
alpar@1678
   149
using the class
alpar@1678
   150
\ref lemon::ColorSet "ColorSet"
alpar@1678
   151
and the \ref map_adaptors "map adaptor" called
alpar@1678
   152
\ref lemon::ComposeMap "composeMap".
alpar@1678
   153
alpar@1678
   154
\skip graphToEps
alpar@1678
   155
\until run
alpar@1678
   156
alpar@1678
   157
alpar@1678
   158
\until end of main
alpar@1678
   159
alpar@1678
   160
Finally here are again the list of the used include files (because I can't turn
alpar@1678
   161
this section off.)
alpar@1678
   162
alpar@1678
   163
*/
alpar@1678
   164
alpar@1678
   165
}