lemon/graph_writer.h
author deba
Tue, 17 Oct 2006 10:50:57 +0000
changeset 2247 269a0dcee70b
parent 2083 f50c8c191cbd
child 2386 81b47fc5c444
permissions -rw-r--r--
Update the Path concept
Concept check for paths

DirPath renamed to Path
The interface updated to the new lemon interface
Make difference between the empty path and the path from one node
Builder interface have not been changed
// I wanted but there was not accordance about it

UPath is removed
It was a buggy implementation, it could not iterate on the
nodes in the right order
Right way to use undirected paths => path of edges in undirected graphs

The tests have been modified to the current implementation
     1 /* -*- C++ -*-
     2  *
     3  * This file is a part of LEMON, a generic C++ optimization library
     4  *
     5  * Copyright (C) 2003-2006
     6  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
     7  * (Egervary Research Group on Combinatorial Optimization, EGRES).
     8  *
     9  * Permission to use, modify and distribute this software is granted
    10  * provided that this copyright notice appears in all copies. For
    11  * precise terms see the accompanying LICENSE file.
    12  *
    13  * This software is provided "AS IS" with no warranty of any kind,
    14  * express or implied, and with no claim as to its suitability for any
    15  * purpose.
    16  *
    17  */
    18 
    19 ///\ingroup lemon_io
    20 ///\file
    21 ///\brief Lemon Graph Format writer.
    22 ///
    23 
    24 #ifndef LEMON_GRAPH_WRITER_H
    25 #define LEMON_GRAPH_WRITER_H
    26 
    27 #include <iostream>
    28 
    29 #include <lemon/error.h>
    30 #include <lemon/lemon_writer.h>
    31 
    32 namespace lemon {
    33 
    34   /// \addtogroup lemon_io
    35   /// @{
    36 
    37   /// \brief The graph writer class.
    38   ///
    39   /// The \c GraphWriter class provides the graph output.  Before you
    40   /// read this documentation it might be useful to read the general
    41   /// description of \ref graph-io-page "Graph Input-Output".
    42   ///
    43   /// To write a graph you should first give writing commands to the
    44   /// writer. You can declare write commands as \c NodeMap or \c
    45   /// EdgeMap writing and labeled Node and Edge writing.
    46   ///
    47   ///\code
    48   /// GraphWriter<ListGraph> writer(std::cout, graph);
    49   ///\endcode
    50   ///
    51   /// The \c writeNodeMap() function declares a \c NodeMap writing
    52   /// command in the \c GraphWriter. You should give as parameter the
    53   /// name of the map and the map object. The NodeMap writing command
    54   /// with name "label" should write a unique map because it is
    55   /// regarded as label map (such a map is essential if the graph has
    56   /// edges).
    57   ///
    58   ///\code
    59   /// IdMap<ListGraph, Node> nodeLabelMap;
    60   /// writer.writeNodeMap("label", nodeLabelMap);
    61   ///
    62   /// writer.writeNodeMap("coords", coords);
    63   /// writer.writeNodeMap("color", colorMap);
    64   ///\endcode
    65   ///
    66   /// With the \c writeEdgeMap() member function you can give an edge map
    67   /// writing command similar to the NodeMaps.
    68   ///
    69   ///\code
    70   /// DescriptorMap<ListGraph, Edge, ListGraph::EdgeMap<int> > 
    71   ///   edgeDescMap(graph);
    72   /// writer.writeEdgeMap("descriptor", edgeDescMap);
    73   ///
    74   /// writer.writeEdgeMap("weight", weightMap);
    75   /// writer.writeEdgeMap("label", labelMap);
    76   ///\endcode
    77   ///
    78   /// With \c writeNode() and \c writeEdge() functions you can 
    79   /// point out Nodes and Edges in the graph. For example, you can 
    80   /// write out the source and target of a maximum flow instance.
    81   ///
    82   ///\code
    83   /// writer.writeNode("source", sourceNode);
    84   /// writer.writeNode("target", targetNode);
    85   ///
    86   /// writer.writeEdge("observed", edge);
    87   ///\endcode
    88   ///
    89   /// After you give all write commands you must call the \c run() member
    90   /// function, which executes all the writing commands.
    91   ///
    92   ///\code
    93   /// writer.run();
    94   ///\endcode
    95   ///
    96   /// \see DefaultWriterTraits
    97   /// \see QuotedStringWriter
    98   /// \see IdMap
    99   /// \see DescriptorMap
   100   /// \see \ref GraphReader
   101   /// \see \ref graph-io-page
   102   /// \author Balazs Dezso
   103   template <typename _Graph, typename _WriterTraits = DefaultWriterTraits> 
   104   class GraphWriter {
   105   public:
   106     
   107     typedef _Graph Graph;
   108     typedef typename Graph::Node Node;
   109     typedef typename Graph::Edge Edge;
   110 
   111     typedef _WriterTraits WriterTraits;
   112 
   113     /// \brief Construct a new GraphWriter.
   114     ///
   115     /// This function constructs a new GraphWriter to write the given graph
   116     /// to the given stream.
   117     GraphWriter(std::ostream& _os, const Graph& _graph) 
   118       : writer(new LemonWriter(_os)), own_writer(true), 
   119 	nodeset_writer(*writer, _graph, std::string()),
   120 	edgeset_writer(*writer, _graph, nodeset_writer, std::string()),
   121 	node_writer(*writer, nodeset_writer, std::string()),
   122 	edge_writer(*writer, edgeset_writer, std::string()),
   123 	attribute_writer(*writer, std::string()) {}
   124 
   125     /// \brief Construct a new GraphWriter.
   126     ///
   127     /// This function constructs a new GraphWriter to write the given graph
   128     /// to the given file.
   129     GraphWriter(const std::string& _filename, const Graph& _graph) 
   130       : writer(new LemonWriter(_filename)), own_writer(true), 
   131 	nodeset_writer(*writer, _graph, std::string()),
   132 	edgeset_writer(*writer, _graph, nodeset_writer, std::string()),
   133 	node_writer(*writer, nodeset_writer, std::string()),
   134 	edge_writer(*writer, edgeset_writer, std::string()),
   135 	attribute_writer(*writer, std::string()) {}
   136 
   137     /// \brief Construct a new GraphWriter.
   138     ///
   139     /// This function constructs a new GraphWriter to write the given graph
   140     /// to the given LemonReader.
   141     GraphWriter(LemonWriter& _writer, const Graph& _graph)
   142       : writer(_writer), own_writer(false), 
   143 	nodeset_writer(*writer, _graph, std::string()),
   144 	edgeset_writer(*writer, _graph, nodeset_writer, std::string()),
   145 	node_writer(*writer, nodeset_writer, std::string()),
   146 	edge_writer(*writer, edgeset_writer, std::string()),
   147 	attribute_writer(*writer, std::string()) {}
   148 
   149     /// \brief Destruct the graph writer.
   150     ///
   151     /// This function destructs the graph writer.
   152     ~GraphWriter() {
   153       if (own_writer) 
   154 	delete writer;
   155     }
   156 
   157     /// \brief Issue a new node map writing command for the writer.
   158     ///
   159    /// This function issues a new <i> node map writing command</i> to the writer.
   160     template <typename Map>
   161     GraphWriter& writeNodeMap(std::string name, const Map& map) {
   162       nodeset_writer.writeNodeMap(name, map);
   163       return *this;
   164     }
   165 
   166 
   167     /// \brief Issue a new node map writing command for the writer.
   168     ///
   169    /// This function issues a new <i> node map writing command</i> to the writer.
   170     template <typename Writer, typename Map>
   171     GraphWriter& writeNodeMap(std::string name, const Map& map, 
   172 			      const Writer& writer = Writer()) {
   173       nodeset_writer.writeNodeMap(name, map, writer);
   174       return *this;
   175     }
   176 
   177 
   178     /// \brief Issue a new edge map writing command for the writer.
   179     ///
   180    /// This function issues a new <i> edge map writing command</i> to the writer.
   181     template <typename Map>
   182     GraphWriter& writeEdgeMap(std::string name, const Map& map) { 
   183       edgeset_writer.writeEdgeMap(name, map);
   184       return *this;
   185     }
   186 
   187 
   188     /// \brief Issue a new edge map writing command for the writer.
   189     ///
   190    /// This function issues a new <i> edge map writing command</i> to the writer.
   191     template <typename Writer, typename Map>
   192     GraphWriter& writeEdgeMap(std::string name, const Map& map,
   193 			      const Writer& writer = Writer()) {
   194       edgeset_writer.writeEdgeMap(name, map, writer);
   195       return *this;
   196     }
   197 
   198     /// \brief Issue a new labeled node writing command to the writer.
   199     ///
   200     /// This function issues a new <i> labeled node writing command</i> 
   201     /// to the writer.
   202     GraphWriter& writeNode(std::string name, const Node& node) {
   203       node_writer.writeNode(name, node);
   204       return *this;
   205     }
   206 
   207     /// \brief Issue a new labeled edge writing command to the writer.
   208     ///
   209     /// This function issues a new <i> labeled edge writing command</i> 
   210     /// to the writer.
   211     GraphWriter& writeEdge(std::string name, const Edge& edge) {
   212       edge_writer.writeEdge(name, edge);
   213     }
   214 
   215     /// \brief Issue a new attribute writing command.
   216     ///
   217     /// This function issues a new <i> attribute writing command</i> 
   218     /// to the writer.
   219     template <typename Value>
   220     GraphWriter& writeAttribute(std::string name, const Value& value) {
   221       attribute_writer.writeAttribute(name, value);
   222       return *this;
   223     }
   224     
   225     /// \brief Issue a new attribute writing command.
   226     ///
   227     /// This function issues a new <i> attribute writing command</i> 
   228     /// to the writer.
   229     template <typename Writer, typename Value>
   230     GraphWriter& writeAttribute(std::string name, const Value& value, 
   231 			       const Writer& writer) {
   232       attribute_writer.writeAttribute<Writer>(name, value, writer);
   233       return *this;
   234     }
   235 
   236     /// \brief Conversion operator to LemonWriter.
   237     ///
   238     /// Conversion operator to LemonWriter. It makes possible
   239     /// to access the encapsulated \e LemonWriter, this way
   240     /// you can attach to this writer new instances of 
   241     /// \e LemonWriter::SectionWriter. For more details see
   242     /// the \ref rwbackground "Background of Reading and Writing".
   243     operator LemonWriter&() {
   244       return *writer;
   245     }
   246 
   247     /// \brief Executes the writing commands.
   248     ///
   249     /// Executes the writing commands.
   250     void run() {
   251       writer->run();
   252     }
   253 
   254     /// \brief Write the label of the given node.
   255     ///
   256     /// It writes the label of the given node. If there was written an "label"
   257     /// named node map then it will write the map value belonging to the node.
   258     void writeLabel(std::ostream& os, const Node& item) const {
   259       nodeset_writer.writeLabel(os, item);
   260     } 
   261 
   262     /// \brief Write the label of the given edge.
   263     ///
   264     /// It writes the label of the given edge. If there was written an "label"
   265     /// named edge map then it will write the map value belonging to the edge.
   266     void writeLabel(std::ostream& os, const Edge& item) const {
   267       edgeset_writer.writeLabel(os, item);
   268     } 
   269 
   270   private:
   271 
   272     LemonWriter* writer;
   273     bool own_writer;
   274 
   275     NodeSetWriter<Graph, WriterTraits> nodeset_writer;
   276     EdgeSetWriter<Graph, WriterTraits> edgeset_writer;
   277 
   278     NodeWriter<Graph> node_writer;
   279     EdgeWriter<Graph> edge_writer;
   280     
   281     AttributeWriter<WriterTraits> attribute_writer;
   282   };
   283 
   284 
   285   /// \brief The undirected graph writer class.
   286   ///
   287   /// The \c UGraphWriter class provides the ugraph output. To write 
   288   /// a graph you should first give writing commands to the writer. You can 
   289   /// declare write command as \c NodeMap, \c EdgeMap or \c UEdgeMap 
   290   /// writing and labeled Node, Edge or UEdge writing.
   291   ///
   292   ///\code
   293   /// UGraphWriter<ListUGraph> writer(std::cout, graph);
   294   ///\endcode
   295   ///
   296   /// The \c writeNodeMap() function declares a \c NodeMap writing 
   297   /// command in the \c UGraphWriter. You should give as parameter 
   298   /// the name of the map and the map object. The NodeMap writing 
   299   /// command with name "label" should write a unique map because it 
   300   /// is regarded as label map.
   301   ///
   302   ///\code
   303   /// IdMap<ListUGraph, Node> nodeLabelMap;
   304   /// writer.writeNodeMap("label", nodeLabelMap);
   305   ///
   306   /// writer.writeNodeMap("coords", coords);
   307   /// writer.writeNodeMap("color", colorMap);
   308   ///\endcode
   309   ///
   310   /// With the \c writeUEdgeMap() member function you can give an 
   311   /// undirected edge map writing command similar to the NodeMaps.
   312   ///
   313   ///\code
   314   /// DescriptorMap<ListGraph, Edge, ListGraph::EdgeMap<int> > 
   315   ///   edgeDescMap(graph);
   316   /// writer.writeUEdgeMap("descriptor", edgeDescMap);
   317   ///
   318   /// writer.writeUEdgeMap("weight", weightMap);
   319   /// writer.writeUEdgeMap("label", labelMap);
   320   ///\endcode
   321   /// 
   322   /// The EdgeMap handling is just a syntactical sugar. It writes
   323   /// two undirected edge map with '+' and '-' prefix in the name.
   324   ///
   325   ///\code
   326   /// writer.writeEdgeMap("capacity", capacityMap);
   327   ///\endcode
   328   ///
   329   ///
   330   /// With \c writeNode() and \c writeUEdge() functions you can 
   331   /// designate nodes and undirected edges in the graph. For example, you can 
   332   /// write out the source and target of the graph.
   333   ///
   334   ///\code
   335   /// writer.writeNode("source", sourceNode);
   336   /// writer.writeNode("target", targetNode);
   337   ///
   338   /// writer.writeUEdge("observed", uEdge);
   339   ///\endcode
   340   ///
   341   /// After you give all write commands you must call the \c run() member
   342   /// function, which executes all the writing commands.
   343   ///
   344   ///\code
   345   /// writer.run();
   346   ///\endcode
   347   ///
   348   /// \see DefaultWriterTraits
   349   /// \see QuotedStringWriter
   350   /// \see IdMap
   351   /// \see DescriptorMap
   352   /// \see \ref GraphWriter
   353   /// \see \ref graph-io-page
   354   /// \author Balazs Dezso
   355   template <typename _Graph, typename _WriterTraits = DefaultWriterTraits> 
   356   class UGraphWriter {
   357   public:
   358     
   359     typedef _Graph Graph;
   360     typedef typename Graph::Node Node;
   361     typedef typename Graph::Edge Edge;
   362     typedef typename Graph::UEdge UEdge;
   363 
   364     typedef _WriterTraits WriterTraits;
   365 
   366     /// \brief Construct a new UGraphWriter.
   367     ///
   368     /// Construct a new UGraphWriter. It writes the given graph
   369     /// to the given stream.
   370     UGraphWriter(std::ostream& _os, const Graph& _graph) 
   371       : writer(new LemonWriter(_os)), own_writer(true), 
   372 	nodeset_writer(*writer, _graph, std::string()),
   373 	u_edgeset_writer(*writer, _graph, nodeset_writer, std::string()),
   374 	node_writer(*writer, nodeset_writer, std::string()),
   375 	u_edge_writer(*writer, u_edgeset_writer, std::string()),
   376 	attribute_writer(*writer, std::string()) {}
   377 
   378     /// \brief Construct a new UGraphWriter.
   379     ///
   380     /// Construct a new UGraphWriter. It writes the given graph
   381     /// to the given file.
   382     UGraphWriter(const std::string& _filename, const Graph& _graph) 
   383       : writer(new LemonWriter(_filename)), own_writer(true), 
   384 	nodeset_writer(*writer, _graph, std::string()),
   385 	u_edgeset_writer(*writer, _graph, nodeset_writer, std::string()),
   386 	node_writer(*writer, nodeset_writer, std::string()),
   387 	u_edge_writer(*writer, u_edgeset_writer, std::string()),
   388 	attribute_writer(*writer, std::string()) {}
   389 
   390     /// \brief Construct a new UGraphWriter.
   391     ///
   392     /// Construct a new UGraphWriter. It writes the given graph
   393     /// to given LemonReader.
   394     UGraphWriter(LemonWriter& _writer, const Graph& _graph)
   395       : writer(_writer), own_writer(false), 
   396 	nodeset_writer(*writer, _graph, std::string()),
   397 	u_edgeset_writer(*writer, _graph, nodeset_writer, std::string()),
   398 	node_writer(*writer, nodeset_writer, std::string()),
   399 	u_edge_writer(*writer, u_edgeset_writer, std::string()),
   400 	attribute_writer(*writer, std::string()) {}
   401 
   402     /// \brief Destruct the graph writer.
   403     ///
   404     /// Destruct the graph writer.
   405     ~UGraphWriter() {
   406       if (own_writer) 
   407 	delete writer;
   408     }
   409 
   410     /// \brief Issue a new node map writing command to the writer.
   411     ///
   412     /// This function issues a new <i> node map writing command</i> to
   413     /// the writer.
   414     template <typename Map>
   415     UGraphWriter& writeNodeMap(std::string name, const Map& map) {
   416       nodeset_writer.writeNodeMap(name, map);
   417       return *this;
   418     }
   419 
   420     /// \brief Issue a new node map writing command to the writer.
   421     ///
   422     /// This function issues a new <i> node map writing command</i> to
   423     /// the writer.
   424     template <typename Writer, typename Map>
   425     UGraphWriter& writeNodeMap(std::string name, const Map& map, 
   426 			      const Writer& writer = Writer()) {
   427       nodeset_writer.writeNodeMap(name, map, writer);
   428       return *this;
   429     }
   430 
   431     /// \brief Issue a new edge map writing command to the writer.
   432     ///
   433     /// This function issues a new <i> edge map writing command</i> to
   434     /// the writer.
   435     template <typename Map>
   436     UGraphWriter& writeEdgeMap(std::string name, const Map& map) { 
   437       u_edgeset_writer.writeEdgeMap(name, map);
   438       return *this;
   439     }
   440 
   441     /// \brief Issue a new edge map writing command to the writer.
   442     ///
   443     /// This function issues a new <i> edge map writing command</i> to
   444     /// the writer.
   445     template <typename Writer, typename Map>
   446     UGraphWriter& writeEdgeMap(std::string name, const Map& map,
   447 				   const Writer& writer = Writer()) {
   448       u_edgeset_writer.writeEdgeMap(name, map, writer);
   449       return *this;
   450     }
   451 
   452     /// \brief Issue a new undirected edge map writing command to the writer.
   453     ///
   454     /// This function issues a new <i> undirected edge map writing
   455     /// command</i> to the writer.
   456     template <typename Map>
   457     UGraphWriter& writeUEdgeMap(std::string name, const Map& map) { 
   458       u_edgeset_writer.writeUEdgeMap(name, map);
   459       return *this;
   460     }
   461 
   462     /// \brief Issue a new undirected edge map writing command to the writer.
   463     ///
   464     /// This function issues a new <i> undirected edge map writing
   465     /// command</i> to the writer.
   466    template <typename Writer, typename Map>
   467     UGraphWriter& writeUEdgeMap(std::string name, const Map& map,
   468 					const Writer& writer = Writer()) {
   469       u_edgeset_writer.writeUEdgeMap(name, map, writer);
   470       return *this;
   471     }
   472 
   473     /// \brief Issue a new labeled node writer to the writer.
   474     ///
   475     /// This function issues a new <i> labeled node writing
   476     /// command</i> to the writer.
   477     UGraphWriter& writeNode(std::string name, const Node& node) {
   478       node_writer.writeNode(name, node);
   479       return *this;
   480     }
   481 
   482     /// \brief Issue a new labeled edge writer to the writer.
   483     ///
   484     /// This function issues a new <i> labeled edge writing
   485     /// command</i> to the writer.
   486     UGraphWriter& writeEdge(std::string name, const Edge& edge) {
   487       u_edge_writer.writeEdge(name, edge);
   488     }
   489 
   490     /// \brief Issue a new labeled undirected edge writing command to
   491     /// the writer.
   492     ///
   493     /// Issue a new <i>labeled undirected edge writing command</i> to
   494     /// the writer.
   495     UGraphWriter& writeUEdge(std::string name, const UEdge& edge) {
   496       u_edge_writer.writeUEdge(name, edge);
   497     }
   498 
   499     /// \brief Issue a new attribute writing command.
   500     ///
   501     /// This function issues a new <i> attribute writing
   502     /// command</i> to the writer.
   503     template <typename Value>
   504     UGraphWriter& writeAttribute(std::string name, const Value& value) {
   505       attribute_writer.writeAttribute(name, value);
   506       return *this;
   507     }
   508     
   509     /// \brief Issue a new attribute writing command.
   510     ///
   511     /// This function issues a new <i> attribute writing
   512     /// command</i> to the writer.
   513     template <typename Writer, typename Value>
   514     UGraphWriter& writeAttribute(std::string name, const Value& value, 
   515 			       const Writer& writer) {
   516       attribute_writer.writeAttribute<Writer>(name, value, writer);
   517       return *this;
   518     }
   519 
   520     /// \brief Conversion operator to LemonWriter.
   521     ///
   522     /// Conversion operator to LemonWriter. It makes possible
   523     /// to access the encapsulated \e LemonWriter, this way
   524     /// you can attach to this writer new instances of 
   525     /// \e LemonWriter::SectionWriter.
   526     operator LemonWriter&() {
   527       return *writer;
   528     }
   529 
   530     /// \brief Executes the writing commands.
   531     ///
   532     /// Executes the writing commands.
   533     void run() {
   534       writer->run();
   535     }
   536 
   537     /// \brief Write the label of the given node.
   538     ///
   539     /// It writes the label of the given node. If there was written an "label"
   540     /// named node map then it will write the map value belonging to the node.
   541     void writeLabel(std::ostream& os, const Node& item) const {
   542       nodeset_writer.writeLabel(os, item);
   543     } 
   544 
   545     /// \brief Write the label of the given edge.
   546     ///
   547     /// It writes the label of the given edge. If there was written an "label"
   548     /// named edge map then it will write the map value belonging to the edge.
   549     void writeLabel(std::ostream& os, const Edge& item) const {
   550       u_edgeset_writer.writeLabel(os, item);
   551     } 
   552 
   553     /// \brief Write the label of the given undirected edge.
   554     ///
   555     /// It writes the label of the given undirected edge. If there was
   556     /// written an "label" named edge map then it will write the map
   557     /// value belonging to the edge.
   558     void writeLabel(std::ostream& os, const UEdge& item) const {
   559       u_edgeset_writer.writeLabel(os, item);
   560     } 
   561 
   562 
   563   private:
   564 
   565     LemonWriter* writer;
   566     bool own_writer;
   567 
   568     NodeSetWriter<Graph, WriterTraits> nodeset_writer;
   569     UEdgeSetWriter<Graph, WriterTraits> u_edgeset_writer;
   570 
   571     NodeWriter<Graph> node_writer;
   572     UEdgeWriter<Graph> u_edge_writer;
   573     
   574     AttributeWriter<WriterTraits> attribute_writer;
   575   };
   576 
   577   /// @}
   578 
   579 }
   580 
   581 #endif