Graph input-output demo, some documentation.
2 * lemon/graph_writer.h - Part of LEMON, a generic C++ optimization library
4 * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
5 * (Egervary Research Group on Combinatorial Optimization, EGRES).
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.
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
19 ///\brief Lemon Graph Format writer.
21 #ifndef LEMON_GRAPH_WRITER_H
22 #define LEMON_GRAPH_WRITER_H
26 #include <lemon/error.h>
27 #include <lemon/lemon_writer.h>
31 /// \addtogroup io_group
34 /// \brief The graph writer class.
36 /// The \c GraphWriter class provides the graph output.
37 /// Before you read this documentation it might be useful to read the general
38 /// description of \ref graph-io-page "Graph Input-Output".
40 /// you should first give writing commands to the writer. You can declare
41 /// write commands as \c NodeMap or \c EdgeMap writing and labeled Node and
45 /// GraphWriter<ListGraph> writer(std::cout, graph);
48 /// The \c writeNodeMap() function declares a \c NodeMap writing
49 /// command in the \c GraphWriter. You should give as parameter
50 /// the name of the map and the map object. The NodeMap writing
51 /// command with name "id" should write a unique map because it
52 /// is regarded as ID map (such a map is essential if the graph has edges).
55 /// IdMap<ListGraph, Node> nodeIdMap;
56 /// writer.writeNodeMap("id", nodeIdMap);
58 /// writer.writeNodeMap("coords", coords);
59 /// writer.writeNodeMap("color", colorMap);
62 /// With the \c writeEdgeMap() member function you can give an edge map
63 /// writing command similar to the NodeMaps.
66 /// DescriptorMap<ListGraph, Edge, ListGraph::EdgeMap<int> >
67 /// edgeDescMap(graph);
68 /// writer.writeEdgeMap("descriptor", edgeDescMap);
70 /// writer.writeEdgeMap("weight", weightMap);
71 /// writer.writeEdgeMap("label", labelMap);
74 /// With \c writeNode() and \c writeEdge() functions you can
75 /// point out Nodes and Edges in the graph. For example, you can
76 /// write out the source and target of a maximum flow instance.
79 /// writer.writeNode("source", sourceNode);
80 /// writer.writeNode("target", targetNode);
82 /// writer.writeEdge("observed", edge);
85 /// After you give all write commands you must call the \c run() member
86 /// function, which executes all the writing commands.
92 /// \see DefaultWriterTraits
93 /// \see QuotedStringWriter
95 /// \see DescriptorMap
96 /// \see \ref GraphReader
97 /// \see \ref graph-io-page
98 /// \author Balazs Dezso
99 template <typename _Graph, typename _WriterTraits = DefaultWriterTraits>
103 typedef _Graph Graph;
104 typedef typename Graph::Node Node;
105 typedef typename Graph::Edge Edge;
107 typedef _WriterTraits WriterTraits;
109 /// \brief Construct a new GraphWriter.
111 /// This function constructs a new GraphWriter to write the given graph
112 /// to the given stream.
113 GraphWriter(std::ostream& _os, const Graph& _graph)
114 : writer(new LemonWriter(_os)), own_writer(true),
115 nodeset_writer(*writer, _graph, std::string()),
116 edgeset_writer(*writer, _graph, nodeset_writer, std::string()),
117 node_writer(*writer, nodeset_writer, std::string()),
118 edge_writer(*writer, edgeset_writer, std::string()),
119 attribute_writer(*writer, std::string()) {}
121 /// \brief Construct a new GraphWriter.
123 /// This function constructs a new GraphWriter to write the given graph
124 /// to the given file.
125 GraphWriter(const std::string& _filename, const Graph& _graph)
126 : writer(new LemonWriter(_filename)), own_writer(true),
127 nodeset_writer(*writer, _graph, std::string()),
128 edgeset_writer(*writer, _graph, nodeset_writer, std::string()),
129 node_writer(*writer, nodeset_writer, std::string()),
130 edge_writer(*writer, edgeset_writer, std::string()),
131 attribute_writer(*writer, std::string()) {}
133 /// \brief Construct a new GraphWriter.
135 /// This function constructs a new GraphWriter to write the given graph
136 /// to the given LemonReader.
137 GraphWriter(LemonWriter& _writer, const Graph& _graph)
138 : writer(_writer), own_writer(false),
139 nodeset_writer(*writer, _graph, std::string()),
140 edgeset_writer(*writer, _graph, nodeset_writer, std::string()),
141 node_writer(*writer, nodeset_writer, std::string()),
142 edge_writer(*writer, edgeset_writer, std::string()),
143 attribute_writer(*writer, std::string()) {}
145 /// \brief Destruct the graph writer.
147 /// This function destructs the graph writer.
153 /// \brief Issue a new node map writing command for the writer.
155 /// This function issues a new <i> node map writing command</i> to the writer.
156 template <typename Map>
157 GraphWriter& writeNodeMap(std::string name, const Map& map) {
158 nodeset_writer.writeNodeMap(name, map);
162 /// \brief Issue a new node map writing command for the writer.
164 /// This function issues a new <i> node map writing command</i> to the writer.
165 template <typename Writer, typename Map>
166 GraphWriter& writeNodeMap(std::string name, const Map& map,
167 const Writer& writer = Writer()) {
168 nodeset_writer.writeNodeMap(name, map, writer);
173 /// \brief Issue a new edge map writing command for the writer.
175 /// This function issues a new <i> edge map writing command</i> to the writer.
176 template <typename Map>
177 GraphWriter& writeEdgeMap(std::string name, const Map& map) {
178 edgeset_writer.writeEdgeMap(name, map);
183 /// \brief Issue a new edge map writing command for the writer.
185 /// This function issues a new <i> edge map writing command</i> to the writer.
186 template <typename Writer, typename Map>
187 GraphWriter& writeEdgeMap(std::string name, const Map& map,
188 const Writer& writer = Writer()) {
189 edgeset_writer.writeEdgeMap(name, map, writer);
193 /// \brief Issue a new labeled node writing command to the writer.
195 /// This function issues a new <i> labeled node writing command</i>
197 GraphWriter& writeNode(std::string name, const Node& node) {
198 node_writer.writeNode(name, node);
202 /// \brief Issue a new labeled edge writing command to the writer.
204 /// This function issues a new <i> labeled edge writing command</i>
206 GraphWriter& writeEdge(std::string name, const Edge& edge) {
207 edge_writer.writeEdge(name, edge);
210 /// \brief Issue a new attribute writing command.
212 /// This function issues a new <i> attribute writing command</i>
214 template <typename Value>
215 GraphWriter& writeAttribute(std::string name, const Value& value) {
216 attribute_writer.writeAttribute(name, value);
220 /// \brief Issue a new attribute writing command.
222 /// This function issues a new <i> attribute writing command</i>
224 template <typename Writer, typename Value>
225 GraphWriter& writeAttribute(std::string name, const Value& value,
226 const Writer& writer) {
227 attribute_writer.writeAttribute<Writer>(name, value, writer);
231 /// \brief Conversion operator to LemonWriter.
233 /// Conversion operator to LemonWriter. It makes possible
234 /// to access the encapsulated \e LemonWriter, this way
235 /// you can attach to this writer new instances of
236 /// \e LemonWriter::SectionWriter.
237 operator LemonWriter&() {
241 /// \brief Executes the writing commands.
243 /// Executes the writing commands.
248 /// \brief Write the id of the given node.
250 /// It writes the id of the given node. If there was written an "id"
251 /// named node map then it will write the map value belonging to the node.
252 void writeId(std::ostream& os, const Node& item) const {
253 nodeset_writer.writeId(os, item);
256 /// \brief Write the id of the given edge.
258 /// It writes the id of the given edge. If there was written an "id"
259 /// named edge map then it will write the map value belonging to the edge.
260 void writeId(std::ostream& os, const Edge& item) const {
261 edgeset_writer.writeId(os, item);
269 NodeSetWriter<Graph, WriterTraits> nodeset_writer;
270 EdgeSetWriter<Graph, WriterTraits> edgeset_writer;
272 NodeWriter<Graph> node_writer;
273 EdgeWriter<Graph> edge_writer;
275 AttributeWriter<WriterTraits> attribute_writer;
279 /// \brief Write a graph to the output.
281 /// Write a graph to the output.
282 /// \param os The output stream.
283 /// \param g The graph.
284 /// \param capacity The capacity map.
285 /// \param s The source node.
286 /// \param t The target node.
287 /// \param cost The cost map.
288 template<typename Graph, typename CapacityMap, typename CostMap>
289 void writeGraph(std::ostream& os, const Graph &g,
290 const CapacityMap& capacity, const typename Graph::Node &s,
291 const typename Graph::Node &t, const CostMap& cost) {
292 GraphWriter<Graph> writer(os, g);
293 IdMap<Graph, typename Graph::Node> nodeIdMap(g);
294 writer.writeNodeMap("id", nodeIdMap);
295 IdMap<Graph, typename Graph::Edge> edgeIdMap(g);
296 writer.writeEdgeMap("id", edgeIdMap);
297 writer.writeEdgeMap("capacity", capacity);
298 writer.writeEdgeMap("cost", cost);
299 writer.writeNode("source", s);
300 writer.writeNode("target", t);
304 /// \brief Write a graph to the output.
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 /// \param t The target node.
312 template<typename Graph, typename CapacityMap>
313 void writeGraph(std::ostream& os, const Graph &g,
314 const CapacityMap& capacity, const typename Graph::Node &s,
315 const typename Graph::Node &t) {
316 GraphWriter<Graph> writer(os, g);
317 IdMap<Graph, typename Graph::Node> nodeIdMap(g);
318 writer.writeNodeMap("id", nodeIdMap);
319 IdMap<Graph, typename Graph::Edge> edgeIdMap(g);
320 writer.writeEdgeMap("id", edgeIdMap);
321 writer.writeEdgeMap("capacity", capacity);
322 writer.writeNode("source", s);
323 writer.writeNode("target", t);
327 /// \brief Write a graph to the output.
329 /// Write a graph to the output.
330 /// \param os The output stream.
331 /// \param g The graph.
332 /// \param capacity The capacity map.
333 /// \param s The source node.
334 template<typename Graph, typename CapacityMap>
335 void writeGraph(std::ostream& os, const Graph &g,
336 const CapacityMap& capacity, const typename Graph::Node &s) {
337 GraphWriter<Graph> writer(os, g);
338 IdMap<Graph, typename Graph::Node> nodeIdMap(g);
339 writer.writeNodeMap("id", nodeIdMap);
340 IdMap<Graph, typename Graph::Edge> edgeIdMap(g);
341 writer.writeEdgeMap("id", edgeIdMap);
342 writer.writeEdgeMap("capacity", capacity);
343 writer.writeNode("source", s);
347 /// \brief Write a graph to the output.
349 /// Write a graph to the output.
350 /// \param os The output stream.
351 /// \param g The graph.
352 /// \param capacity The capacity map.
353 template<typename Graph, typename CapacityMap>
354 void writeGraph(std::ostream& os, const Graph &g,
355 const CapacityMap& capacity) {
356 GraphWriter<Graph> writer(os, g);
357 IdMap<Graph, typename Graph::Node> nodeIdMap(g);
358 writer.writeNodeMap("id", nodeIdMap);
359 IdMap<Graph, typename Graph::Edge> edgeIdMap(g);
360 writer.writeEdgeMap("id", edgeIdMap);
361 writer.writeEdgeMap("capacity", capacity);
365 /// \brief Write a graph to the output.
367 /// Write a graph to the output.
368 /// \param os The output stream.
369 /// \param g The graph.
370 template<typename Graph>
371 void writeGraph(std::ostream& os, const Graph &g) {
372 GraphWriter<Graph> writer(os, g);
373 IdMap<Graph, typename Graph::Node> nodeIdMap(g);
374 writer.writeNodeMap("id", nodeIdMap);
375 IdMap<Graph, typename Graph::Edge> edgeIdMap(g);
376 writer.writeEdgeMap("id", edgeIdMap);
380 /// \brief The undirected graph writer class.
382 /// The \c UndirGraphWriter class provides the undir graph output. To write
383 /// a graph you should first give writing commands to the writer. You can
384 /// declare write command as \c NodeMap, \c EdgeMap or \c UndirEdgeMap
385 /// writing and labeled Node, Edge or UndirEdge writing.
388 /// UndirGraphWriter<UndirListGraph> writer(std::cout, graph);
391 /// The \c writeNodeMap() function declares a \c NodeMap writing
392 /// command in the \c UndirGraphWriter. You should give as parameter
393 /// the name of the map and the map object. The NodeMap writing
394 /// command with name "id" should write a unique map because it
395 /// is regarded as ID map.
398 /// IdMap<UndirListGraph, Node> nodeIdMap;
399 /// writer.writeNodeMap("id", nodeIdMap);
401 /// writer.writeNodeMap("coords", coords);
402 /// writer.writeNodeMap("color", colorMap);
405 /// With the \c writeUndirEdgeMap() member function you can give an
406 /// undirected edge map writing command similar to the NodeMaps.
409 /// DescriptorMap<ListGraph, Edge, ListGraph::EdgeMap<int> >
410 /// edgeDescMap(graph);
411 /// writer.writeUndirEdgeMap("descriptor", edgeDescMap);
413 /// writer.writeUndirEdgeMap("weight", weightMap);
414 /// writer.writeUndirEdgeMap("label", labelMap);
417 /// The EdgeMap handling is just a syntactical sugar. It writes
418 /// two undirected edge map with '+' and '-' prefix in the name.
421 /// writer.writeEdgeMap("capacity", capacityMap);
425 /// With \c writeNode() and \c writeUndirEdge() functions you can
426 /// designate nodes and undirected edges in the graph. For example, you can
427 /// write out the source and target of the graph.
430 /// writer.writeNode("source", sourceNode);
431 /// writer.writeNode("target", targetNode);
433 /// writer.writeUndirEdge("observed", undirEdge);
436 /// After you give all write commands you must call the \c run() member
437 /// function, which executes all the writing commands.
443 /// \see DefaultWriterTraits
444 /// \see QuotedStringWriter
446 /// \see DescriptorMap
447 /// \see \ref GraphWriter
448 /// \see \ref graph-io-page
449 /// \author Balazs Dezso
450 template <typename _Graph, typename _WriterTraits = DefaultWriterTraits>
451 class UndirGraphWriter {
454 typedef _Graph Graph;
455 typedef typename Graph::Node Node;
456 typedef typename Graph::Edge Edge;
457 typedef typename Graph::UndirEdge UndirEdge;
459 typedef _WriterTraits WriterTraits;
461 /// \brief Construct a new UndirGraphWriter.
463 /// Construct a new UndirGraphWriter. It writes the given graph
464 /// to the given stream.
465 UndirGraphWriter(std::ostream& _os, const Graph& _graph)
466 : writer(new LemonWriter(_os)), own_writer(true),
467 nodeset_writer(*writer, _graph, std::string()),
468 undir_edgeset_writer(*writer, _graph, nodeset_writer, std::string()),
469 node_writer(*writer, nodeset_writer, std::string()),
470 undir_edge_writer(*writer, undir_edgeset_writer, std::string()),
471 attribute_writer(*writer, std::string()) {}
473 /// \brief Construct a new UndirGraphWriter.
475 /// Construct a new UndirGraphWriter. It writes the given graph
476 /// to the given file.
477 UndirGraphWriter(const std::string& _filename, const Graph& _graph)
478 : writer(new LemonWriter(_filename)), own_writer(true),
479 nodeset_writer(*writer, _graph, std::string()),
480 undir_edgeset_writer(*writer, _graph, nodeset_writer, std::string()),
481 node_writer(*writer, nodeset_writer, std::string()),
482 undir_edge_writer(*writer, undir_edgeset_writer, std::string()),
483 attribute_writer(*writer, std::string()) {}
485 /// \brief Construct a new UndirGraphWriter.
487 /// Construct a new UndirGraphWriter. It writes the given graph
488 /// to given LemonReader.
489 UndirGraphWriter(LemonWriter& _writer, const Graph& _graph)
490 : writer(_writer), own_writer(false),
491 nodeset_writer(*writer, _graph, std::string()),
492 undir_edgeset_writer(*writer, _graph, nodeset_writer, std::string()),
493 node_writer(*writer, nodeset_writer, std::string()),
494 undir_edge_writer(*writer, undir_edgeset_writer, std::string()),
495 attribute_writer(*writer, std::string()) {}
497 /// \brief Destruct the graph writer.
499 /// Destruct the graph writer.
500 ~UndirGraphWriter() {
505 /// \brief Issue a new node map writing command to the writer.
507 /// This function issues a new <i> node map writing command</i> to the writer.
508 template <typename Map>
509 UndirGraphWriter& writeNodeMap(std::string name, const Map& map) {
510 nodeset_writer.writeNodeMap(name, map);
514 /// \brief Issue a new node map writing command to the writer.
516 /// This function issues a new <i> node map writing command</i> to the writer.
517 template <typename Writer, typename Map>
518 UndirGraphWriter& writeNodeMap(std::string name, const Map& map,
519 const Writer& writer = Writer()) {
520 nodeset_writer.writeNodeMap(name, map, writer);
524 /// \brief Issue a new edge map writing command to the writer.
526 /// This function issues a new <i> edge map writing command</i> to the writer.
527 template <typename Map>
528 UndirGraphWriter& writeEdgeMap(std::string name, const Map& map) {
529 undir_edgeset_writer.writeEdgeMap(name, map);
533 /// \brief Issue a new edge map writing command to the writer.
535 /// This function issues a new <i> edge map writing command</i> to the writer.
536 template <typename Writer, typename Map>
537 UndirGraphWriter& writeEdgeMap(std::string name, const Map& map,
538 const Writer& writer = Writer()) {
539 undir_edgeset_writer.writeEdgeMap(name, map, writer);
543 /// \brief Issue a new undirected edge map writing command to the writer.
545 /// This function issues a new <i> undirected edge map writing
546 /// command</i> to the writer.
547 template <typename Map>
548 UndirGraphWriter& writeUndirEdgeMap(std::string name, const Map& map) {
549 undir_edgeset_writer.writeUndirEdgeMap(name, map);
553 /// \brief Issue a new undirected edge map writing command to the writer.
555 /// This function issues a new <i> undirected edge map writing
556 /// command</i> to the writer.
557 template <typename Writer, typename Map>
558 UndirGraphWriter& writeUndirEdgeMap(std::string name, const Map& map,
559 const Writer& writer = Writer()) {
560 undir_edgeset_writer.writeUndirEdgeMap(name, map, writer);
564 /// \brief Issue a new labeled node writer to the writer.
566 /// This function issues a new <i> labeled node writing
567 /// command</i> to the writer.
568 UndirGraphWriter& writeNode(std::string name, const Node& node) {
569 node_writer.writeNode(name, node);
573 /// \brief Issue a new labeled edge writer to the writer.
575 /// This function issues a new <i> labeled edge writing
576 /// command</i> to the writer.
577 UndirGraphWriter& writeEdge(std::string name, const Edge& edge) {
578 undir_edge_writer.writeEdge(name, edge);
581 /// \brief Issue a new labeled undirected edge writing command to
584 /// Issue a new <i>labeled undirected edge writing command</i> to
586 UndirGraphWriter& writeUndirEdge(std::string name, const UndirEdge& edge) {
587 undir_edge_writer.writeUndirEdge(name, edge);
590 /// \brief Issue a new attribute writing command.
592 /// This function issues a new <i> attribute writing
593 /// command</i> to the writer.
594 template <typename Value>
595 UndirGraphWriter& writeAttribute(std::string name, const Value& value) {
596 attribute_writer.writeAttribute(name, value);
600 /// \brief Issue a new attribute writing command.
602 /// This function issues a new <i> attribute writing
603 /// command</i> to the writer.
604 template <typename Writer, typename Value>
605 UndirGraphWriter& writeAttribute(std::string name, const Value& value,
606 const Writer& writer) {
607 attribute_writer.writeAttribute<Writer>(name, value, writer);
611 /// \brief Conversion operator to LemonWriter.
613 /// Conversion operator to LemonWriter. It makes possible
614 /// to access the encapsulated \e LemonWriter, this way
615 /// you can attach to this writer new instances of
616 /// \e LemonWriter::SectionWriter.
617 operator LemonWriter&() {
621 /// \brief Executes the writing commands.
623 /// Executes the writing commands.
628 /// \brief Write the id of the given node.
630 /// It writes the id of the given node. If there was written an "id"
631 /// named node map then it will write the map value belonging to the node.
632 void writeId(std::ostream& os, const Node& item) const {
633 nodeset_writer.writeId(os, item);
636 /// \brief Write the id of the given edge.
638 /// It writes the id of the given edge. If there was written an "id"
639 /// named edge map then it will write the map value belonging to the edge.
640 void writeId(std::ostream& os, const Edge& item) const {
641 undir_edgeset_writer.writeId(os, item);
644 /// \brief Write the id of the given undirected edge.
646 /// It writes the id of the given undirected edge. If there was written
647 /// an "id" named edge map then it will write the map value belonging to
649 void writeId(std::ostream& os, const UndirEdge& item) const {
650 undir_edgeset_writer.writeId(os, item);
659 NodeSetWriter<Graph, WriterTraits> nodeset_writer;
660 UndirEdgeSetWriter<Graph, WriterTraits> undir_edgeset_writer;
662 NodeWriter<Graph> node_writer;
663 UndirEdgeWriter<Graph> undir_edge_writer;
665 AttributeWriter<WriterTraits> attribute_writer;
669 /// \brief Write an undirected multigraph (undirected graph + capacity
670 /// map on the edges) to the output.
672 /// Write an undirected multigraph (undirected graph + capacity
673 /// map on the edges) to the output.
674 /// \param os The output stream.
675 /// \param g The graph.
676 /// \param capacity The capacity undirected map.
677 template<typename Graph, typename CapacityMap>
678 void writeUndirGraph(std::ostream& os, const Graph &g,
679 const CapacityMap& capacity) {
680 UndirGraphWriter<Graph> writer(os, g);
681 writer.writeUndirEdgeMap("capacity", capacity);
685 /// \brief Write an undirected graph to the output.
687 /// Write an undirected graph to the output.
688 /// \param os The output stream.
689 /// \param g The graph.
690 template<typename Graph>
691 void writeUndirGraph(std::ostream& os, const Graph &g) {
692 UndirGraphWriter<Graph> writer(os, g);