doc/quicktour.dox
author alpar
Mon, 27 Jun 2005 14:39:53 +0000
changeset 1516 4aeda8d11d5e
parent 1511 d6b95a59da26
child 1517 b303c1741c9a
permissions -rw-r--r--
processNextXyz() returns the processed object.
athos@1169
     1
/**
athos@1169
     2
alpar@1170
     3
\page quicktour Quick Tour to LEMON
alpar@1170
     4
athos@1175
     5
Let us first answer the question <b>"What do I want to use LEMON for?"
athos@1175
     6
</b>. 
athos@1175
     7
LEMON is a C++ library, so you can use it if you want to write C++ 
athos@1175
     8
programs. What kind of tasks does the library LEMON help to solve? 
athos@1175
     9
It helps to write programs that solve optimization problems that arise
athos@1175
    10
frequently when <b>designing and testing certain networks</b>, for example
athos@1175
    11
in telecommunication, computer networks, and other areas that I cannot
athos@1175
    12
think of now. A very natural way of modelling these networks is by means
athos@1183
    13
of a <b> graph</b> (we will always mean a directed graph by that and say
athos@1183
    14
<b> undirected graph </b> otherwise). 
athos@1175
    15
So if you want to write a program that works with 
athos@1183
    16
graphs then you might find it useful to use our library LEMON. LEMON 
athos@1183
    17
defines various graph concepts depending on what you want to do with the 
athos@1183
    18
graph: a very good description can be found in the page
athos@1183
    19
about \ref graphs "graphs".
athos@1175
    20
athos@1514
    21
You will also want to assign data to the edges or nodes of the graph, for
athos@1514
    22
example a length or capacity function defined on the edges. You can do this in
athos@1514
    23
LEMON using so called \b maps. You can define a map on the nodes or on the edges of the graph and the value of the map (the range of the function) can be practically almost of any type. Read more about maps \ref maps-page "here".
athos@1175
    24
athos@1511
    25
Some examples are the following (you will find links next to the code fragments that help to download full demo programs: save them on your computer and compile them according to the description in the page about \ref getsart How to start using LEMON):
athos@1175
    26
athos@1514
    27
<ul>
athos@1514
    28
<li> First we give two examples that show how to instantiate a graph. The
athos@1175
    29
first one shows the methods that add nodes and edges, but one will
athos@1175
    30
usually use the second way which reads a graph from a stream (file).
athos@1514
    31
<ol>
athos@1514
    32
<li>The following code fragment shows how to fill a graph with data. It creates a complete graph on 4 nodes. The type Listgraph is one of the LEMON graph types: the typedefs in the beginning are for convenience and we will suppose them later as well.
athos@1175
    33
 \code
athos@1175
    34
  typedef ListGraph Graph;
athos@1175
    35
  typedef Graph::NodeIt NodeIt;
athos@1175
    36
athos@1175
    37
  Graph g;
athos@1175
    38
  
athos@1175
    39
  for (int i = 0; i < 3; i++)
athos@1175
    40
    g.addNode();
athos@1175
    41
  
athos@1175
    42
  for (NodeIt i(g); i!=INVALID; ++i)
athos@1175
    43
    for (NodeIt j(g); j!=INVALID; ++j)
athos@1175
    44
      if (i != j) g.addEdge(i, j);
athos@1175
    45
 \endcode 
athos@1175
    46
athos@1511
    47
See the whole program in file \ref helloworld.cc.
athos@1511
    48
athos@1514
    49
    If you want to read more on the LEMON graph structures and concepts, read the page about \ref graphs "graphs". 
athos@1181
    50
athos@1514
    51
<li> The following code shows how to read a graph from a stream (e.g. a file). LEMON supports the DIMACS file format: it can read a graph instance from a file 
athos@1511
    52
in that format (find the documentation of the DIMACS file format on the web). 
athos@1181
    53
\code
athos@1181
    54
Graph g;
athos@1181
    55
std::ifstream f("graph.dim");
athos@1181
    56
readDimacs(f, g);
athos@1181
    57
\endcode
athos@1183
    58
One can also store network (graph+capacity on the edges) instances and other things in DIMACS format and use these in LEMON: to see the details read the documentation of the \ref dimacs.h "Dimacs file format reader".
athos@1181
    59
athos@1514
    60
</ol>
athos@1514
    61
<li> If you want to solve some transportation problems in a network then 
athos@1175
    62
you will want to find shortest paths between nodes of a graph. This is 
athos@1175
    63
usually solved using Dijkstra's algorithm. A utility
athos@1175
    64
that solves this is  the \ref lemon::Dijkstra "LEMON Dijkstra class".
athos@1183
    65
The following code is a simple program using the \ref lemon::Dijkstra "LEMON
athos@1183
    66
Dijkstra class" and it also shows how to define a map on the edges (the length
athos@1183
    67
function):
athos@1175
    68
athos@1175
    69
\code
athos@1183
    70
athos@1183
    71
    typedef ListGraph Graph;
athos@1183
    72
    typedef Graph::Node Node;
athos@1183
    73
    typedef Graph::Edge Edge;
athos@1183
    74
    typedef Graph::EdgeMap<int> LengthMap;
athos@1183
    75
athos@1183
    76
    Graph g;
athos@1183
    77
athos@1183
    78
    //An example from Ahuja's book
athos@1183
    79
athos@1183
    80
    Node s=g.addNode();
athos@1183
    81
    Node v2=g.addNode();
athos@1183
    82
    Node v3=g.addNode();
athos@1183
    83
    Node v4=g.addNode();
athos@1183
    84
    Node v5=g.addNode();
athos@1183
    85
    Node t=g.addNode();
athos@1183
    86
athos@1183
    87
    Edge s_v2=g.addEdge(s, v2);
athos@1183
    88
    Edge s_v3=g.addEdge(s, v3);
athos@1183
    89
    Edge v2_v4=g.addEdge(v2, v4);
athos@1183
    90
    Edge v2_v5=g.addEdge(v2, v5);
athos@1183
    91
    Edge v3_v5=g.addEdge(v3, v5);
athos@1183
    92
    Edge v4_t=g.addEdge(v4, t);
athos@1183
    93
    Edge v5_t=g.addEdge(v5, t);
athos@1183
    94
  
athos@1183
    95
    LengthMap len(g);
athos@1183
    96
athos@1183
    97
    len.set(s_v2, 10);
athos@1183
    98
    len.set(s_v3, 10);
athos@1183
    99
    len.set(v2_v4, 5);
athos@1183
   100
    len.set(v2_v5, 8);
athos@1183
   101
    len.set(v3_v5, 5);
athos@1183
   102
    len.set(v4_t, 8);
athos@1183
   103
    len.set(v5_t, 8);
athos@1183
   104
athos@1511
   105
    std::cout << "The id of s is " << g.id(s)<< std::endl;
athos@1511
   106
    std::cout <<"The id of t is " << g.id(t)<<"."<<std::endl;
athos@1183
   107
athos@1183
   108
    std::cout << "Dijkstra algorithm test..." << std::endl;
athos@1183
   109
athos@1183
   110
    Dijkstra<Graph, LengthMap> dijkstra_test(g,len);
athos@1183
   111
    
athos@1183
   112
    dijkstra_test.run(s);
athos@1183
   113
athos@1183
   114
    
athos@1183
   115
    std::cout << "The distance of node t from node s: " << dijkstra_test.dist(t)<<std::endl;
athos@1183
   116
athos@1511
   117
    std::cout << "The shortest path from s to t goes through the following nodes" <<std::endl;
athos@1511
   118
 std::cout << " (the first one is t, the last one is s): "<<std::endl;
athos@1183
   119
athos@1183
   120
    for (Node v=t;v != s; v=dijkstra_test.predNode(v)){
athos@1183
   121
	std::cout << g.id(v) << "<-";
athos@1183
   122
    }
athos@1183
   123
    std::cout << g.id(s) << std::endl;	
athos@1175
   124
\endcode
athos@1175
   125
alpar@1287
   126
See the whole program in \ref dijkstra_demo.cc.
athos@1183
   127
athos@1183
   128
The first part of the code is self-explanatory: we build the graph and set the
athos@1183
   129
length values of the edges. Then we instantiate a member of the Dijkstra class
athos@1183
   130
and run the Dijkstra algorithm from node \c s. After this we read some of the
athos@1183
   131
results. 
athos@1183
   132
You can do much more with the Dijkstra class, for example you can run it step
athos@1183
   133
by step and gain full control of the execution. For a detailed description, see the documentation of the \ref lemon::Dijkstra "LEMON Dijkstra class".
athos@1183
   134
athos@1183
   135
athos@1514
   136
<li> If you want to design a network and want to minimize the total length
athos@1175
   137
of wires then you might be looking for a <b>minimum spanning tree</b> in
athos@1175
   138
an undirected graph. This can be found using the Kruskal algorithm: the 
athos@1175
   139
class \ref lemon::Kruskal "LEMON Kruskal class" does this job for you.
athos@1175
   140
The following code fragment shows an example:
athos@1175
   141
athos@1511
   142
Ide Zsuzska fog irni!
athos@1511
   143
athos@1514
   144
<li>Many problems in network optimization can be formalized by means of a
athos@1514
   145
linear programming problem (LP problem, for short). In our library we decided
athos@1514
   146
not to write an LP solver, since such packages are available in the commercial
athos@1514
   147
world just as well as in the open source world, and it is also a difficult
athos@1514
   148
task to compete these. Instead we decided to develop an interface that makes
athos@1514
   149
it easier to use these solvers together with LEMON. So far we have an
athos@1514
   150
interface for the commercial LP solver software \b CLPLEX (developed by ILOG)
athos@1514
   151
and for the open source solver \b GLPK (a shorthand for Gnu Linear Programming
athos@1514
   152
Toolkit). 
athos@1514
   153
athos@1514
   154
We will show two examples, the first one shows how simple it is to formalize
athos@1514
   155
and solve an LP problem in LEMON, while the second one shows how LEMON
athos@1514
   156
facilitates solving network optimization problems using LP solvers.
athos@1514
   157
athos@1514
   158
<ol>
athos@1514
   159
<li>The following code shows how to solve an LP problem using the LEMON lp
athos@1514
   160
interface. 
athos@1511
   161
athos@1175
   162
\code
athos@1175
   163
athos@1514
   164
  //A default solver is taken
athos@1514
   165
  LpDefault lp;
athos@1514
   166
  typedef LpDefault::Row Row;
athos@1514
   167
  typedef LpDefault::Col Col;
athos@1514
   168
  
athos@1514
   169
athos@1514
   170
  //This will be a maximization
athos@1514
   171
  lp.max();
athos@1514
   172
athos@1514
   173
  //We add coloumns (variables) to our problem
athos@1514
   174
  Col x1 = lp.addCol();
athos@1514
   175
  Col x2 = lp.addCol();
athos@1514
   176
  Col x3 = lp.addCol();
athos@1514
   177
athos@1514
   178
  //Constraints
athos@1514
   179
  lp.addRow(x1+x2+x3 <=100);  
athos@1514
   180
  lp.addRow(10*x1+4*x2+5*x3<=600);  
athos@1514
   181
  lp.addRow(2*x1+2*x2+6*x3<=300);  
athos@1514
   182
  //Nonnegativity of the variables
athos@1514
   183
  lp.colLowerBound(x1, 0);
athos@1514
   184
  lp.colLowerBound(x2, 0);
athos@1514
   185
  lp.colLowerBound(x3, 0);
athos@1514
   186
  //Objective function
athos@1514
   187
  lp.setObj(10*x1+6*x2+4*x3);
athos@1514
   188
  
athos@1514
   189
  //Call the routine of the underlying LP solver
athos@1514
   190
  lp.solve();
athos@1514
   191
athos@1514
   192
  //Print results
athos@1514
   193
  if (lp.primalStatus()==LpSolverBase::OPTIMAL){
athos@1514
   194
    printf("Z = %g; x1 = %g; x2 = %g; x3 = %g\n", 
athos@1514
   195
	   lp.primalValue(), 
athos@1514
   196
	   lp.primal(x1), lp.primal(x2), lp.primal(x3));
athos@1514
   197
  }
athos@1514
   198
  else{
athos@1514
   199
    std::cout<<"Optimal solution not found!"<<std::endl;
athos@1514
   200
  }
athos@1514
   201
athos@1514
   202
athos@1175
   203
\endcode
athos@1175
   204
athos@1514
   205
See the whole code in \ref lp_demo.cc.
athos@1514
   206
athos@1514
   207
<li>The second example shows how easy it is to formalize a network
athos@1514
   208
optimization problem as an LP problem using the LEMON LP interface.
athos@1514
   209
athos@1514
   210
</ol>
athos@1514
   211
</ul>
athos@1175
   212
athos@1175
   213
*/