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.
22 #ifndef LEMON_GRAPH_WRITER_H
23 #define LEMON_GRAPH_WRITER_H
27 #include <lemon/error.h>
28 #include <lemon/lemon_writer.h>
32 /// \addtogroup io_group
35 /// \brief The graph writer class.
37 /// The \c GraphWriter class provides the graph output.
38 /// Before you read this documentation it might be useful to read the general
39 /// description of \ref graph-io-page "Graph Input-Output".
40 /// If you don't need very sophisticated
41 /// behaviour then you can use the versions of the public function
42 /// \ref writeGraph() to output a graph (or a max flow instance etc).
45 /// you should first give writing commands to the writer. You can declare
46 /// write commands as \c NodeMap or \c EdgeMap writing and labeled Node and
50 /// GraphWriter<ListGraph> writer(std::cout, graph);
53 /// The \c writeNodeMap() function declares a \c NodeMap writing
54 /// command in the \c GraphWriter. You should give as parameter
55 /// the name of the map and the map object. The NodeMap writing
56 /// command with name "id" should write a unique map because it
57 /// is regarded as ID map (such a map is essential if the graph has edges).
60 /// IdMap<ListGraph, Node> nodeIdMap;
61 /// writer.writeNodeMap("id", nodeIdMap);
63 /// writer.writeNodeMap("coords", coords);
64 /// writer.writeNodeMap("color", colorMap);
67 /// With the \c writeEdgeMap() member function you can give an edge map
68 /// writing command similar to the NodeMaps.
71 /// DescriptorMap<ListGraph, Edge, ListGraph::EdgeMap<int> >
72 /// edgeDescMap(graph);
73 /// writer.writeEdgeMap("descriptor", edgeDescMap);
75 /// writer.writeEdgeMap("weight", weightMap);
76 /// writer.writeEdgeMap("label", labelMap);
79 /// With \c writeNode() and \c writeEdge() functions you can
80 /// point out Nodes and Edges in the graph. For example, you can
81 /// write out the source and target of a maximum flow instance.
84 /// writer.writeNode("source", sourceNode);
85 /// writer.writeNode("target", targetNode);
87 /// writer.writeEdge("observed", edge);
90 /// After you give all write commands you must call the \c run() member
91 /// function, which executes all the writing commands.
97 /// \see DefaultWriterTraits
98 /// \see QuotedStringWriter
100 /// \see DescriptorMap
101 /// \see \ref GraphReader
102 /// \see \ref graph-io-page
103 /// \author Balazs Dezso
104 template <typename _Graph, typename _WriterTraits = DefaultWriterTraits>
108 typedef _Graph Graph;
109 typedef typename Graph::Node Node;
110 typedef typename Graph::Edge Edge;
112 typedef _WriterTraits WriterTraits;
114 /// \brief Construct a new GraphWriter.
116 /// This function constructs a new GraphWriter to write the given graph
117 /// to the given stream.
118 GraphWriter(std::ostream& _os, const Graph& _graph)
119 : writer(new LemonWriter(_os)), own_writer(true),
120 nodeset_writer(*writer, _graph, std::string()),
121 edgeset_writer(*writer, _graph, nodeset_writer, std::string()),
122 node_writer(*writer, nodeset_writer, std::string()),
123 edge_writer(*writer, edgeset_writer, std::string()),
124 attribute_writer(*writer, std::string()) {}
126 /// \brief Construct a new GraphWriter.
128 /// This function constructs a new GraphWriter to write the given graph
129 /// to the given file.
130 GraphWriter(const std::string& _filename, const Graph& _graph)
131 : writer(new LemonWriter(_filename)), own_writer(true),
132 nodeset_writer(*writer, _graph, std::string()),
133 edgeset_writer(*writer, _graph, nodeset_writer, std::string()),
134 node_writer(*writer, nodeset_writer, std::string()),
135 edge_writer(*writer, edgeset_writer, std::string()),
136 attribute_writer(*writer, std::string()) {}
138 /// \brief Construct a new GraphWriter.
140 /// This function constructs a new GraphWriter to write the given graph
141 /// to the given LemonReader.
142 GraphWriter(LemonWriter& _writer, const Graph& _graph)
143 : writer(_writer), own_writer(false),
144 nodeset_writer(*writer, _graph, std::string()),
145 edgeset_writer(*writer, _graph, nodeset_writer, std::string()),
146 node_writer(*writer, nodeset_writer, std::string()),
147 edge_writer(*writer, edgeset_writer, std::string()),
148 attribute_writer(*writer, std::string()) {}
150 /// \brief Destruct the graph writer.
152 /// This function destructs the graph writer.
158 /// \brief Issue a new node map writing command for the writer.
160 /// This function issues a new <i> node map writing command</i> to the writer.
161 template <typename Map>
162 GraphWriter& writeNodeMap(std::string name, const Map& map) {
163 nodeset_writer.writeNodeMap(name, map);
167 /// \brief Issue a new node map writing command for the writer.
169 /// This function issues a new <i> node map writing command</i> to the writer.
170 template <typename Writer, typename Map>
171 GraphWriter& writeNodeMap(std::string name, const Map& map,
172 const Writer& writer = Writer()) {
173 nodeset_writer.writeNodeMap(name, map, writer);
178 /// \brief Issue a new edge map writing command for the writer.
180 /// This function issues a new <i> edge map writing command</i> to the writer.
181 template <typename Map>
182 GraphWriter& writeEdgeMap(std::string name, const Map& map) {
183 edgeset_writer.writeEdgeMap(name, map);
188 /// \brief Issue a new edge map writing command for the writer.
190 /// This function issues a new <i> edge map writing command</i> to the writer.
191 template <typename Writer, typename Map>
192 GraphWriter& writeEdgeMap(std::string name, const Map& map,
193 const Writer& writer = Writer()) {
194 edgeset_writer.writeEdgeMap(name, map, writer);
198 /// \brief Issue a new labeled node writing command to the writer.
200 /// This function issues a new <i> labeled node writing command</i>
202 GraphWriter& writeNode(std::string name, const Node& node) {
203 node_writer.writeNode(name, node);
207 /// \brief Issue a new labeled edge writing command to the writer.
209 /// This function issues a new <i> labeled edge writing command</i>
211 GraphWriter& writeEdge(std::string name, const Edge& edge) {
212 edge_writer.writeEdge(name, edge);
215 /// \brief Issue a new attribute writing command.
217 /// This function issues a new <i> attribute writing command</i>
219 template <typename Value>
220 GraphWriter& writeAttribute(std::string name, const Value& value) {
221 attribute_writer.writeAttribute(name, value);
225 /// \brief Issue a new attribute writing command.
227 /// This function issues a new <i> attribute writing command</i>
229 template <typename Writer, typename Value>
230 GraphWriter& writeAttribute(std::string name, const Value& value,
231 const Writer& writer) {
232 attribute_writer.writeAttribute<Writer>(name, value, writer);
236 /// \brief Conversion operator to LemonWriter.
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.
242 operator LemonWriter&() {
246 /// \brief Executes the writing commands.
248 /// Executes the writing commands.
253 /// \brief Write the id of the given node.
255 /// It writes the id of the given node. If there was written an "id"
256 /// named node map then it will write the map value belonging to the node.
257 void writeId(std::ostream& os, const Node& item) const {
258 nodeset_writer.writeId(os, item);
261 /// \brief Write the id of the given edge.
263 /// It writes the id of the given edge. If there was written an "id"
264 /// named edge map then it will write the map value belonging to the edge.
265 void writeId(std::ostream& os, const Edge& item) const {
266 edgeset_writer.writeId(os, item);
274 NodeSetWriter<Graph, WriterTraits> nodeset_writer;
275 EdgeSetWriter<Graph, WriterTraits> edgeset_writer;
277 NodeWriter<Graph> node_writer;
278 EdgeWriter<Graph> edge_writer;
280 AttributeWriter<WriterTraits> attribute_writer;
284 ///\anchor writeGraph()
286 /// \brief Write a graph to the output.
288 /// Write a graph to the output.
289 /// \param os The output stream.
290 /// \param g The graph.
291 template<typename Graph>
292 void writeGraph(std::ostream& os, const Graph &g) {
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);
301 /// \brief Write a capacitated graph instance to the output.
303 /// Write a capacitated graph (graph+capacity on the
304 /// edges) to the output.
305 /// \param os The output stream.
306 /// \param g The graph.
307 /// \param capacity The capacity map.
308 template<typename Graph, typename CapacityMap>
309 void writeGraph(std::ostream& os, const Graph &g,
310 const CapacityMap& capacity) {
311 GraphWriter<Graph> writer(os, g);
312 IdMap<Graph, typename Graph::Node> nodeIdMap(g);
313 writer.writeNodeMap("id", nodeIdMap);
314 IdMap<Graph, typename Graph::Edge> edgeIdMap(g);
315 writer.writeEdgeMap("id", edgeIdMap);
316 writer.writeEdgeMap("capacity", capacity);
320 /// \brief Write a shortest path instance to the output.
322 /// Write a shortest path instance (graph+capacity on the
323 /// edges+designated source) to the output.
324 /// \param os The output stream.
325 /// \param g The graph.
326 /// \param capacity The capacity map.
327 /// \param s The source node.
328 template<typename Graph, typename CapacityMap>
329 void writeGraph(std::ostream& os, const Graph &g,
330 const CapacityMap& capacity, const typename Graph::Node &s) {
331 GraphWriter<Graph> writer(os, g);
332 IdMap<Graph, typename Graph::Node> nodeIdMap(g);
333 writer.writeNodeMap("id", nodeIdMap);
334 IdMap<Graph, typename Graph::Edge> edgeIdMap(g);
335 writer.writeEdgeMap("id", edgeIdMap);
336 writer.writeEdgeMap("capacity", capacity);
337 writer.writeNode("source", s);
342 /// \brief Write a max flow instance to the output.
344 /// Write a max flow instance (graph+capacity on the
345 /// edges+designated source and target) to the output.
347 /// \param os The output stream.
348 /// \param g The graph.
349 /// \param capacity The capacity map.
350 /// \param s The source node.
351 /// \param t The target node.
352 template<typename Graph, typename CapacityMap>
353 void writeGraph(std::ostream& os, const Graph &g,
354 const CapacityMap& capacity, const typename Graph::Node &s,
355 const typename Graph::Node &t) {
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);
362 writer.writeNode("source", s);
363 writer.writeNode("target", t);
367 /// \brief Write a min cost flow instance to the output.
369 /// Write a min cost flow instance (graph+capacity on the edges+cost
370 /// function on the edges+designated source and target) to the output.
372 /// \param os The output stream.
373 /// \param g The graph.
374 /// \param capacity The capacity map.
375 /// \param s The source node.
376 /// \param t The target node.
377 /// \param cost The cost map.
378 template<typename Graph, typename CapacityMap, typename CostMap>
379 void writeGraph(std::ostream& os, const Graph &g,
380 const CapacityMap& capacity, const typename Graph::Node &s,
381 const typename Graph::Node &t, const CostMap& cost) {
382 GraphWriter<Graph> writer(os, g);
383 IdMap<Graph, typename Graph::Node> nodeIdMap(g);
384 writer.writeNodeMap("id", nodeIdMap);
385 IdMap<Graph, typename Graph::Edge> edgeIdMap(g);
386 writer.writeEdgeMap("id", edgeIdMap);
387 writer.writeEdgeMap("capacity", capacity);
388 writer.writeEdgeMap("cost", cost);
389 writer.writeNode("source", s);
390 writer.writeNode("target", t);
394 /// \brief The undirected graph writer class.
396 /// The \c UndirGraphWriter class provides the undir graph output. To write
397 /// a graph you should first give writing commands to the writer. You can
398 /// declare write command as \c NodeMap, \c EdgeMap or \c UndirEdgeMap
399 /// writing and labeled Node, Edge or UndirEdge writing.
402 /// UndirGraphWriter<UndirListGraph> writer(std::cout, graph);
405 /// The \c writeNodeMap() function declares a \c NodeMap writing
406 /// command in the \c UndirGraphWriter. You should give as parameter
407 /// the name of the map and the map object. The NodeMap writing
408 /// command with name "id" should write a unique map because it
409 /// is regarded as ID map.
412 /// IdMap<UndirListGraph, Node> nodeIdMap;
413 /// writer.writeNodeMap("id", nodeIdMap);
415 /// writer.writeNodeMap("coords", coords);
416 /// writer.writeNodeMap("color", colorMap);
419 /// With the \c writeUndirEdgeMap() member function you can give an
420 /// undirected edge map writing command similar to the NodeMaps.
423 /// DescriptorMap<ListGraph, Edge, ListGraph::EdgeMap<int> >
424 /// edgeDescMap(graph);
425 /// writer.writeUndirEdgeMap("descriptor", edgeDescMap);
427 /// writer.writeUndirEdgeMap("weight", weightMap);
428 /// writer.writeUndirEdgeMap("label", labelMap);
431 /// The EdgeMap handling is just a syntactical sugar. It writes
432 /// two undirected edge map with '+' and '-' prefix in the name.
435 /// writer.writeEdgeMap("capacity", capacityMap);
439 /// With \c writeNode() and \c writeUndirEdge() functions you can
440 /// designate nodes and undirected edges in the graph. For example, you can
441 /// write out the source and target of the graph.
444 /// writer.writeNode("source", sourceNode);
445 /// writer.writeNode("target", targetNode);
447 /// writer.writeUndirEdge("observed", undirEdge);
450 /// After you give all write commands you must call the \c run() member
451 /// function, which executes all the writing commands.
457 /// \see DefaultWriterTraits
458 /// \see QuotedStringWriter
460 /// \see DescriptorMap
461 /// \see \ref GraphWriter
462 /// \see \ref graph-io-page
463 /// \author Balazs Dezso
464 template <typename _Graph, typename _WriterTraits = DefaultWriterTraits>
465 class UndirGraphWriter {
468 typedef _Graph Graph;
469 typedef typename Graph::Node Node;
470 typedef typename Graph::Edge Edge;
471 typedef typename Graph::UndirEdge UndirEdge;
473 typedef _WriterTraits WriterTraits;
475 /// \brief Construct a new UndirGraphWriter.
477 /// Construct a new UndirGraphWriter. It writes the given graph
478 /// to the given stream.
479 UndirGraphWriter(std::ostream& _os, const Graph& _graph)
480 : writer(new LemonWriter(_os)), own_writer(true),
481 nodeset_writer(*writer, _graph, std::string()),
482 undir_edgeset_writer(*writer, _graph, nodeset_writer, std::string()),
483 node_writer(*writer, nodeset_writer, std::string()),
484 undir_edge_writer(*writer, undir_edgeset_writer, std::string()),
485 attribute_writer(*writer, std::string()) {}
487 /// \brief Construct a new UndirGraphWriter.
489 /// Construct a new UndirGraphWriter. It writes the given graph
490 /// to the given file.
491 UndirGraphWriter(const std::string& _filename, const Graph& _graph)
492 : writer(new LemonWriter(_filename)), own_writer(true),
493 nodeset_writer(*writer, _graph, std::string()),
494 undir_edgeset_writer(*writer, _graph, nodeset_writer, std::string()),
495 node_writer(*writer, nodeset_writer, std::string()),
496 undir_edge_writer(*writer, undir_edgeset_writer, std::string()),
497 attribute_writer(*writer, std::string()) {}
499 /// \brief Construct a new UndirGraphWriter.
501 /// Construct a new UndirGraphWriter. It writes the given graph
502 /// to given LemonReader.
503 UndirGraphWriter(LemonWriter& _writer, const Graph& _graph)
504 : writer(_writer), own_writer(false),
505 nodeset_writer(*writer, _graph, std::string()),
506 undir_edgeset_writer(*writer, _graph, nodeset_writer, std::string()),
507 node_writer(*writer, nodeset_writer, std::string()),
508 undir_edge_writer(*writer, undir_edgeset_writer, std::string()),
509 attribute_writer(*writer, std::string()) {}
511 /// \brief Destruct the graph writer.
513 /// Destruct the graph writer.
514 ~UndirGraphWriter() {
519 /// \brief Issue a new node map writing command to the writer.
521 /// This function issues a new <i> node map writing command</i> to the writer.
522 template <typename Map>
523 UndirGraphWriter& writeNodeMap(std::string name, const Map& map) {
524 nodeset_writer.writeNodeMap(name, map);
528 /// \brief Issue a new node map writing command to the writer.
530 /// This function issues a new <i> node map writing command</i> to the writer.
531 template <typename Writer, typename Map>
532 UndirGraphWriter& writeNodeMap(std::string name, const Map& map,
533 const Writer& writer = Writer()) {
534 nodeset_writer.writeNodeMap(name, map, writer);
538 /// \brief Issue a new edge map writing command to the writer.
540 /// This function issues a new <i> edge map writing command</i> to the writer.
541 template <typename Map>
542 UndirGraphWriter& writeEdgeMap(std::string name, const Map& map) {
543 undir_edgeset_writer.writeEdgeMap(name, map);
547 /// \brief Issue a new edge map writing command to the writer.
549 /// This function issues a new <i> edge map writing command</i> to the writer.
550 template <typename Writer, typename Map>
551 UndirGraphWriter& writeEdgeMap(std::string name, const Map& map,
552 const Writer& writer = Writer()) {
553 undir_edgeset_writer.writeEdgeMap(name, map, writer);
557 /// \brief Issue a new undirected edge map writing command to the writer.
559 /// This function issues a new <i> undirected edge map writing
560 /// command</i> to the writer.
561 template <typename Map>
562 UndirGraphWriter& writeUndirEdgeMap(std::string name, const Map& map) {
563 undir_edgeset_writer.writeUndirEdgeMap(name, map);
567 /// \brief Issue a new undirected edge map writing command to the writer.
569 /// This function issues a new <i> undirected edge map writing
570 /// command</i> to the writer.
571 template <typename Writer, typename Map>
572 UndirGraphWriter& writeUndirEdgeMap(std::string name, const Map& map,
573 const Writer& writer = Writer()) {
574 undir_edgeset_writer.writeUndirEdgeMap(name, map, writer);
578 /// \brief Issue a new labeled node writer to the writer.
580 /// This function issues a new <i> labeled node writing
581 /// command</i> to the writer.
582 UndirGraphWriter& writeNode(std::string name, const Node& node) {
583 node_writer.writeNode(name, node);
587 /// \brief Issue a new labeled edge writer to the writer.
589 /// This function issues a new <i> labeled edge writing
590 /// command</i> to the writer.
591 UndirGraphWriter& writeEdge(std::string name, const Edge& edge) {
592 undir_edge_writer.writeEdge(name, edge);
595 /// \brief Issue a new labeled undirected edge writing command to
598 /// Issue a new <i>labeled undirected edge writing command</i> to
600 UndirGraphWriter& writeUndirEdge(std::string name, const UndirEdge& edge) {
601 undir_edge_writer.writeUndirEdge(name, edge);
604 /// \brief Issue a new attribute writing command.
606 /// This function issues a new <i> attribute writing
607 /// command</i> to the writer.
608 template <typename Value>
609 UndirGraphWriter& writeAttribute(std::string name, const Value& value) {
610 attribute_writer.writeAttribute(name, value);
614 /// \brief Issue a new attribute writing command.
616 /// This function issues a new <i> attribute writing
617 /// command</i> to the writer.
618 template <typename Writer, typename Value>
619 UndirGraphWriter& writeAttribute(std::string name, const Value& value,
620 const Writer& writer) {
621 attribute_writer.writeAttribute<Writer>(name, value, writer);
625 /// \brief Conversion operator to LemonWriter.
627 /// Conversion operator to LemonWriter. It makes possible
628 /// to access the encapsulated \e LemonWriter, this way
629 /// you can attach to this writer new instances of
630 /// \e LemonWriter::SectionWriter.
631 operator LemonWriter&() {
635 /// \brief Executes the writing commands.
637 /// Executes the writing commands.
642 /// \brief Write the id of the given node.
644 /// It writes the id of the given node. If there was written an "id"
645 /// named node map then it will write the map value belonging to the node.
646 void writeId(std::ostream& os, const Node& item) const {
647 nodeset_writer.writeId(os, item);
650 /// \brief Write the id of the given edge.
652 /// It writes the id of the given edge. If there was written an "id"
653 /// named edge map then it will write the map value belonging to the edge.
654 void writeId(std::ostream& os, const Edge& item) const {
655 undir_edgeset_writer.writeId(os, item);
658 /// \brief Write the id of the given undirected edge.
660 /// It writes the id of the given undirected edge. If there was written
661 /// an "id" named edge map then it will write the map value belonging to
663 void writeId(std::ostream& os, const UndirEdge& item) const {
664 undir_edgeset_writer.writeId(os, item);
673 NodeSetWriter<Graph, WriterTraits> nodeset_writer;
674 UndirEdgeSetWriter<Graph, WriterTraits> undir_edgeset_writer;
676 NodeWriter<Graph> node_writer;
677 UndirEdgeWriter<Graph> undir_edge_writer;
679 AttributeWriter<WriterTraits> attribute_writer;
682 /// \brief Write an undirected graph to the output.
684 /// Write an undirected graph to the output.
685 /// \param os The output stream.
686 /// \param g The graph.
687 template<typename Graph>
688 void writeUndirGraph(std::ostream& os, const Graph &g) {
689 UndirGraphWriter<Graph> writer(os, g);
693 /// \brief Write an undirected multigraph (undirected graph + capacity
694 /// map on the edges) to the output.
696 /// Write an undirected multigraph (undirected graph + capacity
697 /// map on the edges) to the output.
698 /// \param os The output stream.
699 /// \param g The graph.
700 /// \param capacity The capacity undirected map.
701 template<typename Graph, typename CapacityMap>
702 void writeUndirGraph(std::ostream& os, const Graph &g,
703 const CapacityMap& capacity) {
704 UndirGraphWriter<Graph> writer(os, g);
705 writer.writeUndirEdgeMap("capacity", capacity);