COIN-OR::LEMON - Graph Library

source: lemon-0.x/lemon/graph_writer.h @ 2476:059dcdda37c5

Last change on this file since 2476:059dcdda37c5 was 2467:2025a571895e, checked in by Balazs Dezso, 12 years ago

PathNodeIt?

PathWriter/Reader? structures
Distinict MapSet? readers and writers

File size: 21.9 KB
Line 
1/* -*- C++ -*-
2 *
3 * This file is a part of LEMON, a generic C++ optimization library
4 *
5 * Copyright (C) 2003-2007
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
32namespace 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 label, const Map& map) {
162      nodeset_writer.writeNodeMap(label, 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 ItemWriter, typename Map>
171    GraphWriter& writeNodeMap(std::string label, const Map& map,
172                              const ItemWriter& iw = ItemWriter()) {
173      nodeset_writer.writeNodeMap(label, map, iw);
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 label, const Map& map) {
183      edgeset_writer.writeEdgeMap(label, 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 ItemWriter, typename Map>
192    GraphWriter& writeEdgeMap(std::string label, const Map& map,
193                              const ItemWriter& iw = ItemWriter()) {
194      edgeset_writer.writeEdgeMap(label, map, iw);
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 label, const Node& node) {
203      node_writer.writeNode(label, 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 label, const Edge& edge) {
212      edge_writer.writeEdge(label, 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 label, const Value& value) {
221      attribute_writer.writeAttribute(label, 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 ItemWriter, typename Value>
230    GraphWriter& writeAttribute(std::string label, const Value& value,
231                               const ItemWriter& iw = ItemWriter()) {
232      attribute_writer.writeAttribute(label, value, iw);
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 Returns true if the writer can give back the labels by the items.
255    ///
256    /// Returns true if the writer can give back the the labels by the items.
257    bool isLabelWriter() const {
258      return nodeset_writer.isLabelWriter() &&
259        edgeset_writer.isLabelWriter();
260    }
261
262    /// \brief Write the label of the given node.
263    ///
264    /// It writes the label of the given node. If there was written a "label"
265    /// named node map then it will write the map value belonging to the node.
266    void writeLabel(std::ostream& os, const Node& item) const {
267      nodeset_writer.writeLabel(os, item);
268    }
269
270    /// \brief Write the label of the given edge.
271    ///
272    /// It writes the label of the given edge. If there was written a "label"
273    /// named edge map then it will write the map value belonging to the edge.
274    void writeLabel(std::ostream& os, const Edge& item) const {
275      edgeset_writer.writeLabel(os, item);
276    }
277
278    /// \brief Sorts the given node vector by label.
279    ///
280    /// Sorts the given node vector by label. If there was written an
281    /// "label" named map then the vector will be sorted by the values
282    /// of this map. Otherwise if the \c forceLabel parameter was true
283    /// it will be sorted by its id in the graph.
284    void sortByLabel(std::vector<Node>& nodes) const {
285      nodeset_writer.sortByLabel(nodes);
286    }
287
288    /// \brief Sorts the given edge vector by label.
289    ///
290    /// Sorts the given edge vector by label. If there was written an
291    /// "label" named map then the vector will be sorted by the values
292    /// of this map. Otherwise if the \c forceLabel parameter was true
293    /// it will be sorted by its id in the graph.
294    void sortByLabel(std::vector<Edge>& edges) const {
295      edgeset_writer.sortByLabel(edges);
296    }
297
298  private:
299
300    LemonWriter* writer;
301    bool own_writer;
302
303    NodeSetWriter<Graph, WriterTraits> nodeset_writer;
304    EdgeSetWriter<Graph, WriterTraits> edgeset_writer;
305
306    NodeWriter<Graph> node_writer;
307    EdgeWriter<Graph> edge_writer;
308   
309    AttributeWriter<WriterTraits> attribute_writer;
310  };
311
312
313  /// \brief The undirected graph writer class.
314  ///
315  /// The \c UGraphWriter class provides the ugraph output. To write
316  /// a graph you should first give writing commands to the writer. You can
317  /// declare write command as \c NodeMap, \c EdgeMap or \c UEdgeMap
318  /// writing and labeled Node, Edge or UEdge writing.
319  ///
320  ///\code
321  /// UGraphWriter<ListUGraph> writer(std::cout, graph);
322  ///\endcode
323  ///
324  /// The \c writeNodeMap() function declares a \c NodeMap writing
325  /// command in the \c UGraphWriter. You should give as parameter
326  /// the name of the map and the map object. The NodeMap writing
327  /// command with name "label" should write a unique map because it
328  /// is regarded as label map.
329  ///
330  ///\code
331  /// IdMap<ListUGraph, Node> nodeLabelMap;
332  /// writer.writeNodeMap("label", nodeLabelMap);
333  ///
334  /// writer.writeNodeMap("coords", coords);
335  /// writer.writeNodeMap("color", colorMap);
336  ///\endcode
337  ///
338  /// With the \c writeUEdgeMap() member function you can give an
339  /// undirected edge map writing command similar to the NodeMaps.
340  ///
341  ///\code
342  /// DescriptorMap<ListGraph, Edge, ListGraph::EdgeMap<int> >
343  ///   edgeDescMap(graph);
344  /// writer.writeUEdgeMap("descriptor", edgeDescMap);
345  ///
346  /// writer.writeUEdgeMap("weight", weightMap);
347  /// writer.writeUEdgeMap("label", labelMap);
348  ///\endcode
349  ///
350  /// The EdgeMap handling is just a syntactical sugar. It writes
351  /// two undirected edge map with '+' and '-' prefix in the name.
352  ///
353  ///\code
354  /// writer.writeEdgeMap("capacity", capacityMap);
355  ///\endcode
356  ///
357  ///
358  /// With \c writeNode() and \c writeUEdge() functions you can
359  /// designate nodes and undirected edges in the graph. For example, you can
360  /// write out the source and target of the graph.
361  ///
362  ///\code
363  /// writer.writeNode("source", sourceNode);
364  /// writer.writeNode("target", targetNode);
365  ///
366  /// writer.writeUEdge("observed", uEdge);
367  ///\endcode
368  ///
369  /// After you give all write commands you must call the \c run() member
370  /// function, which executes all the writing commands.
371  ///
372  ///\code
373  /// writer.run();
374  ///\endcode
375  ///
376  /// \see DefaultWriterTraits
377  /// \see QuotedStringWriter
378  /// \see IdMap
379  /// \see DescriptorMap
380  /// \see \ref GraphWriter
381  /// \see \ref graph-io-page
382  /// \author Balazs Dezso
383  template <typename _Graph, typename _WriterTraits = DefaultWriterTraits>
384  class UGraphWriter {
385  public:
386   
387    typedef _Graph Graph;
388    typedef typename Graph::Node Node;
389    typedef typename Graph::Edge Edge;
390    typedef typename Graph::UEdge UEdge;
391
392    typedef _WriterTraits WriterTraits;
393
394    /// \brief Construct a new UGraphWriter.
395    ///
396    /// Construct a new UGraphWriter. It writes the given graph
397    /// to the given stream.
398    UGraphWriter(std::ostream& _os, const Graph& _graph)
399      : writer(new LemonWriter(_os)), own_writer(true),
400        nodeset_writer(*writer, _graph, std::string()),
401        uedgeset_writer(*writer, _graph, nodeset_writer, std::string()),
402        node_writer(*writer, nodeset_writer, std::string()),
403        uedge_writer(*writer, uedgeset_writer, std::string()),
404        attribute_writer(*writer, std::string()) {}
405
406    /// \brief Construct a new UGraphWriter.
407    ///
408    /// Construct a new UGraphWriter. It writes the given graph
409    /// to the given file.
410    UGraphWriter(const std::string& _filename, const Graph& _graph)
411      : writer(new LemonWriter(_filename)), own_writer(true),
412        nodeset_writer(*writer, _graph, std::string()),
413        uedgeset_writer(*writer, _graph, nodeset_writer, std::string()),
414        node_writer(*writer, nodeset_writer, std::string()),
415        uedge_writer(*writer, uedgeset_writer, std::string()),
416        attribute_writer(*writer, std::string()) {}
417
418    /// \brief Construct a new UGraphWriter.
419    ///
420    /// Construct a new UGraphWriter. It writes the given graph
421    /// to given LemonWriter.
422    UGraphWriter(LemonWriter& _writer, const Graph& _graph)
423      : writer(_writer), own_writer(false),
424        nodeset_writer(*writer, _graph, std::string()),
425        uedgeset_writer(*writer, _graph, nodeset_writer, std::string()),
426        node_writer(*writer, nodeset_writer, std::string()),
427        uedge_writer(*writer, uedgeset_writer, std::string()),
428        attribute_writer(*writer, std::string()) {}
429
430    /// \brief Destruct the graph writer.
431    ///
432    /// Destruct the graph writer.
433    ~UGraphWriter() {
434      if (own_writer)
435        delete writer;
436    }
437
438    /// \brief Issue a new node map writing command to the writer.
439    ///
440    /// This function issues a new <i> node map writing command</i> to
441    /// the writer.
442    template <typename Map>
443    UGraphWriter& writeNodeMap(std::string label, const Map& map) {
444      nodeset_writer.writeNodeMap(label, map);
445      return *this;
446    }
447
448    /// \brief Issue a new node map writing command to the writer.
449    ///
450    /// This function issues a new <i> node map writing command</i> to
451    /// the writer.
452    template <typename ItemWriter, typename Map>
453    UGraphWriter& writeNodeMap(std::string label, const Map& map,
454                              const ItemWriter& iw = ItemWriter()) {
455      nodeset_writer.writeNodeMap(label, map, iw);
456      return *this;
457    }
458
459    /// \brief Issue a new edge map writing command to the writer.
460    ///
461    /// This function issues a new <i> edge map writing command</i> to
462    /// the writer.
463    template <typename Map>
464    UGraphWriter& writeEdgeMap(std::string label, const Map& map) {
465      uedgeset_writer.writeEdgeMap(label, 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
472    /// the writer.
473    template <typename ItemWriter, typename Map>
474    UGraphWriter& writeEdgeMap(std::string label, const Map& map,
475                                   const ItemWriter& iw = ItemWriter()) {
476      uedgeset_writer.writeEdgeMap(label, map, iw);
477      return *this;
478    }
479
480    /// \brief Issue a new undirected edge map writing command to the writer.
481    ///
482    /// This function issues a new <i> undirected edge map writing
483    /// command</i> to the writer.
484    template <typename Map>
485    UGraphWriter& writeUEdgeMap(std::string label, const Map& map) {
486      uedgeset_writer.writeUEdgeMap(label, map);
487      return *this;
488    }
489
490    /// \brief Issue a new undirected edge map writing command to the writer.
491    ///
492    /// This function issues a new <i> undirected edge map writing
493    /// command</i> to the writer.
494   template <typename ItemWriter, typename Map>
495    UGraphWriter& writeUEdgeMap(std::string label, const Map& map,
496                                        const ItemWriter& iw = ItemWriter()) {
497      uedgeset_writer.writeUEdgeMap(label, map, iw);
498      return *this;
499    }
500
501    /// \brief Issue a new labeled node writer to the writer.
502    ///
503    /// This function issues a new <i> labeled node writing
504    /// command</i> to the writer.
505    UGraphWriter& writeNode(std::string label, const Node& node) {
506      node_writer.writeNode(label, node);
507      return *this;
508    }
509
510    /// \brief Issue a new labeled edge writer to the writer.
511    ///
512    /// This function issues a new <i> labeled edge writing
513    /// command</i> to the writer.
514    UGraphWriter& writeEdge(std::string label, const Edge& edge) {
515      uedge_writer.writeEdge(label, edge);
516    }
517
518    /// \brief Issue a new labeled undirected edge writing command to
519    /// the writer.
520    ///
521    /// Issue a new <i>labeled undirected edge writing command</i> to
522    /// the writer.
523    UGraphWriter& writeUEdge(std::string label, const UEdge& edge) {
524      uedge_writer.writeUEdge(label, edge);
525    }
526
527    /// \brief Issue a new attribute writing command.
528    ///
529    /// This function issues a new <i> attribute writing
530    /// command</i> to the writer.
531    template <typename Value>
532    UGraphWriter& writeAttribute(std::string label, const Value& value) {
533      attribute_writer.writeAttribute(label, value);
534      return *this;
535    }
536   
537    /// \brief Issue a new attribute writing command.
538    ///
539    /// This function issues a new <i> attribute writing
540    /// command</i> to the writer.
541    template <typename ItemWriter, typename Value>
542    UGraphWriter& writeAttribute(std::string label, const Value& value,
543                               const ItemWriter& iw = ItemWriter()) {
544      attribute_writer.writeAttribute(label, value, iw);
545      return *this;
546    }
547
548    /// \brief Conversion operator to LemonWriter.
549    ///
550    /// Conversion operator to LemonWriter. It makes possible
551    /// to access the encapsulated \e LemonWriter, this way
552    /// you can attach to this writer new instances of
553    /// \e LemonWriter::SectionWriter.
554    operator LemonWriter&() {
555      return *writer;
556    }
557
558    /// \brief Executes the writing commands.
559    ///
560    /// Executes the writing commands.
561    void run() {
562      writer->run();
563    }
564
565    /// \brief Returns true if the writer can give back the labels by the items.
566    ///
567    /// Returns true if the writer can give back the the labels by the items.
568    bool isLabelWriter() const {
569      return nodeset_writer.isLabelWriter() &&
570        uedgeset_writer.isLabelWriter();
571    }
572
573    /// \brief Write the label of the given node.
574    ///
575    /// It writes the label of the given node. If there was written a "label"
576    /// named node map then it will write the map value belonging to the node.
577    void writeLabel(std::ostream& os, const Node& item) const {
578      nodeset_writer.writeLabel(os, item);
579    }
580
581    /// \brief Write the label of the given edge.
582    ///
583    /// It writes the label of the given edge. If there was written a "label"
584    /// named edge map then it will write the map value belonging to the edge.
585    void writeLabel(std::ostream& os, const Edge& item) const {
586      uedgeset_writer.writeLabel(os, item);
587    }
588
589    /// \brief Write the label of the given undirected edge.
590    ///
591    /// It writes the label of the given undirected edge. If there was
592    /// written a "label" named edge map then it will write the map
593    /// value belonging to the edge.
594    void writeLabel(std::ostream& os, const UEdge& item) const {
595      uedgeset_writer.writeLabel(os, item);
596    }
597
598    /// \brief Sorts the given node vector by label.
599    ///
600    /// Sorts the given node vector by label. If there was written an
601    /// "label" named map then the vector will be sorted by the values
602    /// of this map. Otherwise if the \c forceLabel parameter was true
603    /// it will be sorted by its id in the graph.
604    void sortByLabel(std::vector<Node>& nodes) const {
605      nodeset_writer.sortByLabel(nodes);
606    }
607
608    /// \brief Sorts the given edge vector by label.
609    ///
610    /// Sorts the given edge vector by label. If there was written an
611    /// "label" named map then the vector will be sorted by the values
612    /// of this map. Otherwise if the \c forceLabel parameter was true
613    /// it will be sorted by its id in the graph.
614    void sortByLabel(std::vector<Edge>& edges) const {
615      uedgeset_writer.sortByLabel(edges);
616    }
617
618    /// \brief Sorts the given undirected edge vector by label.
619    ///
620    /// Sorts the given undirected edge vector by label. If there was
621    /// written an "label" named map then the vector will be sorted by
622    /// the values of this map. Otherwise if the \c forceLabel
623    /// parameter was true it will be sorted by its id in the graph.
624    void sortByLabel(std::vector<UEdge>& uedges) const {
625      uedgeset_writer.sortByLabel(uedges);
626    }
627
628  private:
629
630    LemonWriter* writer;
631    bool own_writer;
632
633    NodeSetWriter<Graph, WriterTraits> nodeset_writer;
634    UEdgeSetWriter<Graph, WriterTraits> uedgeset_writer;
635
636    NodeWriter<Graph> node_writer;
637    UEdgeWriter<Graph> uedge_writer;
638   
639    AttributeWriter<WriterTraits> attribute_writer;
640  };
641
642  /// @}
643
644}
645
646#endif
Note: See TracBrowser for help on using the repository browser.