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. 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
42 /// GraphWriter<ListGraph> writer(std::cout, graph);
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.
52 /// IdMap<ListGraph, Node> nodeIdMap;
53 /// writer.writeNodeMap("id", nodeIdMap);
55 /// writer.writeNodeMap("coords", coords);
56 /// writer.writeNodeMap("color", colorMap);
59 /// With the \c writeEdgeMap() member function you can give an edge map
60 /// writing command similar to the NodeMaps.
63 /// DescriptorMap<ListGraph, Edge, ListGraph::EdgeMap<int> >
64 /// edgeDescMap(graph);
65 /// writer.writeEdgeMap("descriptor", edgeDescMap);
67 /// writer.writeEdgeMap("weight", weightMap);
68 /// writer.writeEdgeMap("label", labelMap);
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.
76 /// writer.writeNode("source", sourceNode);
77 /// writer.writeNode("target", targetNode);
79 /// writer.writeEdge("observed", edge);
82 /// After you give all write commands you must call the \c run() member
83 /// function, which execute all the writer commands.
89 /// \see DefaultWriterTraits
90 /// \see QuotedStringWriter
92 /// \see DescriptorMap
93 /// \see \ref GraphReader
94 /// \see \ref graph-io-page
95 /// \author Balazs Dezso
96 template <typename _Graph, typename _WriterTraits = DefaultWriterTraits>
100 typedef _Graph Graph;
101 typedef typename Graph::Node Node;
102 typedef typename Graph::Edge Edge;
104 typedef _WriterTraits WriterTraits;
106 /// \brief Construct a new GraphWriter.
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()) {}
118 /// \brief Construct a new GraphWriter.
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()) {}
130 /// \brief Construct a new GraphWriter.
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()) {}
142 /// \brief Destruct the graph writer.
144 /// Destruct the graph writer.
150 /// \brief Add a new node map writer command for the writer.
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);
159 /// \brief Add a new node map writer command for the writer.
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);
170 /// \brief Add a new edge map writer command for the writer.
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);
180 /// \brief Add a new edge map writer command for the writer.
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);
190 /// \brief Add a new labeled node writer for the writer.
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);
198 /// \brief Add a new labeled edge writer for the writer.
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);
205 /// \brief Add a new attribute writer command.
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);
214 /// \brief Add a new attribute writer command.
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);
224 /// \brief Conversion operator to LemonWriter.
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&() {
234 /// \brief Executes the writer commands.
236 /// Executes the writer commands.
241 /// \brief Write the id of the given node.
243 /// It writes the id of the given node. If there was written an "id"
244 /// named node map then it will write the map value belongs to the node.
245 void writeId(std::ostream& os, const Node& item) const {
246 nodeset_writer.writeId(os, item);
249 /// \brief Write the id of the given edge.
251 /// It writes the id of the given edge. If there was written an "id"
252 /// named edge map then it will write the map value belongs to the edge.
253 void writeId(std::ostream& os, const Edge& item) const {
254 edgeset_writer.writeId(os, item);
262 NodeSetWriter<Graph, WriterTraits> nodeset_writer;
263 EdgeSetWriter<Graph, WriterTraits> edgeset_writer;
265 NodeWriter<Graph> node_writer;
266 EdgeWriter<Graph> edge_writer;
268 AttributeWriter<WriterTraits> attribute_writer;
272 /// \brief Write a graph to the output.
274 /// Write a graph to the output.
275 /// \param os The output stream.
276 /// \param g The graph.
277 /// \param capacity The capacity map.
278 /// \param s The source node.
279 /// \param t The target node.
280 /// \param cost The cost map.
281 template<typename Graph, typename CapacityMap, typename CostMap>
282 void writeGraph(std::ostream& os, const Graph &g,
283 const CapacityMap& capacity, const typename Graph::Node &s,
284 const typename Graph::Node &t, const CostMap& cost) {
285 GraphWriter<Graph> writer(os, g);
286 IdMap<Graph, typename Graph::Node> nodeIdMap(g);
287 writer.writeNodeMap("id", nodeIdMap);
288 IdMap<Graph, typename Graph::Edge> edgeIdMap(g);
289 writer.writeEdgeMap("id", edgeIdMap);
290 writer.writeEdgeMap("capacity", capacity);
291 writer.writeEdgeMap("cost", cost);
292 writer.writeNode("source", s);
293 writer.writeNode("target", t);
297 /// \brief Write a graph to the output.
299 /// Write a graph to the output.
300 /// \param os The output stream.
301 /// \param g The graph.
302 /// \param capacity The capacity map.
303 /// \param s The source node.
304 /// \param t The target node.
305 template<typename Graph, typename CapacityMap>
306 void writeGraph(std::ostream& os, const Graph &g,
307 const CapacityMap& capacity, const typename Graph::Node &s,
308 const typename Graph::Node &t) {
309 GraphWriter<Graph> writer(os, g);
310 IdMap<Graph, typename Graph::Node> nodeIdMap(g);
311 writer.writeNodeMap("id", nodeIdMap);
312 IdMap<Graph, typename Graph::Edge> edgeIdMap(g);
313 writer.writeEdgeMap("id", edgeIdMap);
314 writer.writeEdgeMap("capacity", capacity);
315 writer.writeNode("source", s);
316 writer.writeNode("target", t);
320 /// \brief Write a graph to the output.
322 /// Write a graph to the output.
323 /// \param os The output stream.
324 /// \param g The graph.
325 /// \param capacity The capacity map.
326 /// \param s The source node.
327 template<typename Graph, typename CapacityMap>
328 void writeGraph(std::ostream& os, const Graph &g,
329 const CapacityMap& capacity, const typename Graph::Node &s) {
330 GraphWriter<Graph> writer(os, g);
331 IdMap<Graph, typename Graph::Node> nodeIdMap(g);
332 writer.writeNodeMap("id", nodeIdMap);
333 IdMap<Graph, typename Graph::Edge> edgeIdMap(g);
334 writer.writeEdgeMap("id", edgeIdMap);
335 writer.writeEdgeMap("capacity", capacity);
336 writer.writeNode("source", s);
340 /// \brief Write a graph to the output.
342 /// Write a graph to the output.
343 /// \param os The output stream.
344 /// \param g The graph.
345 /// \param capacity The capacity map.
346 template<typename Graph, typename CapacityMap>
347 void writeGraph(std::ostream& os, const Graph &g,
348 const CapacityMap& capacity) {
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.writeEdgeMap("capacity", capacity);
358 /// \brief Write a graph to the output.
360 /// Write a graph to the output.
361 /// \param os The output stream.
362 /// \param g The graph.
363 template<typename Graph>
364 void writeGraph(std::ostream& os, const Graph &g) {
365 GraphWriter<Graph> writer(os, g);
366 IdMap<Graph, typename Graph::Node> nodeIdMap(g);
367 writer.writeNodeMap("id", nodeIdMap);
368 IdMap<Graph, typename Graph::Edge> edgeIdMap(g);
369 writer.writeEdgeMap("id", edgeIdMap);
373 /// \brief The undirected graph writer class.
375 /// The \c UndirGraphWriter class provides the undir graph output. To write
376 /// a graph you should first give writing commands for the writer. You can
377 /// declare write command as \c NodeMap, \c EdgeMap or \c UndirEdgeMap
378 /// writing and labeled Node, Edge or UndirEdge writing.
381 /// UndirGraphWriter<UndirListGraph> writer(std::cout, graph);
384 /// The \c writeNodeMap() function declares a \c NodeMap writing
385 /// command in the \c UndirGraphWriter. You should give as parameter
386 /// the name of the map and the map object. The NodeMap writing
387 /// command with name "id" should write a unique map because it
388 /// is regarded as ID map.
391 /// IdMap<UndirListGraph, Node> nodeIdMap;
392 /// writer.writeNodeMap("id", nodeIdMap);
394 /// writer.writeNodeMap("coords", coords);
395 /// writer.writeNodeMap("color", colorMap);
398 /// With the \c writeUndirEdgeMap() member function you can give an
399 /// undirected edge map writing command similar to the NodeMaps.
402 /// DescriptorMap<ListGraph, Edge, ListGraph::EdgeMap<int> >
403 /// edgeDescMap(graph);
404 /// writer.writeUndirEdgeMap("descriptor", edgeDescMap);
406 /// writer.writeUndirEdgeMap("weight", weightMap);
407 /// writer.writeUndirEdgeMap("label", labelMap);
410 /// The EdgeMap handling is just a syntactical sugar. It writes
411 /// two undirected edge map with '+' and '-' prefix in the name.
414 /// writer.writeEdgeMap("capacity", capacityMap);
418 /// With \c writeNode() and \c writeUndirEdge() functions you can
419 /// point out nodes and undirected edges in the graph. By example, you can
420 /// write out the source and target of the graph.
423 /// writer.writeNode("source", sourceNode);
424 /// writer.writeNode("target", targetNode);
426 /// writer.writeUndirEdge("observed", undirEdge);
429 /// After you give all write commands you must call the \c run() member
430 /// function, which execute all the writer commands.
436 /// \see DefaultWriterTraits
437 /// \see QuotedStringWriter
439 /// \see DescriptorMap
440 /// \see \ref GraphWriter
441 /// \see \ref graph-io-page
442 /// \author Balazs Dezso
443 template <typename _Graph, typename _WriterTraits = DefaultWriterTraits>
444 class UndirGraphWriter {
447 typedef _Graph Graph;
448 typedef typename Graph::Node Node;
449 typedef typename Graph::Edge Edge;
450 typedef typename Graph::UndirEdge UndirEdge;
452 typedef _WriterTraits WriterTraits;
454 /// \brief Construct a new UndirGraphWriter.
456 /// Construct a new UndirGraphWriter. It writes the given graph
457 /// to the given stream.
458 UndirGraphWriter(std::ostream& _os, const Graph& _graph)
459 : writer(new LemonWriter(_os)), own_writer(true),
460 nodeset_writer(*writer, _graph, std::string()),
461 undir_edgeset_writer(*writer, _graph, nodeset_writer, std::string()),
462 node_writer(*writer, nodeset_writer, std::string()),
463 undir_edge_writer(*writer, undir_edgeset_writer, std::string()),
464 attribute_writer(*writer, std::string()) {}
466 /// \brief Construct a new UndirGraphWriter.
468 /// Construct a new UndirGraphWriter. It writes into the given graph
469 /// to the given file.
470 UndirGraphWriter(const std::string& _filename, const Graph& _graph)
471 : writer(new LemonWriter(_filename)), own_writer(true),
472 nodeset_writer(*writer, _graph, std::string()),
473 undir_edgeset_writer(*writer, _graph, nodeset_writer, std::string()),
474 node_writer(*writer, nodeset_writer, std::string()),
475 undir_edge_writer(*writer, undir_edgeset_writer, std::string()),
476 attribute_writer(*writer, std::string()) {}
478 /// \brief Construct a new UndirGraphWriter.
480 /// Construct a new UndirGraphWriter. It writes into the given graph
481 /// to given LemonReader.
482 UndirGraphWriter(LemonWriter& _writer, const Graph& _graph)
483 : writer(_writer), own_writer(false),
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 Destruct the graph writer.
492 /// Destruct the graph writer.
493 ~UndirGraphWriter() {
498 /// \brief Add a new node map writer command for the writer.
500 /// Add a new node map writer command for the writer.
501 template <typename Map>
502 UndirGraphWriter& writeNodeMap(std::string name, const Map& map) {
503 nodeset_writer.writeNodeMap(name, map);
507 /// \brief Add a new node map writer command for the writer.
509 /// Add a new node map writer command for the writer.
510 template <typename Writer, typename Map>
511 UndirGraphWriter& writeNodeMap(std::string name, const Map& map,
512 const Writer& writer = Writer()) {
513 nodeset_writer.writeNodeMap(name, map, writer);
517 /// \brief Add a new edge map writer command for the writer.
519 /// Add a new edge map writer command for the writer.
520 template <typename Map>
521 UndirGraphWriter& writeEdgeMap(std::string name, const Map& map) {
522 undir_edgeset_writer.writeEdgeMap(name, map);
526 /// \brief Add a new edge map writer command for the writer.
528 /// Add a new edge map writer command for the writer.
529 template <typename Writer, typename Map>
530 UndirGraphWriter& writeEdgeMap(std::string name, const Map& map,
531 const Writer& writer = Writer()) {
532 undir_edgeset_writer.writeEdgeMap(name, map, writer);
536 /// \brief Add a new undirected edge map writer command for the writer.
538 /// Add a new undirected edge map writer command for the writer.
539 template <typename Map>
540 UndirGraphWriter& writeUndirEdgeMap(std::string name, const Map& map) {
541 undir_edgeset_writer.writeUndirEdgeMap(name, map);
545 /// \brief Add a new undirected edge map writer command for the writer.
547 /// Add a new edge undirected map writer command for the writer.
548 template <typename Writer, typename Map>
549 UndirGraphWriter& writeUndirEdgeMap(std::string name, const Map& map,
550 const Writer& writer = Writer()) {
551 undir_edgeset_writer.writeUndirEdgeMap(name, map, writer);
555 /// \brief Add a new labeled node writer for the writer.
557 /// Add a new labeled node writer for the writer.
558 UndirGraphWriter& writeNode(std::string name, const Node& node) {
559 node_writer.writeNode(name, node);
563 /// \brief Add a new labeled edge writer for the writer.
565 /// Add a new labeled edge writer for the writer.
566 UndirGraphWriter& writeEdge(std::string name, const Edge& edge) {
567 undir_edge_writer.writeEdge(name, edge);
570 /// \brief Add a new labeled undirected edge writer for the writer.
572 /// Add a new labeled undirected edge writer for the writer.
573 UndirGraphWriter& writeUndirEdge(std::string name, const UndirEdge& edge) {
574 undir_edge_writer.writeUndirEdge(name, edge);
577 /// \brief Add a new attribute writer command.
579 /// Add a new attribute writer command.
580 template <typename Value>
581 UndirGraphWriter& writeAttribute(std::string name, const Value& value) {
582 attribute_writer.writeAttribute(name, value);
586 /// \brief Add a new attribute writer command.
588 /// Add a new attribute writer command.
589 template <typename Writer, typename Value>
590 UndirGraphWriter& writeAttribute(std::string name, const Value& value,
591 const Writer& writer) {
592 attribute_writer.writeAttribute<Writer>(name, value, writer);
596 /// \brief Conversion operator to LemonWriter.
598 /// Conversion operator to LemonWriter. It make possible
599 /// to access the encapsulated \e LemonWriter, this way
600 /// you can attach to this writer new instances of
601 /// \e LemonWriter::SectionWriter.
602 operator LemonWriter&() {
606 /// \brief Executes the writer commands.
608 /// Executes the writer commands.
613 /// \brief Write the id of the given node.
615 /// It writes the id of the given node. If there was written an "id"
616 /// named node map then it will write the map value belongs to the node.
617 void writeId(std::ostream& os, const Node& item) const {
618 nodeset_writer.writeId(os, item);
621 /// \brief Write the id of the given edge.
623 /// It writes the id of the given edge. If there was written an "id"
624 /// named edge map then it will write the map value belongs to the edge.
625 void writeId(std::ostream& os, const Edge& item) const {
626 undir_edgeset_writer.writeId(os, item);
629 /// \brief Write the id of the given undirected edge.
631 /// It writes the id of the given undirected edge. If there was written
632 /// an "id" named edge map then it will write the map value belongs to
634 void writeId(std::ostream& os, const UndirEdge& item) const {
635 undir_edgeset_writer.writeId(os, item);
644 NodeSetWriter<Graph, WriterTraits> nodeset_writer;
645 UndirEdgeSetWriter<Graph, WriterTraits> undir_edgeset_writer;
647 NodeWriter<Graph> node_writer;
648 UndirEdgeWriter<Graph> undir_edge_writer;
650 AttributeWriter<WriterTraits> attribute_writer;
654 /// \brief Write an undirected graph to the output.
656 /// Write an undirected graph to the output.
657 /// \param os The output stream.
658 /// \param g The graph.
659 /// \param capacity The capacity undirected map.
660 template<typename Graph, typename CapacityMap>
661 void writeUndirGraph(std::ostream& os, const Graph &g,
662 const CapacityMap& capacity) {
663 UndirGraphWriter<Graph> writer(os, g);
664 writer.writeUndirEdgeMap("capacity", capacity);
668 /// \brief Write an undirected graph to the output.
670 /// Write an undirected graph to the output.
671 /// \param os The output stream.
672 /// \param g The graph.
673 template<typename Graph>
674 void writeUndirGraph(std::ostream& os, const Graph &g) {
675 UndirGraphWriter<Graph> writer(os, g);