COIN-OR::LEMON - Graph Library

source: lemon-0.x/lemon/graph_writer.h @ 1909:2d806130e700

Last change on this file since 1909:2d806130e700 was 1909:2d806130e700, checked in by Mihaly Barasz, 14 years ago

Undir -> U transition

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