2 * lemon/graph_reader.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 reader.
21 #ifndef LEMON_GRAPH_READER_H
22 #define LEMON_GRAPH_READER_H
26 #include <lemon/error.h>
27 #include <lemon/lemon_reader.h>
31 /// \addtogroup io_group
34 /// \brief The graph reader class.
36 /// The given file format may contain several maps and labeled nodes or
39 /// If you read a graph you need not read all the maps and items just those
40 /// that you need. The interface of the \c GraphReader is very similar to
41 /// the GraphWriter but the reading method does not depend on the order the
44 /// The reader object suppose that each not readed value does not contain
45 /// whitespaces, therefore it has some extra possibilities to control how
46 /// it should skip the values when the string representation contains spaces.
49 /// GraphReader<ListGraph> reader(std::cin, graph);
52 /// The \c readNodeMap() function reads a map from the \c \@nodeset section.
53 /// If there is a map that you do not want to read from the file and there is
54 /// whitespace in the string represenation of the values then you should
55 /// call the \c skipNodeMap() template member function with proper
59 /// reader.readNodeMap("coords", coords);
61 /// reader.readNodeMap<QuotedStringReader>("label", labelMap);
62 /// reader.skipNodeMap<QuotedStringReader>("description");
64 /// reader.readNodeMap("color", colorMap);
67 /// With the \c readEdgeMap() member function you can give an edge map
68 /// reading command similar to the NodeMaps.
71 /// reader.readEdgeMap("weight", weightMap);
72 /// reader.readEdgeMap("label", labelMap);
75 /// With \c readNode() and \c readEdge() functions you can read
76 /// labeled Nodes and Edges.
79 /// reader.readNode("source", sourceNode);
80 /// reader.readNode("target", targetNode);
82 /// reader.readEdge("observed", edge);
85 /// With the \c readAttribute() functions you can read an attribute
86 /// in a variable. You can specify the reader for the attribute as
89 /// After you give all read commands you must call the \c run() member
90 /// function, which execute all the commands.
96 /// \see DefaultReaderTraits
97 /// \see QuotedStringReader
98 /// \see \ref GraphWriter
99 /// \see \ref graph-io-page
100 /// \author Balazs Dezso
101 template <typename _Graph, typename _ReaderTraits = DefaultReaderTraits>
105 typedef _Graph Graph;
106 typedef typename Graph::Node Node;
107 typedef typename Graph::Edge Edge;
109 typedef _ReaderTraits ReaderTraits;
110 typedef typename ReaderTraits::Skipper DefaultSkipper;
112 /// \brief Construct a new GraphReader.
114 /// Construct a new GraphReader. It reads into the given graph
115 /// and it use the given reader as the default skipper.
116 GraphReader(std::istream& _is,
117 typename SmartParameter<Graph>::Type _graph,
118 const DefaultSkipper& _skipper = DefaultSkipper())
119 : reader(new LemonReader(_is)), own_reader(true), skipper(_skipper),
120 nodeset_reader(*reader, _graph, std::string(), skipper),
121 edgeset_reader(*reader, _graph, nodeset_reader,
122 std::string(), skipper),
123 node_reader(*reader, nodeset_reader, std::string()),
124 edge_reader(*reader, edgeset_reader, std::string()),
125 attribute_reader(*reader, std::string()) {}
127 /// \brief Construct a new GraphReader.
129 /// Construct a new GraphReader. It reads into the given graph
130 /// and it use the given reader as the default skipper.
131 GraphReader(const std::string& _filename,
132 typename SmartParameter<Graph>::Type _graph,
133 const DefaultSkipper& _skipper = DefaultSkipper())
134 : reader(new LemonReader(_filename)), own_reader(true),
136 nodeset_reader(*reader, _graph, std::string(), skipper),
137 edgeset_reader(*reader, _graph, nodeset_reader,
138 std::string(), skipper),
139 node_reader(*reader, nodeset_reader, std::string()),
140 edge_reader(*reader, edgeset_reader, std::string()),
141 attribute_reader(*reader, std::string()) {}
143 /// \brief Construct a new GraphReader.
145 /// Construct a new GraphReader. It reads into the given graph
146 /// and it use the given reader as the default skipper.
147 GraphReader(LemonReader& _reader,
148 typename SmartParameter<Graph>::Type _graph,
149 const DefaultSkipper& _skipper = DefaultSkipper())
150 : reader(_reader), own_reader(false), skipper(_skipper),
151 nodeset_reader(*reader, _graph, std::string(), skipper),
152 edgeset_reader(*reader, _graph, nodeset_reader,
153 std::string(), skipper),
154 node_reader(*reader, nodeset_reader, std::string()),
155 edge_reader(*reader, edgeset_reader, std::string()),
156 attribute_reader(*reader, std::string()) {}
158 /// \brief Destruct the graph reader.
160 /// Destruct the graph reader.
166 /// \brief Add a new node map reader command for the reader.
168 /// Add a new node map reader command for the reader.
169 template <typename Map>
170 GraphReader& readNodeMap(std::string name, Map& map) {
171 nodeset_reader.readNodeMap(name, map);
175 template <typename Map>
176 GraphReader& readNodeMap(std::string name, const Map& map) {
177 nodeset_reader.readNodeMap(name, map);
181 /// \brief Add a new node map reader command for the reader.
183 /// Add a new node map reader command for the reader.
184 template <typename Reader, typename Map>
185 GraphReader& readNodeMap(std::string name, Map& map,
186 const Reader& reader = Reader()) {
187 nodeset_reader.readNodeMap(name, map, reader);
191 template <typename Reader, typename Map>
192 GraphReader& readNodeMap(std::string name, const Map& map,
193 const Reader& reader = Reader()) {
194 nodeset_reader.readNodeMap(name, map, reader);
198 /// \brief Add a new node map skipper command for the reader.
200 /// Add a new node map skipper command for the reader.
201 template <typename Reader>
202 GraphReader& skipNodeMap(std::string name,
203 const Reader& reader = Reader()) {
204 nodeset_reader.skipNodeMap(name, reader);
208 /// \brief Add a new edge map reader command for the reader.
210 /// Add a new edge map reader command for the reader.
211 template <typename Map>
212 GraphReader& readEdgeMap(std::string name, Map& map) {
213 edgeset_reader.readEdgeMap(name, map);
217 template <typename Map>
218 GraphReader& readEdgeMap(std::string name, const Map& map) {
219 edgeset_reader.readEdgeMap(name, map);
224 /// \brief Add a new edge map reader command for the reader.
226 /// Add a new edge map reader command for the reader.
227 template <typename Reader, typename Map>
228 GraphReader& readEdgeMap(std::string name, Map& map,
229 const Reader& reader = Reader()) {
230 edgeset_reader.readEdgeMap(name, map, reader);
234 template <typename Reader, typename Map>
235 GraphReader& readEdgeMap(std::string name, const Map& map,
236 const Reader& reader = Reader()) {
237 edgeset_reader.readEdgeMap(name, map, reader);
241 /// \brief Add a new edge map skipper command for the reader.
243 /// Add a new edge map skipper command for the reader.
244 template <typename Reader>
245 GraphReader& skipEdgeMap(std::string name,
246 const Reader& reader = Reader()) {
247 edgeset_reader.skipEdgeMap(name, reader);
251 /// \brief Add a new labeled node reader for the reader.
253 /// Add a new labeled node reader for the reader.
254 GraphReader& readNode(std::string name, Node& node) {
255 node_reader.readNode(name, node);
259 /// \brief Add a new labeled edge reader for the reader.
261 /// Add a new labeled edge reader for the reader.
262 GraphReader& readEdge(std::string name, Edge& edge) {
263 edge_reader.readEdge(name, edge);
267 /// \brief Add a new attribute reader command.
269 /// Add a new attribute reader command.
270 template <typename Value>
271 GraphReader& readAttribute(std::string name, Value& value) {
272 attribute_reader.readAttribute(name, value);
276 /// \brief Add a new attribute reader command.
278 /// Add a new attribute reader command.
279 template <typename Reader, typename Value>
280 GraphReader& readAttribute(std::string name, Value& value,
281 const Reader& reader) {
282 attribute_reader.readAttribute<Reader>(name, value, reader);
286 /// \brief Conversion operator to LemonReader.
288 /// Conversion operator to LemonReader. It make possible
289 /// to access the encapsulated \e LemonReader, this way
290 /// you can attach to this reader new instances of
291 /// \e LemonReader::SectionReader.
292 operator LemonReader&() {
296 /// \brief Executes the reader commands.
298 /// Executes the reader commands.
303 /// \brief Gives back the node by its id.
305 /// It reads an id from the stream and gives back which node belongs to
306 /// it. It is possible only if there was read an "id" named node map.
307 Node readId(std::istream& is, Node) const {
308 return nodeset_reader.readId(is, Node());
311 /// \brief Gives back the edge by its id.
313 /// It reads an id from the stream and gives back which edge belongs to
314 /// it. It is possible only if there was read an "id" named edge map.
315 Edge readId(std::istream& is, Edge) const {
316 return edgeset_reader.readId(is, Edge());
324 DefaultSkipper skipper;
326 NodeSetReader<Graph, ReaderTraits> nodeset_reader;
327 EdgeSetReader<Graph, ReaderTraits> edgeset_reader;
329 NodeReader<Graph> node_reader;
330 EdgeReader<Graph> edge_reader;
332 AttributeReader<ReaderTraits> attribute_reader;
335 /// \brief Read a graph from the input.
337 /// Read a graph from the input.
338 /// \param is The input stream.
339 /// \param g The graph.
340 /// \param capacity The capacity map.
341 /// \param s The source node.
342 /// \param t The target node.
343 /// \param cost The cost map.
344 template<typename Graph, typename CapacityMap, typename CostMap>
345 void readGraph(std::istream& is, Graph &g, CapacityMap& capacity,
346 typename Graph::Node &s, typename Graph::Node &t,
348 GraphReader<Graph> reader(is, g);
349 reader.readEdgeMap("capacity", capacity);
350 reader.readEdgeMap("cost", cost);
351 reader.readNode("source", s);
352 reader.readNode("target", t);
356 /// \brief Read a graph from the input.
358 /// Read a graph from the input.
359 /// \param is The input stream.
360 /// \param g The graph.
361 /// \param capacity The capacity map.
362 /// \param s The source node.
363 /// \param t The target node.
364 template<typename Graph, typename CapacityMap>
365 void readGraph(std::istream& is, Graph &g, CapacityMap& capacity,
366 typename Graph::Node &s, typename Graph::Node &t) {
367 GraphReader<Graph> reader(is, g);
368 reader.readEdgeMap("capacity", capacity);
369 reader.readNode("source", s);
370 reader.readNode("target", t);
374 /// \brief Read a graph from the input.
376 /// Read a graph from the input.
377 /// \param is The input stream.
378 /// \param g The graph.
379 /// \param capacity The capacity map.
380 /// \param s The source node.
381 template<typename Graph, typename CapacityMap>
382 void readGraph(std::istream& is, Graph &g, CapacityMap& capacity,
383 typename Graph::Node &s) {
384 GraphReader<Graph> reader(is, g);
385 reader.readEdgeMap("capacity", capacity);
386 reader.readNode("source", s);
390 /// \brief Read a graph from the input.
392 /// Read a graph from the input.
393 /// \param is The input stream.
394 /// \param g The graph.
395 /// \param capacity The capacity map.
396 template<typename Graph, typename CapacityMap>
397 void readGraph(std::istream& is, Graph &g, CapacityMap& capacity) {
398 GraphReader<Graph> reader(is, g);
399 reader.readEdgeMap("capacity", capacity);
403 /// \brief Read a graph from the input.
405 /// Read a graph from the input.
406 /// \param is The input stream.
407 /// \param g The graph.
408 template<typename Graph>
409 void readGraph(std::istream& is, Graph &g) {
410 GraphReader<Graph> reader(is, g);
414 /// \brief The undir graph reader class.
416 /// The given file format may contain several maps and labeled nodes or
419 /// If you read a graph you need not read all the maps and items just those
420 /// that you need. The interface of the \c GraphReader is very similar to
421 /// the GraphWriter but the reading method does not depend on the order the
424 /// The reader object suppose that each not readed value does not contain
425 /// whitespaces, therefore it has some extra possibilities to control how
426 /// it should skip the values when the string representation contains spaces.
429 /// UndirGraphReader<UndirListGraph> reader(std::cin, graph);
432 /// The \c readNodeMap() function reads a map from the \c \@nodeset section.
433 /// If there is a map that you do not want to read from the file and there is
434 /// whitespace in the string represenation of the values then you should
435 /// call the \c skipNodeMap() template member function with proper
439 /// reader.readNodeMap("coords", coords);
441 /// reader.readNodeMap<QuotedStringReader>("label", labelMap);
442 /// reader.skipNodeMap<QuotedStringReader>("description");
444 /// reader.readNodeMap("color", colorMap);
447 /// With the \c readUndirEdgeMap() member function you can give an
448 /// undir edge map reading command similar to the NodeMaps.
451 /// reader.readUndirEdgeMap("capacity", capacityMap);
454 /// The reading of the directed edge maps is just a syntactical sugar.
455 /// It reads two undirected edgemaps into a directed edge map. The
456 /// undirected edge maps' name should be start with the \c '+' and the
457 /// \c '-' character and the same.
460 /// reader.readEdgeMap("flow", flowMap);
463 /// With \c readNode() and \c readUndirEdge() functions you can read
464 /// labeled Nodes and UndirEdges.
467 /// reader.readNode("source", sourceNode);
468 /// reader.readNode("target", targetNode);
470 /// reader.readUndirEdge("observed", undirEdge);
473 /// With the \c readAttribute() functions you can read an attribute
474 /// in a variable. You can specify the reader for the attribute as
477 /// After you give all read commands you must call the \c run() member
478 /// function, which execute all the commands.
485 /// \see DefaultReaderTraits
486 /// \see \ref UndirGraphWriter
487 /// \see \ref graph-io-page
489 /// \author Balazs Dezso
490 template <typename _Graph, typename _ReaderTraits = DefaultReaderTraits>
491 class UndirGraphReader {
494 typedef _Graph Graph;
495 typedef typename Graph::Node Node;
496 typedef typename Graph::Edge Edge;
497 typedef typename Graph::UndirEdge UndirEdge;
499 typedef _ReaderTraits ReaderTraits;
500 typedef typename ReaderTraits::Skipper DefaultSkipper;
502 /// \brief Construct a new UndirGraphReader.
504 /// Construct a new UndirGraphReader. It reads into the given graph
505 /// and it use the given reader as the default skipper.
506 UndirGraphReader(std::istream& _is, Graph& _graph,
507 const DefaultSkipper& _skipper = DefaultSkipper())
508 : reader(new LemonReader(_is)), own_reader(true), skipper(_skipper),
509 nodeset_reader(*reader, _graph, std::string(), skipper),
510 undir_edgeset_reader(*reader, _graph, nodeset_reader,
511 std::string(), skipper),
512 node_reader(*reader, nodeset_reader, std::string()),
513 undir_edge_reader(*reader, undir_edgeset_reader, std::string()),
514 attribute_reader(*reader, std::string()) {}
516 /// \brief Construct a new UndirGraphReader.
518 /// Construct a new UndirGraphReader. It reads into the given graph
519 /// and it use the given reader as the default skipper.
520 UndirGraphReader(const std::string& _filename, Graph& _graph,
521 const DefaultSkipper& _skipper = DefaultSkipper())
522 : reader(new LemonReader(_filename)), own_reader(true),
524 nodeset_reader(*reader, _graph, std::string(), skipper),
525 undir_edgeset_reader(*reader, _graph, nodeset_reader,
526 std::string(), skipper),
527 node_reader(*reader, nodeset_reader, std::string()),
528 undir_edge_reader(*reader, undir_edgeset_reader, std::string()),
529 attribute_reader(*reader, std::string()) {}
531 /// \brief Construct a new UndirGraphReader.
533 /// Construct a new UndirGraphReader. It reads into the given graph
534 /// and it use the given reader as the default skipper.
535 UndirGraphReader(LemonReader& _reader, Graph& _graph,
536 const DefaultSkipper& _skipper = DefaultSkipper())
537 : reader(_reader), own_reader(false), skipper(_skipper),
538 nodeset_reader(*reader, _graph, std::string(), skipper),
539 undir_edgeset_reader(*reader, _graph, nodeset_reader,
540 std::string(), skipper),
541 node_reader(*reader, nodeset_reader, std::string()),
542 undir_edge_reader(*reader, undir_edgeset_reader, std::string()),
543 attribute_reader(*reader, std::string()) {}
545 /// \brief Destruct the graph reader.
547 /// Destruct the graph reader.
548 ~UndirGraphReader() {
553 /// \brief Add a new node map reader command for the reader.
555 /// Add a new node map reader command for the reader.
556 template <typename Map>
557 UndirGraphReader& readNodeMap(std::string name, Map& map) {
558 nodeset_reader.readNodeMap(name, map);
562 template <typename Map>
563 UndirGraphReader& readNodeMap(std::string name, const Map& map) {
564 nodeset_reader.readNodeMap(name, map);
568 /// \brief Add a new node map reader command for the reader.
570 /// Add a new node map reader command for the reader.
571 template <typename Reader, typename Map>
572 UndirGraphReader& readNodeMap(std::string name, Map& map,
573 const Reader& reader = Reader()) {
574 nodeset_reader.readNodeMap(name, map, reader);
578 template <typename Reader, typename Map>
579 UndirGraphReader& readNodeMap(std::string name, const Map& map,
580 const Reader& reader = Reader()) {
581 nodeset_reader.readNodeMap(name, map, reader);
585 /// \brief Add a new node map skipper command for the reader.
587 /// Add a new node map skipper command for the reader.
588 template <typename Reader>
589 UndirGraphReader& skipNodeMap(std::string name,
590 const Reader& reader = Reader()) {
591 nodeset_reader.skipNodeMap(name, reader);
595 /// \brief Add a new undirected edge map reader command for the reader.
597 /// Add a new undirected edge map reader command for the reader.
598 template <typename Map>
599 UndirGraphReader& readUndirEdgeMap(std::string name, Map& map) {
600 undir_edgeset_reader.readUndirEdgeMap(name, map);
604 template <typename Map>
605 UndirGraphReader& readUndirEdgeMap(std::string name, const Map& map) {
606 undir_edgeset_reader.readUndirEdgeMap(name, map);
611 /// \brief Add a new undirected edge map reader command for the reader.
613 /// Add a new undirected edge map reader command for the reader.
614 template <typename Reader, typename Map>
615 UndirGraphReader& readUndirEdgeMap(std::string name, Map& map,
616 const Reader& reader = Reader()) {
617 undir_edgeset_reader.readUndirEdgeMap(name, map, reader);
621 template <typename Reader, typename Map>
622 UndirGraphReader& readUndirEdgeMap(std::string name, const Map& map,
623 const Reader& reader = Reader()) {
624 undir_edgeset_reader.readUndirEdgeMap(name, map, reader);
628 /// \brief Add a new undirected edge map skipper command for the reader.
630 /// Add a new undirected edge map skipper command for the reader.
631 template <typename Reader>
632 UndirGraphReader& skipUndirEdgeMap(std::string name,
633 const Reader& reader = Reader()) {
634 undir_edgeset_reader.skipUndirMap(name, reader);
639 /// \brief Add a new edge map reader command for the reader.
641 /// Add a new edge map reader command for the reader.
642 template <typename Map>
643 UndirGraphReader& readEdgeMap(std::string name, Map& map) {
644 undir_edgeset_reader.readEdgeMap(name, map);
648 template <typename Map>
649 UndirGraphReader& readEdgeMap(std::string name, const Map& map) {
650 undir_edgeset_reader.readEdgeMap(name, map);
655 /// \brief Add a new edge map reader command for the reader.
657 /// Add a new edge map reader command for the reader.
658 template <typename Reader, typename Map>
659 UndirGraphReader& readEdgeMap(std::string name, Map& map,
660 const Reader& reader = Reader()) {
661 undir_edgeset_reader.readEdgeMap(name, map, reader);
665 template <typename Reader, typename Map>
666 UndirGraphReader& readEdgeMap(std::string name, const Map& map,
667 const Reader& reader = Reader()) {
668 undir_edgeset_reader.readEdgeMap(name, map, reader);
672 /// \brief Add a new edge map skipper command for the reader.
674 /// Add a new edge map skipper command for the reader.
675 template <typename Reader>
676 UndirGraphReader& skipEdgeMap(std::string name,
677 const Reader& reader = Reader()) {
678 undir_edgeset_reader.skipEdgeMap(name, reader);
682 /// \brief Add a new labeled node reader for the reader.
684 /// Add a new labeled node reader for the reader.
685 UndirGraphReader& readNode(std::string name, Node& node) {
686 node_reader.readNode(name, node);
690 /// \brief Add a new labeled edge reader for the reader.
692 /// Add a new labeled edge reader for the reader.
693 UndirGraphReader& readEdge(std::string name, Edge& edge) {
694 undir_edge_reader.readEdge(name, edge);
697 /// \brief Add a new labeled undirected edge reader for the reader.
699 /// Add a new labeled undirected edge reader for the reader.
700 UndirGraphReader& readUndirEdge(std::string name, UndirEdge& edge) {
701 undir_edge_reader.readUndirEdge(name, edge);
704 /// \brief Add a new attribute reader command.
706 /// Add a new attribute reader command.
707 template <typename Value>
708 UndirGraphReader& readAttribute(std::string name, Value& value) {
709 attribute_reader.readAttribute(name, value);
713 /// \brief Add a new attribute reader command.
715 /// Add a new attribute reader command.
716 template <typename Reader, typename Value>
717 UndirGraphReader& readAttribute(std::string name, Value& value,
718 const Reader& reader) {
719 attribute_reader.readAttribute<Reader>(name, value, reader);
723 /// \brief Conversion operator to LemonReader.
725 /// Conversion operator to LemonReader. It make possible
726 /// to access the encapsulated \e LemonReader, this way
727 /// you can attach to this reader new instances of
728 /// \e LemonReader::SectionReader.
729 operator LemonReader&() {
733 /// \brief Executes the reader commands.
735 /// Executes the reader commands.
740 /// \brief Gives back the node by its id.
742 /// It reads an id from the stream and gives back which node belongs to
743 /// it. It is possible only if there was read an "id" named node map.
744 Node readId(std::istream& is, Node) const {
745 return nodeset_reader.readId(is, Node());
748 /// \brief Gives back the edge by its id.
750 /// It reads an id from the stream and gives back which edge belongs to
751 /// it. It is possible only if there was read an "id" named edge map.
752 Edge readId(std::istream& is, Edge) const {
753 return undir_edgeset_reader.readId(is, Edge());
756 /// \brief Gives back the undirected edge by its id.
758 /// It reads an id from the stream and gives back which undirected edge
759 /// belongs to it. It is possible only if there was read an "id" named
761 UndirEdge readId(std::istream& is, UndirEdge) const {
762 return undir_edgeset_reader.readId(is, UndirEdge());
771 DefaultSkipper skipper;
773 NodeSetReader<Graph, ReaderTraits> nodeset_reader;
774 UndirEdgeSetReader<Graph, ReaderTraits> undir_edgeset_reader;
776 NodeReader<Graph> node_reader;
777 UndirEdgeReader<Graph> undir_edge_reader;
779 AttributeReader<ReaderTraits> attribute_reader;
782 /// \brief Read an undir graph from the input.
784 /// Read an undir graph from the input.
785 /// \param is The input stream.
786 /// \param g The graph.
787 /// \param capacity The capacity map.
788 template<typename Graph, typename CapacityMap>
789 void readUndirGraph(std::istream& is, Graph &g, CapacityMap& capacity) {
790 UndirGraphReader<Graph> reader(is, g);
791 reader.readUndirEdgeMap("capacity", capacity);
795 /// \brief Read an undir graph from the input.
797 /// Read an undir graph from the input.
798 /// \param is The input stream.
799 /// \param g The graph.
800 template<typename Graph>
801 void readUndirGraph(std::istream& is, Graph &g) {
802 UndirGraphReader<Graph> reader(is, g);