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".
41 /// If you don't need very sophisticated
42 /// behaviour then you can use the versions of the public function
43 /// \ref writeGraph() to output a graph (or a max flow instance etc).
46 /// you should first give writing commands to the writer. You can declare
47 /// write commands as \c NodeMap or \c EdgeMap writing and labeled Node and
51 /// GraphWriter<ListGraph> writer(std::cout, graph);
54 /// The \c writeNodeMap() function declares a \c NodeMap writing
55 /// command in the \c GraphWriter. You should give as parameter
56 /// the name of the map and the map object. The NodeMap writing
57 /// command with name "id" should write a unique map because it
58 /// is regarded as ID map (such a map is essential if the graph has edges).
61 /// IdMap<ListGraph, Node> nodeIdMap;
62 /// writer.writeNodeMap("id", nodeIdMap);
64 /// writer.writeNodeMap("coords", coords);
65 /// writer.writeNodeMap("color", colorMap);
68 /// With the \c writeEdgeMap() member function you can give an edge map
69 /// writing command similar to the NodeMaps.
72 /// DescriptorMap<ListGraph, Edge, ListGraph::EdgeMap<int> >
73 /// edgeDescMap(graph);
74 /// writer.writeEdgeMap("descriptor", edgeDescMap);
76 /// writer.writeEdgeMap("weight", weightMap);
77 /// writer.writeEdgeMap("label", labelMap);
80 /// With \c writeNode() and \c writeEdge() functions you can
81 /// point out Nodes and Edges in the graph. For example, you can
82 /// write out the source and target of a maximum flow instance.
85 /// writer.writeNode("source", sourceNode);
86 /// writer.writeNode("target", targetNode);
88 /// writer.writeEdge("observed", edge);
91 /// After you give all write commands you must call the \c run() member
92 /// function, which executes all the writing commands.
98 /// \see DefaultWriterTraits
99 /// \see QuotedStringWriter
101 /// \see DescriptorMap
102 /// \see \ref GraphReader
103 /// \see \ref graph-io-page
104 /// \author Balazs Dezso
105 template <typename _Graph, typename _WriterTraits = DefaultWriterTraits>
109 typedef _Graph Graph;
110 typedef typename Graph::Node Node;
111 typedef typename Graph::Edge Edge;
113 typedef _WriterTraits WriterTraits;
115 /// \brief Construct a new GraphWriter.
117 /// This function constructs a new GraphWriter to write the given graph
118 /// to the given stream.
119 GraphWriter(std::ostream& _os, const Graph& _graph)
120 : writer(new LemonWriter(_os)), own_writer(true),
121 nodeset_writer(*writer, _graph, std::string()),
122 edgeset_writer(*writer, _graph, nodeset_writer, std::string()),
123 node_writer(*writer, nodeset_writer, std::string()),
124 edge_writer(*writer, edgeset_writer, std::string()),
125 attribute_writer(*writer, std::string()) {}
127 /// \brief Construct a new GraphWriter.
129 /// This function constructs a new GraphWriter to write the given graph
130 /// to the given file.
131 GraphWriter(const std::string& _filename, const Graph& _graph)
132 : writer(new LemonWriter(_filename)), own_writer(true),
133 nodeset_writer(*writer, _graph, std::string()),
134 edgeset_writer(*writer, _graph, nodeset_writer, std::string()),
135 node_writer(*writer, nodeset_writer, std::string()),
136 edge_writer(*writer, edgeset_writer, std::string()),
137 attribute_writer(*writer, std::string()) {}
139 /// \brief Construct a new GraphWriter.
141 /// This function constructs a new GraphWriter to write the given graph
142 /// to the given LemonReader.
143 GraphWriter(LemonWriter& _writer, const Graph& _graph)
144 : writer(_writer), own_writer(false),
145 nodeset_writer(*writer, _graph, std::string()),
146 edgeset_writer(*writer, _graph, nodeset_writer, std::string()),
147 node_writer(*writer, nodeset_writer, std::string()),
148 edge_writer(*writer, edgeset_writer, std::string()),
149 attribute_writer(*writer, std::string()) {}
151 /// \brief Destruct the graph writer.
153 /// This function destructs the graph writer.
159 /// \brief Issue a new node map writing command for the writer.
161 /// This function issues a new <i> node map writing command</i> to the writer.
162 template <typename Map>
163 GraphWriter& writeNodeMap(std::string name, const Map& map) {
164 nodeset_writer.writeNodeMap(name, map);
169 /// \brief Issue a new node map writing command for the writer.
171 /// This function issues a new <i> node map writing command</i> to the writer.
172 template <typename Writer, typename Map>
173 GraphWriter& writeNodeMap(std::string name, const Map& map,
174 const Writer& writer = Writer()) {
175 nodeset_writer.writeNodeMap(name, map, writer);
180 /// \brief Issue a new edge map writing command for the writer.
182 /// This function issues a new <i> edge map writing command</i> to the writer.
183 template <typename Map>
184 GraphWriter& writeEdgeMap(std::string name, const Map& map) {
185 edgeset_writer.writeEdgeMap(name, map);
190 /// \brief Issue a new edge map writing command for the writer.
192 /// This function issues a new <i> edge map writing command</i> to the writer.
193 template <typename Writer, typename Map>
194 GraphWriter& writeEdgeMap(std::string name, const Map& map,
195 const Writer& writer = Writer()) {
196 edgeset_writer.writeEdgeMap(name, map, writer);
200 /// \brief Issue a new labeled node writing command to the writer.
202 /// This function issues a new <i> labeled node writing command</i>
204 GraphWriter& writeNode(std::string name, const Node& node) {
205 node_writer.writeNode(name, node);
209 /// \brief Issue a new labeled edge writing command to the writer.
211 /// This function issues a new <i> labeled edge writing command</i>
213 GraphWriter& writeEdge(std::string name, const Edge& edge) {
214 edge_writer.writeEdge(name, edge);
217 /// \brief Issue a new attribute writing command.
219 /// This function issues a new <i> attribute writing command</i>
221 template <typename Value>
222 GraphWriter& writeAttribute(std::string name, const Value& value) {
223 attribute_writer.writeAttribute(name, value);
227 /// \brief Issue a new attribute writing command.
229 /// This function issues a new <i> attribute writing command</i>
231 template <typename Writer, typename Value>
232 GraphWriter& writeAttribute(std::string name, const Value& value,
233 const Writer& writer) {
234 attribute_writer.writeAttribute<Writer>(name, value, writer);
238 /// \brief Conversion operator to LemonWriter.
240 /// Conversion operator to LemonWriter. It makes possible
241 /// to access the encapsulated \e LemonWriter, this way
242 /// you can attach to this writer new instances of
243 /// \e LemonWriter::SectionWriter. For more details see
244 /// the \ref rwbackground "Background of Reading and Writing".
245 operator LemonWriter&() {
249 /// \brief Executes the writing commands.
251 /// Executes the writing commands.
256 /// \brief Write the id of the given node.
258 /// It writes the id of the given node. If there was written an "id"
259 /// named node map then it will write the map value belonging to the node.
260 void writeId(std::ostream& os, const Node& item) const {
261 nodeset_writer.writeId(os, item);
264 /// \brief Write the id of the given edge.
266 /// It writes the id of the given edge. If there was written an "id"
267 /// named edge map then it will write the map value belonging to the edge.
268 void writeId(std::ostream& os, const Edge& item) const {
269 edgeset_writer.writeId(os, item);
277 NodeSetWriter<Graph, WriterTraits> nodeset_writer;
278 EdgeSetWriter<Graph, WriterTraits> edgeset_writer;
280 NodeWriter<Graph> node_writer;
281 EdgeWriter<Graph> edge_writer;
283 AttributeWriter<WriterTraits> attribute_writer;
287 ///\anchor writeGraph()
289 /// \brief Write a graph to the output.
291 /// Write a graph to the output.
292 /// \param os The output stream.
293 /// \param g The graph.
294 template<typename Graph>
295 void writeGraph(std::ostream& os, const Graph &g) {
296 GraphWriter<Graph> writer(os, g);
297 IdMap<Graph, typename Graph::Node> nodeIdMap(g);
298 writer.writeNodeMap("id", nodeIdMap);
299 IdMap<Graph, typename Graph::Edge> edgeIdMap(g);
300 writer.writeEdgeMap("id", edgeIdMap);
304 /// \brief Write a capacitated graph instance to the output.
306 /// Write a capacitated graph (graph+capacity on the
307 /// edges) to the output.
308 /// \param os The output stream.
309 /// \param g The graph.
310 /// \param capacity The capacity map.
311 template<typename Graph, typename CapacityMap>
312 void writeGraph(std::ostream& os, const Graph &g,
313 const CapacityMap& capacity) {
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);
323 /// \brief Write a shortest path instance to the output.
325 /// Write a shortest path instance (graph+capacity on the
326 /// edges+designated source) to the output.
327 /// \param os The output stream.
328 /// \param g The graph.
329 /// \param capacity The capacity map.
330 /// \param s The source node.
331 template<typename Graph, typename CapacityMap>
332 void writeGraph(std::ostream& os, const Graph &g,
333 const CapacityMap& capacity, const typename Graph::Node &s) {
334 GraphWriter<Graph> writer(os, g);
335 IdMap<Graph, typename Graph::Node> nodeIdMap(g);
336 writer.writeNodeMap("id", nodeIdMap);
337 IdMap<Graph, typename Graph::Edge> edgeIdMap(g);
338 writer.writeEdgeMap("id", edgeIdMap);
339 writer.writeEdgeMap("capacity", capacity);
340 writer.writeNode("source", s);
345 /// \brief Write a max flow instance to the output.
347 /// Write a max flow instance (graph+capacity on the
348 /// edges+designated source and target) to the output.
350 /// \param os The output stream.
351 /// \param g The graph.
352 /// \param capacity The capacity map.
353 /// \param s The source node.
354 /// \param t The target node.
355 template<typename Graph, typename CapacityMap>
356 void writeGraph(std::ostream& os, const Graph &g,
357 const CapacityMap& capacity, const typename Graph::Node &s,
358 const typename Graph::Node &t) {
359 GraphWriter<Graph> writer(os, g);
360 IdMap<Graph, typename Graph::Node> nodeIdMap(g);
361 writer.writeNodeMap("id", nodeIdMap);
362 IdMap<Graph, typename Graph::Edge> edgeIdMap(g);
363 writer.writeEdgeMap("id", edgeIdMap);
364 writer.writeEdgeMap("capacity", capacity);
365 writer.writeNode("source", s);
366 writer.writeNode("target", t);
370 /// \brief Write a min cost flow instance to the output.
372 /// Write a min cost flow instance (graph+capacity on the edges+cost
373 /// function on the edges+designated source and target) to the output.
375 /// \param os The output stream.
376 /// \param g The graph.
377 /// \param capacity The capacity map.
378 /// \param s The source node.
379 /// \param t The target node.
380 /// \param cost The cost map.
381 template<typename Graph, typename CapacityMap, typename CostMap>
382 void writeGraph(std::ostream& os, const Graph &g,
383 const CapacityMap& capacity, const typename Graph::Node &s,
384 const typename Graph::Node &t, const CostMap& cost) {
385 GraphWriter<Graph> writer(os, g);
386 IdMap<Graph, typename Graph::Node> nodeIdMap(g);
387 writer.writeNodeMap("id", nodeIdMap);
388 IdMap<Graph, typename Graph::Edge> edgeIdMap(g);
389 writer.writeEdgeMap("id", edgeIdMap);
390 writer.writeEdgeMap("capacity", capacity);
391 writer.writeEdgeMap("cost", cost);
392 writer.writeNode("source", s);
393 writer.writeNode("target", t);
397 /// \brief The undirected graph writer class.
399 /// The \c UndirGraphWriter class provides the undir graph output. To write
400 /// a graph you should first give writing commands to the writer. You can
401 /// declare write command as \c NodeMap, \c EdgeMap or \c UndirEdgeMap
402 /// writing and labeled Node, Edge or UndirEdge writing.
405 /// UndirGraphWriter<UndirListGraph> writer(std::cout, graph);
408 /// The \c writeNodeMap() function declares a \c NodeMap writing
409 /// command in the \c UndirGraphWriter. You should give as parameter
410 /// the name of the map and the map object. The NodeMap writing
411 /// command with name "id" should write a unique map because it
412 /// is regarded as ID map.
415 /// IdMap<UndirListGraph, Node> nodeIdMap;
416 /// writer.writeNodeMap("id", nodeIdMap);
418 /// writer.writeNodeMap("coords", coords);
419 /// writer.writeNodeMap("color", colorMap);
422 /// With the \c writeUndirEdgeMap() member function you can give an
423 /// undirected edge map writing command similar to the NodeMaps.
426 /// DescriptorMap<ListGraph, Edge, ListGraph::EdgeMap<int> >
427 /// edgeDescMap(graph);
428 /// writer.writeUndirEdgeMap("descriptor", edgeDescMap);
430 /// writer.writeUndirEdgeMap("weight", weightMap);
431 /// writer.writeUndirEdgeMap("label", labelMap);
434 /// The EdgeMap handling is just a syntactical sugar. It writes
435 /// two undirected edge map with '+' and '-' prefix in the name.
438 /// writer.writeEdgeMap("capacity", capacityMap);
442 /// With \c writeNode() and \c writeUndirEdge() functions you can
443 /// designate nodes and undirected edges in the graph. For example, you can
444 /// write out the source and target of the graph.
447 /// writer.writeNode("source", sourceNode);
448 /// writer.writeNode("target", targetNode);
450 /// writer.writeUndirEdge("observed", undirEdge);
453 /// After you give all write commands you must call the \c run() member
454 /// function, which executes all the writing commands.
460 /// \see DefaultWriterTraits
461 /// \see QuotedStringWriter
463 /// \see DescriptorMap
464 /// \see \ref GraphWriter
465 /// \see \ref graph-io-page
466 /// \author Balazs Dezso
467 template <typename _Graph, typename _WriterTraits = DefaultWriterTraits>
468 class UndirGraphWriter {
471 typedef _Graph Graph;
472 typedef typename Graph::Node Node;
473 typedef typename Graph::Edge Edge;
474 typedef typename Graph::UndirEdge UndirEdge;
476 typedef _WriterTraits WriterTraits;
478 /// \brief Construct a new UndirGraphWriter.
480 /// Construct a new UndirGraphWriter. It writes the given graph
481 /// to the given stream.
482 UndirGraphWriter(std::ostream& _os, const Graph& _graph)
483 : writer(new LemonWriter(_os)), own_writer(true),
484 nodeset_writer(*writer, _graph, std::string()),
485 undir_edgeset_writer(*writer, _graph, nodeset_writer, std::string()),
486 node_writer(*writer, nodeset_writer, std::string()),
487 undir_edge_writer(*writer, undir_edgeset_writer, std::string()),
488 attribute_writer(*writer, std::string()) {}
490 /// \brief Construct a new UndirGraphWriter.
492 /// Construct a new UndirGraphWriter. It writes the given graph
493 /// to the given file.
494 UndirGraphWriter(const std::string& _filename, const Graph& _graph)
495 : writer(new LemonWriter(_filename)), own_writer(true),
496 nodeset_writer(*writer, _graph, std::string()),
497 undir_edgeset_writer(*writer, _graph, nodeset_writer, std::string()),
498 node_writer(*writer, nodeset_writer, std::string()),
499 undir_edge_writer(*writer, undir_edgeset_writer, std::string()),
500 attribute_writer(*writer, std::string()) {}
502 /// \brief Construct a new UndirGraphWriter.
504 /// Construct a new UndirGraphWriter. It writes the given graph
505 /// to given LemonReader.
506 UndirGraphWriter(LemonWriter& _writer, const Graph& _graph)
507 : writer(_writer), own_writer(false),
508 nodeset_writer(*writer, _graph, std::string()),
509 undir_edgeset_writer(*writer, _graph, nodeset_writer, std::string()),
510 node_writer(*writer, nodeset_writer, std::string()),
511 undir_edge_writer(*writer, undir_edgeset_writer, std::string()),
512 attribute_writer(*writer, std::string()) {}
514 /// \brief Destruct the graph writer.
516 /// Destruct the graph writer.
517 ~UndirGraphWriter() {
522 /// \brief Issue a new node map writing command to the writer.
524 /// This function issues a new <i> node map writing command</i> to the writer.
525 template <typename Map>
526 UndirGraphWriter& writeNodeMap(std::string name, const Map& map) {
527 nodeset_writer.writeNodeMap(name, map);
531 /// \brief Issue a new node map writing command to the writer.
533 /// This function issues a new <i> node map writing command</i> to the writer.
534 template <typename Writer, typename Map>
535 UndirGraphWriter& writeNodeMap(std::string name, const Map& map,
536 const Writer& writer = Writer()) {
537 nodeset_writer.writeNodeMap(name, map, writer);
541 /// \brief Issue a new edge map writing command to the writer.
543 /// This function issues a new <i> edge map writing command</i> to the writer.
544 template <typename Map>
545 UndirGraphWriter& writeEdgeMap(std::string name, const Map& map) {
546 undir_edgeset_writer.writeEdgeMap(name, map);
550 /// \brief Issue a new edge map writing command to the writer.
552 /// This function issues a new <i> edge map writing command</i> to the writer.
553 template <typename Writer, typename Map>
554 UndirGraphWriter& writeEdgeMap(std::string name, const Map& map,
555 const Writer& writer = Writer()) {
556 undir_edgeset_writer.writeEdgeMap(name, map, writer);
560 /// \brief Issue a new undirected edge map writing command to the writer.
562 /// This function issues a new <i> undirected edge map writing
563 /// command</i> to the writer.
564 template <typename Map>
565 UndirGraphWriter& writeUndirEdgeMap(std::string name, const Map& map) {
566 undir_edgeset_writer.writeUndirEdgeMap(name, map);
570 /// \brief Issue a new undirected edge map writing command to the writer.
572 /// This function issues a new <i> undirected edge map writing
573 /// command</i> to the writer.
574 template <typename Writer, typename Map>
575 UndirGraphWriter& writeUndirEdgeMap(std::string name, const Map& map,
576 const Writer& writer = Writer()) {
577 undir_edgeset_writer.writeUndirEdgeMap(name, map, writer);
581 /// \brief Issue a new labeled node writer to the writer.
583 /// This function issues a new <i> labeled node writing
584 /// command</i> to the writer.
585 UndirGraphWriter& writeNode(std::string name, const Node& node) {
586 node_writer.writeNode(name, node);
590 /// \brief Issue a new labeled edge writer to the writer.
592 /// This function issues a new <i> labeled edge writing
593 /// command</i> to the writer.
594 UndirGraphWriter& writeEdge(std::string name, const Edge& edge) {
595 undir_edge_writer.writeEdge(name, edge);
598 /// \brief Issue a new labeled undirected edge writing command to
601 /// Issue a new <i>labeled undirected edge writing command</i> to
603 UndirGraphWriter& writeUndirEdge(std::string name, const UndirEdge& edge) {
604 undir_edge_writer.writeUndirEdge(name, edge);
607 /// \brief Issue a new attribute writing command.
609 /// This function issues a new <i> attribute writing
610 /// command</i> to the writer.
611 template <typename Value>
612 UndirGraphWriter& writeAttribute(std::string name, const Value& value) {
613 attribute_writer.writeAttribute(name, value);
617 /// \brief Issue a new attribute writing command.
619 /// This function issues a new <i> attribute writing
620 /// command</i> to the writer.
621 template <typename Writer, typename Value>
622 UndirGraphWriter& writeAttribute(std::string name, const Value& value,
623 const Writer& writer) {
624 attribute_writer.writeAttribute<Writer>(name, value, writer);
628 /// \brief Conversion operator to LemonWriter.
630 /// Conversion operator to LemonWriter. It makes possible
631 /// to access the encapsulated \e LemonWriter, this way
632 /// you can attach to this writer new instances of
633 /// \e LemonWriter::SectionWriter.
634 operator LemonWriter&() {
638 /// \brief Executes the writing commands.
640 /// Executes the writing commands.
645 /// \brief Write the id of the given node.
647 /// It writes the id of the given node. If there was written an "id"
648 /// named node map then it will write the map value belonging to the node.
649 void writeId(std::ostream& os, const Node& item) const {
650 nodeset_writer.writeId(os, item);
653 /// \brief Write the id of the given edge.
655 /// It writes the id of the given edge. If there was written an "id"
656 /// named edge map then it will write the map value belonging to the edge.
657 void writeId(std::ostream& os, const Edge& item) const {
658 undir_edgeset_writer.writeId(os, item);
661 /// \brief Write the id of the given undirected edge.
663 /// It writes the id of the given undirected edge. If there was written
664 /// an "id" named edge map then it will write the map value belonging to
666 void writeId(std::ostream& os, const UndirEdge& item) const {
667 undir_edgeset_writer.writeId(os, item);
676 NodeSetWriter<Graph, WriterTraits> nodeset_writer;
677 UndirEdgeSetWriter<Graph, WriterTraits> undir_edgeset_writer;
679 NodeWriter<Graph> node_writer;
680 UndirEdgeWriter<Graph> undir_edge_writer;
682 AttributeWriter<WriterTraits> attribute_writer;
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);
696 /// \brief Write an undirected multigraph (undirected graph + capacity
697 /// map on the edges) to the output.
699 /// Write an undirected multigraph (undirected graph + capacity
700 /// map on the edges) to the output.
701 /// \param os The output stream.
702 /// \param g The graph.
703 /// \param capacity The capacity undirected map.
704 template<typename Graph, typename CapacityMap>
705 void writeUndirGraph(std::ostream& os, const Graph &g,
706 const CapacityMap& capacity) {
707 UndirGraphWriter<Graph> writer(os, g);
708 writer.writeUndirEdgeMap("capacity", capacity);