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