# HG changeset patch # User alpar # Date 1158261084 0 # Node ID 1e45cdeea3ccbdd5d2dbd9e60ee78f58c97016fe # Parent 83ec156873ab1ab3854f82064cb3e2ac8ee5ad12 The recent progresses on the tutorial due to Mark. diff -r 83ec156873ab -r 1e45cdeea3cc demo/Makefile.am --- a/demo/Makefile.am Thu Sep 14 19:02:52 2006 +0000 +++ b/demo/Makefile.am Thu Sep 14 19:11:24 2006 +0000 @@ -21,6 +21,7 @@ demo/coloring \ demo/grid_ugraph_demo \ demo/topology_demo \ + demo/topological_ordering \ demo/simann_maxcut_demo \ demo/disjoint_paths_demo \ demo/strongly_connected_orientation @@ -78,6 +79,8 @@ demo_topology_demo_SOURCES = demo/topology_demo.cc +demo_topological_ordering_SOURCES = demo/topological_ordering.cc + demo_simann_maxcut_demo_SOURCES = demo/simann_maxcut_demo.cc demo_disjoint_paths_demo_SOURCES = demo/disjoint_paths_demo.cc diff -r 83ec156873ab -r 1e45cdeea3cc demo/topological_ordering.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/demo/topological_ordering.cc Thu Sep 14 19:11:24 2006 +0000 @@ -0,0 +1,115 @@ +/* -*- C++ -*- + * + * This file is a part of LEMON, a generic C++ optimization library + * + * Copyright (C) 2003-2006 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +///\ingroup demos +///\file +///\brief Demonstrating the Dfs class with topological ordering +/// +///\include topological_ordering.cc + +#include +#include +#include +#include +#include +#include + +using namespace lemon; + + +template< typename GR > +class SerializingWriteMap +{ +public: + typedef typename GR::Node Key; + typedef bool Value; + typedef std::list OrderedList; + + OrderedList order; + + SerializingWriteMap( const GR& gr ) {} + + void set( const Key& k, const Value& v ) { + if( v ) order.push_front(k); + } + + Value operator[] ( const Key& ) { + return false; + } +}; + + +int main( int argc, char *argv[] ) +{ + std::cout << "Topological Ordering demo" << std::endl; + + // Create and build the graph + ListGraph gr; + ListGraph::NodeMap label(gr); + typedef ListGraph::Node Node; + + // This DAG example for topological ordering is from the book New Algorithms + // (Thomas H. Cormen, Charles E. Leiserson, Ronald L. Rivest, Clifford Stein) + { + Node belt = gr.addNode(); + Node trousers = gr.addNode(); + Node necktie = gr.addNode(); + Node coat = gr.addNode(); + Node socks = gr.addNode(); + Node shirt = gr.addNode(); + Node shoe = gr.addNode(); + Node watch = gr.addNode(); + Node pants = gr.addNode(); + + label[belt] = "Belt"; + label[trousers] = "Trousers"; + label[necktie] = "Necktie"; + label[coat] = "Coat"; + label[socks] = "Socks"; + label[shirt] = "Shirt"; + label[shoe] = "Shoe"; + label[watch] = "Watch"; + label[pants] = "Pants"; + + // Here we use a directed edge to indicate precedenc. + // The source must precede the target. + gr.addEdge( socks, shoe ); + gr.addEdge( pants, shoe ); + gr.addEdge( pants, trousers ); + gr.addEdge( trousers, shoe ); + gr.addEdge( trousers, belt ); + gr.addEdge( belt, coat ); + gr.addEdge( shirt, belt ); + gr.addEdge( shirt, necktie ); + gr.addEdge( necktie, coat ); + } + + // Calculate topological order + Dfs::DefProcessedMapTraits > > dfs(gr); + SerializingWriteMap list(gr); + dfs.processedMap(list); + dfs.run(); + + // Write out the result + std::cout << "One possible order to dress up:"; + for( SerializingWriteMap::OrderedList::iterator it = list.order.begin(); it != list.order.end(); ++it ) + std::cout << " " << label[*it]; + std::cout << std::endl; + + return 0; +} diff -r 83ec156873ab -r 1e45cdeea3cc doc/Makefile.am --- a/doc/Makefile.am Thu Sep 14 19:02:52 2006 +0000 +++ b/doc/Makefile.am Thu Sep 14 19:11:24 2006 +0000 @@ -16,6 +16,7 @@ doc/graph_io.dox \ doc/graphs.dox \ doc/groups.dox \ + doc/lemon_file_format.dox \ doc/license.dox \ doc/mainpage.dox \ doc/maps.dox \ @@ -24,6 +25,7 @@ doc/named-param.dox \ doc/namespaces.dox \ doc/quicktour.dox \ + doc/read_write_bg.dox \ doc/ugraphs.dox doc: diff -r 83ec156873ab -r 1e45cdeea3cc doc/algorithms.dox --- a/doc/algorithms.dox Thu Sep 14 19:02:52 2006 +0000 +++ b/doc/algorithms.dox Thu Sep 14 19:11:24 2006 +0000 @@ -1,5 +1,130 @@ +namespace lemon { /** \page algorithms Algorithms -Place-holder page for algorithms. +\section algo_bfs_dfs Bfs/Dfs +Both \ref lemon::Bfs "Bfs" and \ref lemon::Dfs "Dfs" are highly adaptable and efficient +implementations of the well known algorithms. The algorithms are placed most cases in +separated files named after the algorithm itself but lower case as all other header file names. +For example the next Bfs class is in the \c lemon/bfs.h. + +\subsection Bfs +The algorithm is implemented in the \ref lemon::Bfs "Bfs" template class - rather than as function. +The class has two template parameters: \b GR and \TR.
+GR is the graph the algorithm runs on. It has \ref lemon::ListGraph "ListGraph" as default type. +TR is a Traits class commonly used to easy the parametrization of templates. In most cases you +wont need to modify the default type \ref lemon::BfsDefaultTraits "BfsDefaultTraits". + +To use the class, declare it! +\code +Bfs bfs(gr); +\endcode +Note the lack of second template argument because of the default parameter. + +It provides a simple but powerful interface to control the execution. +\code +int dist = bfs.run(s,t); +\endcode +It finds the shortest path from node \c s to node \c t and returns it, or zero +if there is no path from \c s to \c t.
+If you want the shortest path from a specified node to all other node, just write: +\code +bfs.run(s); +\endcode +Now the distances and path information are stored in maps which you can access with +member functions like \ref lemon::Bfs::distMap "distMap()" or \ref lemon::Bfs::predMap "predMap()".
+Or more directly whit other member functions like \c predNode(). Once the algorithm +is finished (or to be precise reached that node) \ref lemon::Bfs::dist "dist()" or \ref lemon::Bfs::predNode +"predNode()" can be called. + +For an example let's say we want to print the shortest path of those nodes which +are in a certain distance. +\code +bfs.run(s); + +for( ListUGraph::NodeIt n(gr); n != INVALID; ++n ) { + if( bfs.reached(n) && bfs.dist(n) <= max_dist ) { + std::cout << gr.id(n); + + Node prev = bfs.prevNode(n); + while( prev != INVALID ) { + std::cout << "<-" << gr.id(prev); + prev = bfs.prevNode(n); + } + + std::cout << std::endl; + } +} +\endcode + +\subsubsection bfs_adv_control Advanced control +In the previous code we only used \c run(). Now we introduce the way you can directly +control the execution of the algorithm. + +First you have to initialize the variables with \ref lemon::Bfs::init "init()". +\code + bfs.init(); +\endcode + +Then you add one or more source nodes to the queue. They will be processed, as they would +be reached by the algorithm before. And yes - you can add more sources during the execution. +\code + bfs.addSource(node_1); + bfs.addSource(node_2); + ... +\endcode + +And finally you can start the process with \ref lemon::Bfs::start "start()", or +you can write your own loop to process the nodes one-by-one. + +\todo demo for bfs advanced control + +\subsection Dfs +Since Dfs is very similar to Bfs with a few tiny differences we only see a bit more complex example +to demonstrate Dfs's capabilities. + +We will see a program, which solves the problem of topological ordering. +We need to know in which order we should put on our clothes. The program will do the following: +
    +
  1. We run the dfs algorithm to all nodes. +
  2. Put every node into a list when processed completely. +
  3. Write out the list in reverse order. +
+ +\dontinclude topological_ordering.cc +First of all we will need an own \ref lemon::Dfs::ProcessedMap "ProcessedMap". The ordering +will be done through it. +\skip SerializingWriteMap +\until }; +The class meets the \ref lemon::WriteMap "WriteMap" concept. In it's \c set() method the only thing +we need to do is insert the key - that is the node who's processing just finished - into the beginning +of the list. + +First we declare the needed data structures: the graph and a map to store the nodes' label. +\skip ListGraph +\until label + +Now we build a graph. But keep in mind that it must be DAG because cyclic graphs has no topological +ordering. +\skip belt +\until trousers +We label them... +\skip label +\until trousers +Then add directed edges which represent the precedences between those items. +\skip trousers, belt +\until ); + +See how easy is to access the internal information of this algorithm trough maps. +We only need to set our own map as the class's \ref lemon::Dfs::ProcessedMap "ProcessedMap". +\skip Dfs +\until run + +And now comes the third part. Write out the list in reverse order. But the list was +composed in reverse way (with \c push_front() instead of \c push_back() so we just iterate it. +\skip std +\until endl + +The program is to be found in the \ref demo directory: \ref topological_ordering.cc */ +} diff -r 83ec156873ab -r 1e45cdeea3cc doc/lemon_file_format.dox --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/doc/lemon_file_format.dox Thu Sep 14 19:11:24 2006 +0000 @@ -0,0 +1,270 @@ +namespace lemon { +/*! + + +\page lemon_file_format LEMON Graph File Format + +The standard graph IO enables one to store graphs and additional maps +(i.e. functions on the nodes or edges) in a flexible and efficient way. +Before you read this page you should be familiar with LEMON +\ref graphs "graphs" and \ref maps-page "maps". + +\section format The general file format + +The file contains sections in the following order: + +\li nodeset +\li edgeset +\li nodes +\li edges +\li attributes + +Some of these sections can be omitted, but you will basicly need the nodeset +section (unless your graph has no nodes at all) and the edgeset section +(unless your graph has no edges at all). + +The nodeset section describes the nodes of your graph: it identifies the nodes +and gives the maps defined on them, if any. It starts with the +following line: + +\@nodeset + +The next line contains the names of the nodemaps, separated by whitespaces. Each +following line describes a node in the graph: it contains the values of the +maps in the right order. The map named "label" should contain unique values +because it is regarded as a label map. These labels need not be numbers but they +must identify the nodes uniquely for later reference. For example: + +\code +@nodeset +label x-coord y-coord color +3 1.0 4.0 blue +5 2.3 5.7 red +12 7.8 2.3 green +\endcode + +The edgeset section is very similar to the nodeset section, it has +the same coloumn oriented structure. It starts with the line + +\@edgeset + +The next line contains the whitespace separated list of names of the edge +maps. Each of the next lines describes one edge. The first two elements in +the line are the labels of the source and target (or tail and head) nodes of the +edge as they occur in the label node map of the nodeset section. You can also +have an optional label map on the edges for later reference (which has to be +unique in this case). + +\code +@edgeset + label weight note +3 5 a 4.3 a-edge +5 12 c 2.6 c-edge +3 12 g 3.4 g-edge +\endcode + +The \e nodes section contains labeled (distinguished) nodes +(i.e. nodes having a special +label on them). The section starts with + + \@nodes + +Each of the next lines contains a label for a node in the graph +and then the label as described in the \e nodeset section. + +\code +@nodes +source 3 +target 12 +\endcode + +The last section describes the labeled (distinguished) edges +(i.e. edges having a special label on them). It starts with \c \@edges +and then each line contains the name of the edge and the label. + +\code +@edges +observed c +\endcode + + +The file may contain empty lines and comment lines. The comment lines +start with an \c # character. + +The attributes section can handle some information about the graph. It +contains key-value pairs in each line (a key and the mapped value to key). The +key should be a string without whitespaces, the value can be of various types. + +\code +@attributes +title "Four colored planar graph" +author "Balazs DEZSO" +copyright "Lemon Library" +version 12 +\endcode + +Finally, the file should be closed with \c \@end line. + + +\section use Using graph input-output + + +The graph input and output is based on reading and writing +commands. The user gives reading and writing commands to the reader or +writer class, then he calls the \c run() method that executes all the given +commands. + +\subsection write Writing a graph + +The \ref lemon::GraphWriter "GraphWriter" template class +provides the graph output. To write a graph +you should first give writing commands to the writer. You can declare +writing command as \c NodeMap or \c EdgeMap writing and labeled Node and +Edge writing. + +\code +GraphWriter writer(std::cout, graph); +\endcode + +The \ref lemon::GraphWriter::writeNodeMap() "writeNodeMap()" +function declares a \c NodeMap writing command in the +\ref lemon::GraphWriter "GraphWriter". +You should give a name to the map and the map +object as parameters. The NodeMap writing command with name "label" should write a +unique map because it will be regarded as a label map. + +\see IdMap, DescriptorMap + +\code +IdMap nodeLabelMap; +writer.writeNodeMap("label", nodeLabelMap); + +writer.writeNodeMap("x-coord", xCoordMap); +writer.writeNodeMap("y-coord", yCoordMap); +writer.writeNodeMap("color", colorMap); +\endcode + +With the \ref lemon::GraphWriter::writeEdgeMap() "writeEdgeMap()" +member function you can give an edge map +writing command similar to the NodeMaps. + +\see IdMap, DescriptorMap + +\code +DescriptorMap > edgeDescMap(graph); +writer.writeEdgeMap("descriptor", edgeDescMap); + +writer.writeEdgeMap("weight", weightMap); +writer.writeEdgeMap("note", noteMap); +\endcode + +With \ref lemon::GraphWriter::writeNode() "writeNode()" +and \ref lemon::GraphWriter::writeEdge() "writeEdge()" +functions you can designate Nodes and +Edges in the graph. For example, you can write out the source and target node +of a maximum flow instance. + +\code +writer.writeNode("source", sourceNode); +writer.writeNode("target", targetNode); + +writer.writeEdge("observed", edge); +\endcode + +With \ref lemon::GraphWriter::writeAttribute() "writeAttribute()" +function you can write an attribute to the file. + +\code +writer.writeAttribute("author", "Balazs DEZSO"); +writer.writeAttribute("version", 12); +\endcode + +After you give all write commands you must call the +\ref lemon::GraphWriter::run() "run()" member +function, which executes all the writing commands. + +\code +writer.run(); +\endcode + +\subsection reading Reading a graph + +The file to be read may contain several maps and labeled nodes or edges. +If you read a graph you need not read all the maps and items just those +that you need. The interface of the \ref lemon::GraphReader "GraphReader" +is very similar to +the \ref lemon::GraphWriter "GraphWriter" +but the reading method does not depend on the order of the +given commands. + +The reader object assumes that each not read value does not contain +whitespaces, therefore it has some extra possibilities to control how +it should skip the values when the string representation contains spaces. + +\code +GraphReader reader(std::cin, graph); +\endcode + +The \ref lemon::GraphReader::readNodeMap() "readNodeMap()" +function reads a map from the \c nodeset section. +If there is a map that you do not want to read from the file and there are +whitespaces in the string represenation of the values then you should +call the \ref lemon::GraphReader::skipNodeMap() "skipNodeMap()" +template member function with proper parameters. + +\see QuotedStringReader + +\code +reader.readNodeMap("x-coord", xCoordMap); +reader.readNodeMap("y-coord", yCoordMap); + +reader.readNodeMap("label", labelMap); +reader.skipNodeMap("description"); + +reader.readNodeMap("color", colorMap); +\endcode + +With the \ref lemon::GraphReader::readEdgeMap() "readEdgeMap()" +member function you can give an edge map +reading command similar to the NodeMaps. + +\code +reader.readEdgeMap("weight", weightMap); +reader.readEdgeMap("label", labelMap); +\endcode + +With \ref lemon::GraphReader::readNode() "readNode()" +and \ref lemon::GraphReader::readEdge() "readEdge()" +functions you can read labeled Nodes and +Edges. + +\code +reader.readNode("source", sourceNode); +reader.readNode("target", targetNode); + +reader.readEdge("observed", edge); +\endcode + +With \ref lemon::GraphReader::readAttribute() "readAttribute()" +function you can read an attribute from the file. + +\code +std::string author; +writer.readAttribute("author", author); +int version; +writer.writeAttribute("version", version); +\endcode + +After you give all read commands you must call the +\ref lemon::GraphReader::run() "run()" member +function, which executes all the commands. + +\code +reader.run(); +\endcode + +If you want to lear more, read the \ref read_write_bg "background technics". + +\author Balazs Dezso +*/ +} diff -r 83ec156873ab -r 1e45cdeea3cc doc/read_write_bg.dox --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/doc/read_write_bg.dox Thu Sep 14 19:11:24 2006 +0000 @@ -0,0 +1,219 @@ +namespace lemon { +/*! +\page read_write_bg Background of Reading and Writing + +To read a map (on the nodes or edges) +the \ref lemon::GraphReader "GraphReader" +should know how to read a Value from the given map. +By the default implementation the input operator reads a value from +the stream and the type of the read value is the value type of the given map. +When the reader should skip a value in the stream, because you do not +want to store it in a map, the reader skips a character sequence without +whitespaces. + +If you want to change the functionality of the reader, you can use +template parameters to specialize it. When you give a reading +command for a map you can give a Reader type as template parameter. +With this template parameter you can control how the Reader reads +a value from the stream. + +The reader has the next structure: +\code +struct TypeReader { + typedef TypeName Value; + + void read(std::istream& is, Value& value); +}; +\endcode + +For example, the \c "strings" nodemap contains strings and you do not need +the value of the string just the length. Then you can implement an own Reader +struct. + +\code +struct LengthReader { + typedef int Value; + + void read(std::istream& is, Value& value) { + std::string tmp; + is >> tmp; + value = tmp.length(); + } +}; +... +reader.readNodeMap("strings", lengthMap); +\endcode + +The global functionality of the reader class can be changed by giving a +special template parameter to the GraphReader class. By default, the +template parameter is \c DefaultReaderTraits. A reader traits class +should provide a nested template class Reader for each type, and a +DefaultReader for skipping a value. + +The specialization of writing is very similar to that of reading. + +\section u Undirected graphs + +In a file describing an undirected graph (ugraph, for short) you find an +\c uedgeset section instead of the \c edgeset section. The first line of +the section describes the names of the maps on the undirected egdes and all +next lines describe one undirected edge with the the incident nodes and the +values of the map. + +The format handles directed edge maps as a syntactical sugar???, if there +are two maps with names being the same with a \c '+' and a \c '-' prefix +then this will be read as a directed map. + +\code +@uedgeset + label capacity +flow -flow +32 2 1 4.3 2.0 0.0 +21 21 5 2.6 0.0 2.6 +21 12 8 3.4 0.0 0.0 +\endcode + +The \c edges section is changed to \c uedges section. This section +describes labeled edges and undirected edges. The directed edge label +should start with a \c '+' or a \c '-' prefix to decide the direction +of the edge. + +\code +@uedges +uedge 1 ++edge 5 +-back 5 +\endcode + +There are similar classes to the \ref lemon::GraphReader "GraphReader" and +\ref lemon::GraphWriter "GraphWriter" which +handle the undirected graphs. These classes are +the \ref lemon::UGraphReader "UGraphReader" +and \ref lemon::UGraphWriter "UGraphWriter". + +The \ref lemon::UGraphReader::readUEdgeMap() "readUEdgeMap()" +function reads an undirected map and the +\ref lemon::UGraphReader::readUEdge() "readUEdge()" +reads an undirected edge from the file, + +\code +reader.readUEdgeMap("capacity", capacityMap); +reader.readEdgeMap("flow", flowMap); +... +reader.readUEdge("u_edge", u_edge); +reader.readEdge("edge", edge); +\endcode + +\section advanced Advanced features + +The graph reader and writer classes give an easy way to read and write +graphs. But sometimes we want more advanced features. In this case we can +use the more general lemon reader and writer interface. + +The LEMON file format is a section oriented file format. It contains one or +more sections, each starting with a line identifying its type +(the word starting with the \c \@ character). +The content of the section this way cannot contain line with \c \@ first +character. The file may contains comment lines with \c # first character. + +The \ref lemon::LemonReader "LemonReader" +and \ref lemon::LemonWriter "LemonWriter" +gives a framework to read and +write sections. There are various section reader and section writer +classes which can be attached to a \ref lemon::LemonReader "LemonReader" +or a \ref lemon::LemonWriter "LemonWriter". + +There are default section readers and writers for reading and writing +item sets, and labeled items in the graph. These read and write +the format described above. Other type of data can be handled with own +section reader and writer classes which are inherited from the +\c LemonReader::SectionReader or the +\ref lemon::LemonWriter::SectionWriter "LemonWriter::SectionWriter" +classes. + +The next example defines a special section reader which reads the +\c \@description sections into a string: + +\code +class DescriptionReader : LemonReader::SectionReader { +protected: + virtual bool header(const std::string& line) { + std::istringstream ls(line); + std::string head; + ls >> head; + return head == "@description"; + } + + virtual void read(std::istream& is) { + std::string line; + while (getline(is, line)) { + desc += line; + } + } +public: + + typedef LemonReader::SectionReader Parent; + + DescriptionReader(LemonReader& reader) : Parent(reader) {} + + const std::string& description() const { + return description; + } + +private: + std::string desc; +}; +\endcode + +The other advanced stuff of the generalized file format is that +multiple edgesets can be stored to the same nodeset. It can be used +for example as a network traffic matrix. + +In our example there is a network with symmetric links and there are assymetric +traffic request on the network. This construction can be stored in an +undirected graph and in a directed \c ListEdgeSet class. The example +shows the input with the \ref lemon::LemonReader "LemonReader" class: + +\code +ListUGraph network; +ListUGraph::UEdgeMap capacity; +ListEdgeSet traffic(network); +ListEdgeSet::EdgeMap request(network); + +LemonReader reader(std::cin); +NodeSetReader nodesetReader(reader, network); +UEdgeSetReader + uEdgesetReader(reader, network, nodesetReader); +uEdgesetReader.readEdgeMap("capacity", capacity); +EdgeSetReader > + edgesetReader(reader, traffic, nodesetReader, "traffic"); +edgesetReader.readEdgeMap("request", request); + +reader.run(); +\endcode + +Because both the \ref lemon::GraphReader "GraphReader" +and the \ref lemon::UGraphReader "UGraphReader" can be converted +to \ref lemon::LemonReader "LemonReader" +and it can resolve the label's of the items, the previous +result can be achived with the \ref lemon::UGraphReader "UGraphReader" +class, too. + + +\code +ListUGraph network; +ListUGraph::UEdgeSet capacity; +ListEdgeSet traffic(network); +ListEdgeSet::EdgeMap request(network); + +UGraphReader reader(std::cin, network); +reader.readEdgeMap("capacity", capacity); +EdgeSetReader > + edgesetReader(reader, traffic, reader, "traffic"); +edgesetReader.readEdgeMap("request", request); + +reader.run(); +\endcode + +\author Balazs Dezso +*/ +} diff -r 83ec156873ab -r 1e45cdeea3cc doc/tutorial.dox --- a/doc/tutorial.dox Thu Sep 14 19:02:52 2006 +0000 +++ b/doc/tutorial.dox Thu Sep 14 19:11:24 2006 +0000 @@ -1,3 +1,4 @@ +namespace lemon { /** \page Tutorial LEMON Tutorial @@ -15,24 +16,27 @@
  • \ref basic_ListGraph
  • \ref maps1 -
  • Lemon Graph File Format +
  • \ref lemon_file_format +
      +
    • \ref read_write_bg +
  • \ref algorithms
  • \ref maps2 -
  • Show a graph -
  • Miscellaneous Tool +
  • Show a graph +
  • Miscellaneous Tool @@ -42,3 +46,4 @@ are all available in \c demo directory, so feel free to look at them after the sections. */ +}