2 * src/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.
246 NodeSetWriter<Graph, WriterTraits> nodeset_writer;
247 EdgeSetWriter<Graph, WriterTraits> edgeset_writer;
249 NodeWriter<Graph> node_writer;
250 EdgeWriter<Graph> edge_writer;
252 AttributeWriter<WriterTraits> attribute_writer;
256 /// \brief Write a graph to the output.
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);
281 /// \brief Write a graph to the output.
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);
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 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);
324 /// \brief Write a graph to the output.
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);
342 /// \brief Write a graph to the output.
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);
357 /// \brief The undirected graph writer class.
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.
365 /// UndirGraphWriter<UndirListGraph> writer(std::cout, graph);
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.
375 /// IdMap<UndirListGraph, Node> nodeIdMap;
376 /// writer.writeNodeMap("id", nodeIdMap);
378 /// writer.writeNodeMap("coords", coords);
379 /// writer.writeNodeMap("color", colorMap);
382 /// With the \c writeUndirEdgeMap() member function you can give an
383 /// undirected edge map writing command similar to the NodeMaps.
386 /// DescriptorMap<ListGraph, Edge, ListGraph::EdgeMap<int> >
387 /// edgeDescMap(graph);
388 /// writer.writeUndirEdgeMap("descriptor", edgeDescMap);
390 /// writer.writeUndirEdgeMap("weight", weightMap);
391 /// writer.writeUndirEdgeMap("label", labelMap);
394 /// The EdgeMap handling is just a syntactical sugar. It writes
395 /// two undirected edge map with '+' and '-' prefix in the name.
398 /// writer.writeEdgeMap("capacity", capacityMap);
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.
407 /// writer.writeNode("source", sourceNode);
408 /// writer.writeNode("target", targetNode);
410 /// writer.writeUndirEdge("observed", undirEdge);
413 /// After you give all write commands you must call the \c run() member
414 /// function, which execute all the writer commands.
420 /// \see DefaultWriterTraits
421 /// \see QuotedStringWriter
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 {
431 typedef _Graph Graph;
432 typedef typename Graph::Node Node;
433 typedef typename Graph::Edge Edge;
434 typedef typename Graph::UndirEdge UndirEdge;
436 typedef _WriterTraits WriterTraits;
438 /// \brief Construct a new UndirGraphWriter.
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()) {}
450 /// \brief Construct a new UndirGraphWriter.
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()) {}
462 /// \brief Construct a new UndirGraphWriter.
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()) {}
474 /// \brief Destruct the graph writer.
476 /// Destruct the graph writer.
477 ~UndirGraphWriter() {
482 /// \brief Add a new node map writer command for the writer.
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);
491 /// \brief Add a new node map writer command for the writer.
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);
501 /// \brief Add a new edge map writer command for the writer.
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);
510 /// \brief Add a new edge map writer command for the writer.
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);
520 /// \brief Add a new undirected edge map writer command for the writer.
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);
529 /// \brief Add a new undirected edge map writer command for the writer.
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);
539 /// \brief Add a new labeled node writer for the writer.
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);
547 /// \brief Add a new labeled edge writer for the writer.
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);
554 /// \brief Add a new attribute writer command.
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);
563 /// \brief Add a new attribute writer command.
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);
573 /// \brief Conversion operator to LemonWriter.
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&() {
583 /// \brief Executes the writer commands.
585 /// Executes the writer commands.
595 NodeSetWriter<Graph, WriterTraits> nodeset_writer;
596 UndirEdgeSetWriter<Graph, WriterTraits> undir_edgeset_writer;
598 NodeWriter<Graph> node_writer;
599 UndirEdgeWriter<Graph> undir_edge_writer;
601 AttributeWriter<WriterTraits> attribute_writer;
605 /// \brief Write an undirected graph to the output.
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);
619 /// \brief Write an undirected graph to the output.
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);