COIN-OR::LEMON - Graph Library

source: lemon-0.x/lemon/graph_writer.h @ 2025:93fcadf94ab0

Last change on this file since 2025:93fcadf94ab0 was 1956:a055123339d5, checked in by Alpar Juttner, 18 years ago

Unified copyright notices

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