doc/quicktour.dox
author hegyi
Wed, 29 Jun 2005 19:44:30 +0000
changeset 1525 6d94de269ab1
parent 1521 5815b382421b
child 1526 8c14aa8f27a2
permissions -rw-r--r--
Uh, long comment arrives... Zoom update does not happen after editorial steps. Nodes initial color is light blue, if there is any item under them. Strange node-text relations disappeared. Initial values of new items are given now in a more common way. The wood-cutter way of handling default values of properties is now changed.
     1 /**
     2 
     3 \page quicktour Quick Tour to LEMON
     4 
     5 Let us first answer the question <b>"What do I want to use LEMON for?"
     6 </b>. 
     7 LEMON is a C++ library, so you can use it if you want to write C++ 
     8 programs. What kind of tasks does the library LEMON help to solve? 
     9 It helps to write programs that solve optimization problems that arise
    10 frequently when <b>designing and testing certain networks</b>, for example
    11 in telecommunication, computer networks, and other areas that I cannot
    12 think of now. A very natural way of modelling these networks is by means
    13 of a <b> graph</b> (we will always mean a directed graph by that and say
    14 <b> undirected graph </b> otherwise). 
    15 So if you want to write a program that works with 
    16 graphs then you might find it useful to use our library LEMON. LEMON 
    17 defines various graph concepts depending on what you want to do with the 
    18 graph: a very good description can be found in the page
    19 about \ref graphs "graphs".
    20 
    21 You will also want to assign data to the edges or nodes of the graph, for
    22 example a length or capacity function defined on the edges. You can do this in
    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".
    24 
    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):
    26 
    27 <ul> <li> The first thing to discuss is the way one can create data structures
    28 like graphs and maps in a program using LEMON. 
    29 //There are more graph types
    30 //implemented in LEMON and you can implement your own graph type just as well:
    31 //read more about this in the already mentioned page on \ref graphs "graphs".
    32 
    33 First we show how to add nodes and edges to a graph manually. We will also
    34 define a map on the edges of the graph. After this we show the way one can
    35 read a graph (and perhaps maps on it) from a stream (e.g. a file). Of course
    36 we also have routines that write a graph (and perhaps maps) to a stream
    37 (file): this will also be shown. LEMON supports the DIMACS file formats to
    38 store network optimization problems, but more importantly we also have our own
    39 file format that gives a more flexible way to store data related to network
    40 optimization.
    41 
    42 <ol> <li>The following code fragment shows how to fill a graph with
    43 data. It creates a complete graph on 4 nodes. The type Listgraph is one of the
    44 LEMON graph types: the typedefs in the beginning are for convenience and we
    45 will suppose them later as well.  
    46 
    47 \code 
    48 
    49   typedef ListGraph Graph; 
    50   typedef Graph::NodeIt NodeIt;
    51 
    52   Graph g;
    53   
    54   for (int i = 0; i < 3; i++)
    55     g.addNode();
    56   
    57   for (NodeIt i(g); i!=INVALID; ++i)
    58     for (NodeIt j(g); j!=INVALID; ++j)
    59       if (i != j) g.addEdge(i, j);
    60 
    61 \endcode 
    62 
    63 See the whole program in file \ref helloworld.cc.
    64 
    65     If you want to read more on the LEMON graph structures and concepts, read the page about \ref graphs "graphs". 
    66 
    67 <li> The following code shows how to read a graph from a stream (e.g. a file)
    68 in the DIMACS file format (find the documentation of the DIMACS file formats on the web). 
    69 
    70 \code
    71 Graph g;
    72 std::ifstream f("graph.dim");
    73 readDimacs(f, g);
    74 \endcode
    75 
    76 One can also store network (graph+capacity on the edges) instances and other
    77 things (minimum cost flow instances etc.) in DIMACS format and use these in LEMON: to see the details read the
    78 documentation of the \ref dimacs.h "Dimacs file format reader". There you will
    79 also find the details about the output routines into files of the DIMACS
    80 format. 
    81 
    82 <li>We needed much greater flexibility than the DIMACS formats could give us,
    83 so we worked out our own file format. Instead of any explanation let us give a
    84 short example file in this format: read the detailed description of the LEMON
    85 graph file format and input-output routines \ref graph-io-page here.
    86 
    87 So here is a file describing a graph of 10 nodes (0 to 9), two nodemaps
    88 (called \c coordinates_x and \c coordinates_y), several edges, an edge map
    89 called \c length and two designated nodes (called \c source and \c target).
    90 
    91 \todo Maybe another example would be better here.
    92 
    93 \code
    94 @nodeset
    95 id	coordinates_x	coordinates_y	
    96 9	447.907	578.328	
    97 8	79.2573	909.464	
    98 7	878.677	960.04	
    99 6	11.5504	938.413	
   100 5	327.398	815.035	
   101 4	427.002	954.002	
   102 3	148.549	753.748	
   103 2	903.889	326.476	
   104 1	408.248	577.327	
   105 0	189.239	92.5316	
   106 @edgeset
   107 		length	
   108 2	3	901.074	
   109 8	5	270.85	
   110 6	9	601.553	
   111 5	9	285.022	
   112 9	4	408.091	
   113 3	0	719.712	
   114 7	5	612.836	
   115 0	4	933.353	
   116 5	0	778.871	
   117 5	5	0	
   118 7	1	664.049	
   119 5	5	0	
   120 0	9	560.464	
   121 4	8	352.36	
   122 4	9	399.625	
   123 4	1	402.171	
   124 1	2	591.688	
   125 3	8	182.376	
   126 4	5	180.254	
   127 3	1	345.283	
   128 5	4	184.511	
   129 6	2	1112.45	
   130 0	1	556.624	
   131 @nodes
   132 source	1	
   133 target	8	
   134 @end
   135 \endcode
   136 
   137 Finally let us give a simple example that reads a graph from a file and writes
   138 it to another.
   139 
   140 \todo This is to be done!
   141 
   142 </ol>
   143 <li> If you want to solve some transportation problems in a network then 
   144 you will want to find shortest paths between nodes of a graph. This is 
   145 usually solved using Dijkstra's algorithm. A utility
   146 that solves this is  the \ref lemon::Dijkstra "LEMON Dijkstra class".
   147 The following code is a simple program using the 
   148 \ref lemon::Dijkstra "LEMON Dijkstra class" and it also shows how to define a map on the edges (the length
   149 function):
   150 
   151 \code
   152 
   153     typedef ListGraph Graph;
   154     typedef Graph::Node Node;
   155     typedef Graph::Edge Edge;
   156     typedef Graph::EdgeMap<int> LengthMap;
   157 
   158     Graph g;
   159 
   160     //An example from Ahuja's book
   161 
   162     Node s=g.addNode();
   163     Node v2=g.addNode();
   164     Node v3=g.addNode();
   165     Node v4=g.addNode();
   166     Node v5=g.addNode();
   167     Node t=g.addNode();
   168 
   169     Edge s_v2=g.addEdge(s, v2);
   170     Edge s_v3=g.addEdge(s, v3);
   171     Edge v2_v4=g.addEdge(v2, v4);
   172     Edge v2_v5=g.addEdge(v2, v5);
   173     Edge v3_v5=g.addEdge(v3, v5);
   174     Edge v4_t=g.addEdge(v4, t);
   175     Edge v5_t=g.addEdge(v5, t);
   176   
   177     LengthMap len(g);
   178 
   179     len.set(s_v2, 10);
   180     len.set(s_v3, 10);
   181     len.set(v2_v4, 5);
   182     len.set(v2_v5, 8);
   183     len.set(v3_v5, 5);
   184     len.set(v4_t, 8);
   185     len.set(v5_t, 8);
   186 
   187     std::cout << "The id of s is " << g.id(s)<< std::endl;
   188     std::cout <<"The id of t is " << g.id(t)<<"."<<std::endl;
   189 
   190     std::cout << "Dijkstra algorithm test..." << std::endl;
   191 
   192     Dijkstra<Graph, LengthMap> dijkstra_test(g,len);
   193     
   194     dijkstra_test.run(s);
   195 
   196     
   197     std::cout << "The distance of node t from node s: " << dijkstra_test.dist(t)<<std::endl;
   198 
   199     std::cout << "The shortest path from s to t goes through the following nodes" <<std::endl;
   200  std::cout << " (the first one is t, the last one is s): "<<std::endl;
   201 
   202     for (Node v=t;v != s; v=dijkstra_test.predNode(v)){
   203 	std::cout << g.id(v) << "<-";
   204     }
   205     std::cout << g.id(s) << std::endl;	
   206 \endcode
   207 
   208 See the whole program in \ref dijkstra_demo.cc.
   209 
   210 The first part of the code is self-explanatory: we build the graph and set the
   211 length values of the edges. Then we instantiate a member of the Dijkstra class
   212 and run the Dijkstra algorithm from node \c s. After this we read some of the
   213 results. 
   214 You can do much more with the Dijkstra class, for example you can run it step
   215 by step and gain full control of the execution. For a detailed description, see the documentation of the \ref lemon::Dijkstra "LEMON Dijkstra class".
   216 
   217 
   218 <li> If you want to design a network and want to minimize the total length
   219 of wires then you might be looking for a <b>minimum spanning tree</b> in
   220 an undirected graph. This can be found using the Kruskal algorithm: the 
   221 class \ref lemon::Kruskal "LEMON Kruskal class" does this job for you.
   222 The following code fragment shows an example:
   223 
   224 Ide Zsuzska fog irni!
   225 
   226 <li>Many problems in network optimization can be formalized by means
   227 of a linear programming problem (LP problem, for short). In our
   228 library we decided not to write an LP solver, since such packages are
   229 available in the commercial world just as well as in the open source
   230 world, and it is also a difficult task to compete these. Instead we
   231 decided to develop an interface that makes it easier to use these
   232 solvers together with LEMON. The advantage of this approach is
   233 twofold. Firstly our C++ interface is more comfortable than the
   234 solvers' native interface. Secondly, changing the underlying solver in
   235 a certain software using LEMON's LP interface needs zero effort. So,
   236 for example, one may try his idea using a free solver, demonstrate its
   237 usability for a customer and if it works well, but the performance
   238 should be improved, then one may decide to purchase and use a better
   239 commercial solver.
   240 
   241 So far we have an
   242 interface for the commercial LP solver software \b CLPLEX (developed by ILOG)
   243 and for the open source solver \b GLPK (a shorthand for Gnu Linear Programming
   244 Toolkit).
   245 
   246 We will show two examples, the first one shows how simple it is to formalize
   247 and solve an LP problem in LEMON, while the second one shows how LEMON
   248 facilitates solving network optimization problems using LP solvers.
   249 
   250 <ol>
   251 <li>The following code shows how to solve an LP problem using the LEMON lp
   252 interface. The code together with the comments is self-explanatory.
   253 
   254 \code
   255 
   256   //A default solver is taken
   257   LpDefault lp;
   258   typedef LpDefault::Row Row;
   259   typedef LpDefault::Col Col;
   260   
   261 
   262   //This will be a maximization
   263   lp.max();
   264 
   265   //We add coloumns (variables) to our problem
   266   Col x1 = lp.addCol();
   267   Col x2 = lp.addCol();
   268   Col x3 = lp.addCol();
   269 
   270   //Constraints
   271   lp.addRow(x1+x2+x3 <=100);  
   272   lp.addRow(10*x1+4*x2+5*x3<=600);  
   273   lp.addRow(2*x1+2*x2+6*x3<=300);  
   274   //Nonnegativity of the variables
   275   lp.colLowerBound(x1, 0);
   276   lp.colLowerBound(x2, 0);
   277   lp.colLowerBound(x3, 0);
   278   //Objective function
   279   lp.setObj(10*x1+6*x2+4*x3);
   280   
   281   //Call the routine of the underlying LP solver
   282   lp.solve();
   283 
   284   //Print results
   285   if (lp.primalStatus()==LpSolverBase::OPTIMAL){
   286     printf("Z = %g; x1 = %g; x2 = %g; x3 = %g\n", 
   287 	   lp.primalValue(), 
   288 	   lp.primal(x1), lp.primal(x2), lp.primal(x3));
   289   }
   290   else{
   291     std::cout<<"Optimal solution not found!"<<std::endl;
   292   }
   293 
   294 
   295 \endcode
   296 
   297 See the whole code in \ref lp_demo.cc.
   298 
   299 <li>The second example shows how easy it is to formalize a max-flow
   300 problem as an LP problem using the LEMON LP interface: we are looking
   301 for a real valued function defined on the edges of the digraph
   302 satisfying the nonnegativity-, the capacity constraints and the
   303 flow-conservation constraints and giving the largest flow value
   304 between to designated nodes.
   305 
   306 In the following code we suppose that we already have the graph \c g,
   307 the capacity map \c cap, the source node \c s and the target node \c t
   308 in the memory. We will also omit the typedefs.
   309 
   310 \code
   311   //Define a map on the edges for the variables of the LP problem
   312   typename G::template EdgeMap<LpDefault::Col> x(g);
   313   lp.addColSet(x);
   314   
   315   //Nonnegativity and capacity constraints
   316   for(EdgeIt e(g);e!=INVALID;++e) {
   317     lp.colUpperBound(x[e],cap[e]);
   318     lp.colLowerBound(x[e],0);
   319   }
   320 
   321 
   322   //Flow conservation constraints for the nodes (except for 's' and 't')
   323   for(NodeIt n(g);n!=INVALID;++n) if(n!=s&&n!=t) {
   324     LpDefault::Expr ex;
   325     for(InEdgeIt  e(g,n);e!=INVALID;++e) ex+=x[e];
   326     for(OutEdgeIt e(g,n);e!=INVALID;++e) ex-=x[e];
   327     lp.addRow(ex==0);
   328   }
   329   
   330   //Objective function: the flow value entering 't'
   331   {
   332     LpDefault::Expr ex;
   333     for(InEdgeIt  e(g,t);e!=INVALID;++e) ex+=x[e];
   334     for(OutEdgeIt e(g,t);e!=INVALID;++e) ex-=x[e];
   335     lp.setObj(ex);
   336   }
   337 
   338   //Maximization
   339   lp.max();
   340 
   341   //Solve with the underlying solver
   342   lp.solve();
   343 
   344 \endcode
   345 
   346 The complete program can be found in file \ref lp_maxflow_demo.cc. After compiling run it in the form:
   347 
   348 <tt>./lp_maxflow_demo < ?????????.lgf</tt>
   349 
   350 where ?????????.lgf is a file in the lemon format containing a maxflow instance (designated "source", "target" nodes and "capacity" map on the edges).
   351 
   352 
   353 
   354 </ol>
   355 </ul>
   356 
   357 */