COIN-OR::LEMON - Graph Library

source: lemon-0.x/src/lemon/graph_writer.h @ 1421:7a21e1414c38

Last change on this file since 1421:7a21e1414c38 was 1421:7a21e1414c38, checked in by Balazs Dezso, 19 years ago

IO with undirected edgesets and undirected graphs.
Missing features:

InfoReader?,
aliased edges in undir edgesets

File size: 20.7 KB
Line 
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
29namespace 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
Note: See TracBrowser for help on using the repository browser.