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 \c GraphReader class provides the graph input.
37 /// Before you read this documentation it might be useful to read the general
38 /// 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 readGraph() to read a graph (or a max flow instance etc).
44 /// The file to be read may contain several maps and labeled nodes or
47 /// If you read a graph you need not read all the maps and items just those
48 /// that you need. The interface of the \c GraphReader is very similar to
49 /// the GraphWriter but the reading method does not depend on the order the
50 /// given commands (i.e. you don't have to insist on the order in which the
51 /// maps are given in the file).
53 /// The reader object assumes that not readed values do not contain
54 /// whitespaces, therefore it has some extra possibilities to control how
55 /// it should skip the values when the string representation contains spaces.
58 /// GraphReader<ListGraph> reader(std::cin, graph);
61 /// The \c readNodeMap() function reads a map from the \c \@nodeset section.
62 /// If there is a map that you do not want to read from the file and there is
63 /// whitespace in the string represenation of the values then you should
64 /// call the \c skipNodeMap() template member function with proper
68 /// reader.readNodeMap("coords", coords);
70 /// reader.readNodeMap<QuotedStringReader>("label", labelMap);
71 /// reader.skipNodeMap<QuotedStringReader>("description");
73 /// reader.readNodeMap("color", colorMap);
76 /// With the \c readEdgeMap() member function you can give an edge map
77 /// reading command similar to the NodeMaps.
80 /// reader.readEdgeMap("weight", weightMap);
81 /// reader.readEdgeMap("label", labelMap);
84 /// With \c readNode() and \c readEdge() functions you can read
85 /// labeled Nodes and Edges.
88 /// reader.readNode("source", sourceNode);
89 /// reader.readNode("target", targetNode);
91 /// reader.readEdge("observed", edge);
94 /// With the \c readAttribute() functions you can read an attribute
95 /// into a variable. You can specify the reader for the attribute as
98 /// After you give all read commands you must call the \c run() member
99 /// function, which executes all the commands.
105 /// \see DefaultReaderTraits
106 /// \see QuotedStringReader
107 /// \see \ref GraphWriter
108 /// \see \ref graph-io-page
109 /// \author Balazs Dezso
110 template <typename _Graph, typename _ReaderTraits = DefaultReaderTraits>
114 typedef _Graph Graph;
115 typedef typename Graph::Node Node;
116 typedef typename Graph::Edge Edge;
118 typedef _ReaderTraits ReaderTraits;
119 typedef typename ReaderTraits::Skipper DefaultSkipper;
121 /// \brief Construct a new GraphReader.
123 /// Construct a new GraphReader. It reads into the given graph
124 /// and it uses the given reader as the default skipper.
125 GraphReader(std::istream& _is, Graph& _graph,
126 const DefaultSkipper& _skipper = DefaultSkipper())
127 : reader(new LemonReader(_is)), own_reader(true), skipper(_skipper),
128 nodeset_reader(*reader, _graph, std::string(), skipper),
129 edgeset_reader(*reader, _graph, nodeset_reader,
130 std::string(), skipper),
131 node_reader(*reader, nodeset_reader, std::string()),
132 edge_reader(*reader, edgeset_reader, std::string()),
133 attribute_reader(*reader, std::string()) {}
135 /// \brief Construct a new GraphReader.
137 /// Construct a new GraphReader. It reads into the given graph
138 /// and it uses the given reader as the default skipper.
139 GraphReader(const std::string& _filename, Graph& _graph,
140 const DefaultSkipper& _skipper = DefaultSkipper())
141 : reader(new LemonReader(_filename)), own_reader(true),
143 nodeset_reader(*reader, _graph, std::string(), skipper),
144 edgeset_reader(*reader, _graph, nodeset_reader,
145 std::string(), skipper),
146 node_reader(*reader, nodeset_reader, std::string()),
147 edge_reader(*reader, edgeset_reader, std::string()),
148 attribute_reader(*reader, std::string()) {}
150 /// \brief Construct a new GraphReader.
152 /// Construct a new GraphReader. It reads into the given graph
153 /// and it uses the given reader as the default skipper.
154 GraphReader(LemonReader& _reader, Graph& _graph,
155 const DefaultSkipper& _skipper = DefaultSkipper())
156 : reader(_reader), own_reader(false), skipper(_skipper),
157 nodeset_reader(*reader, _graph, std::string(), skipper),
158 edgeset_reader(*reader, _graph, nodeset_reader,
159 std::string(), skipper),
160 node_reader(*reader, nodeset_reader, std::string()),
161 edge_reader(*reader, edgeset_reader, std::string()),
162 attribute_reader(*reader, std::string()) {}
164 /// \brief Destruct the graph reader.
166 /// Destruct the graph reader.
172 /// \brief Give a new node map reading command to the reader.
174 /// Give a new node map reading command to the reader.
175 template <typename Map>
176 GraphReader& readNodeMap(std::string name, Map& map) {
177 nodeset_reader.readNodeMap(name, map);
181 template <typename Map>
182 GraphReader& readNodeMap(std::string name, const Map& map) {
183 nodeset_reader.readNodeMap(name, map);
187 /// \brief Give a new node map reading command to the reader.
189 /// Give a new node map reading command to the reader.
190 template <typename Reader, typename Map>
191 GraphReader& readNodeMap(std::string name, Map& map,
192 const Reader& reader = Reader()) {
193 nodeset_reader.readNodeMap(name, map, reader);
197 template <typename Reader, typename Map>
198 GraphReader& readNodeMap(std::string name, const Map& map,
199 const Reader& reader = Reader()) {
200 nodeset_reader.readNodeMap(name, map, reader);
204 /// \brief Give a new node map skipping command to the reader.
206 /// Give a new node map skipping command to the reader.
207 template <typename Reader>
208 GraphReader& skipNodeMap(std::string name,
209 const Reader& reader = Reader()) {
210 nodeset_reader.skipNodeMap(name, reader);
214 /// \brief Give a new edge map reading command to the reader.
216 /// Give a new edge map reading command to the reader.
217 template <typename Map>
218 GraphReader& readEdgeMap(std::string name, Map& map) {
219 edgeset_reader.readEdgeMap(name, map);
223 template <typename Map>
224 GraphReader& readEdgeMap(std::string name, const Map& map) {
225 edgeset_reader.readEdgeMap(name, map);
230 /// \brief Give a new edge map reading command to the reader.
232 /// Give a new edge map reading command to the reader.
233 template <typename Reader, typename Map>
234 GraphReader& readEdgeMap(std::string name, Map& map,
235 const Reader& reader = Reader()) {
236 edgeset_reader.readEdgeMap(name, map, reader);
240 template <typename Reader, typename Map>
241 GraphReader& readEdgeMap(std::string name, const Map& map,
242 const Reader& reader = Reader()) {
243 edgeset_reader.readEdgeMap(name, map, reader);
247 /// \brief Give a new edge map skipping command to the reader.
249 /// Give a new edge map skipping command to the reader.
250 template <typename Reader>
251 GraphReader& skipEdgeMap(std::string name,
252 const Reader& reader = Reader()) {
253 edgeset_reader.skipEdgeMap(name, reader);
257 /// \brief Give a new labeled node reading command to the reader.
259 /// Give a new labeled node reading command to the reader.
260 GraphReader& readNode(std::string name, Node& node) {
261 node_reader.readNode(name, node);
265 /// \brief Give a new labeled edge reading command to the reader.
267 /// Give a new labeled edge reading command to the reader.
268 GraphReader& readEdge(std::string name, Edge& edge) {
269 edge_reader.readEdge(name, edge);
273 /// \brief Give a new attribute reading command.
275 /// Give a new attribute reading command.
276 template <typename Value>
277 GraphReader& readAttribute(std::string name, Value& value) {
278 attribute_reader.readAttribute(name, value);
282 /// \brief Give a new attribute reading command.
284 /// Give a new attribute reading command.
285 template <typename Reader, typename Value>
286 GraphReader& readAttribute(std::string name, Value& value,
287 const Reader& reader) {
288 attribute_reader.readAttribute<Reader>(name, value, reader);
292 /// \brief Conversion operator to LemonReader.
294 /// Conversion operator to LemonReader. It makes possible to access the
295 /// encapsulated \e LemonReader, this way you can attach to this reader
296 /// new instances of \e LemonReader::SectionReader. For more details see
297 /// the \ref rwbackground "Background of Reading and Writing".
298 operator LemonReader&() {
302 /// \brief Executes the reading commands.
304 /// Executes the reading commands.
309 /// \brief Gives back the node by its id.
311 /// It reads an id from the stream and gives back which node belongs to
312 /// it. It is possible only if there was read an "id" named node map.
313 Node readId(std::istream& is, Node) const {
314 return nodeset_reader.readId(is, Node());
317 /// \brief Gives back the edge by its id.
319 /// It reads an id from the stream and gives back which edge belongs to
320 /// it. It is possible only if there was read an "id" named edge map.
321 Edge readId(std::istream& is, Edge) const {
322 return edgeset_reader.readId(is, Edge());
330 DefaultSkipper skipper;
332 NodeSetReader<Graph, ReaderTraits> nodeset_reader;
333 EdgeSetReader<Graph, ReaderTraits> edgeset_reader;
335 NodeReader<Graph> node_reader;
336 EdgeReader<Graph> edge_reader;
338 AttributeReader<ReaderTraits> attribute_reader;
342 /// \brief Read a graph from the input.
344 /// It is a helper function to read a graph from the given input
345 /// stream. It gives back an GraphReader object and this object
346 /// can read more maps, labeled nodes, edges and attributes.
348 /// \warning Do not forget to call the \c run() function.
350 /// \param is The input stream.
351 /// \param g The graph.
352 template<typename Graph>
353 GraphReader<Graph> graphReader(std::istream& is, Graph &g) {
354 return GraphReader<Graph>(is, g);
357 /// \brief Read a graph from the input.
359 /// It is a helper function to read a graph from the given input
360 /// file. It gives back an GraphReader object and this object
361 /// can read more maps, labeled nodes, edges and attributes.
363 /// \warning Do not forget to call the \c run() function.
365 /// \param fn The input filename.
366 /// \param g The graph.
367 template<typename Graph>
368 GraphReader<Graph> graphReader(const std::string& fn, Graph &g) {
369 return GraphReader<Graph>(fn, g);
372 /// \brief The undirected graph reader class.
374 /// The \c UndirGraphReader class provides the graph input.
375 /// Before you read this documentation it might be useful to read the general
376 /// description of \ref graph-io-page "Graph Input-Output".
378 /// If you don't need very sophisticated
379 /// behaviour then you can use the versions of the public function
380 /// \ref readGraph() to read a graph (or a max flow instance etc).
382 /// The given file format may contain several maps and labeled nodes or
385 /// If you read a graph you need not read all the maps and items just those
386 /// that you need. The interface of the \c UndirGraphReader is very similar
387 /// to the UndirGraphWriter but the reading method does not depend on the
388 /// order of the given commands.
390 /// The reader object suppose that each not readed value does not contain
391 /// whitespaces, therefore it has some extra possibilities to control how
392 /// it should skip the values when the string representation contains spaces.
395 /// UndirGraphReader<UndirListGraph> reader(std::cin, graph);
398 /// The \c readNodeMap() function reads a map from the \c \@nodeset section.
399 /// If there is a map that you do not want to read from the file and there is
400 /// whitespace in the string represenation of the values then you should
401 /// call the \c skipNodeMap() template member function with proper
405 /// reader.readNodeMap("coords", coords);
407 /// reader.readNodeMap<QuotedStringReader>("label", labelMap);
408 /// reader.skipNodeMap<QuotedStringReader>("description");
410 /// reader.readNodeMap("color", colorMap);
413 /// With the \c readUndirEdgeMap() member function you can give an
414 /// undir edge map reading command similar to the NodeMaps.
417 /// reader.readUndirEdgeMap("capacity", capacityMap);
420 /// The reading of the directed edge maps is just a syntactical sugar.
421 /// It reads two undirected edgemaps into a directed edge map. The
422 /// undirected edge maps' name should be start with the \c '+' and the
423 /// \c '-' character and the same.
426 /// reader.readEdgeMap("flow", flowMap);
429 /// With \c readNode() and \c readUndirEdge() functions you can read
430 /// labeled Nodes and UndirEdges.
433 /// reader.readNode("source", sourceNode);
434 /// reader.readNode("target", targetNode);
436 /// reader.readUndirEdge("observed", undirEdge);
439 /// With the \c readAttribute() functions you can read an attribute
440 /// in a variable. You can specify the reader for the attribute as
443 /// After you give all read commands you must call the \c run() member
444 /// function, which execute all the commands.
451 /// \see DefaultReaderTraits
452 /// \see \ref UndirGraphWriter
453 /// \see \ref graph-io-page
455 /// \author Balazs Dezso
456 template <typename _Graph, typename _ReaderTraits = DefaultReaderTraits>
457 class UndirGraphReader {
460 typedef _Graph Graph;
461 typedef typename Graph::Node Node;
462 typedef typename Graph::Edge Edge;
463 typedef typename Graph::UndirEdge UndirEdge;
465 typedef _ReaderTraits ReaderTraits;
466 typedef typename ReaderTraits::Skipper DefaultSkipper;
468 /// \brief Construct a new UndirGraphReader.
470 /// Construct a new UndirGraphReader. It reads into the given graph
471 /// and it use the given reader as the default skipper.
472 UndirGraphReader(std::istream& _is, Graph& _graph,
473 const DefaultSkipper& _skipper = DefaultSkipper())
474 : reader(new LemonReader(_is)), own_reader(true), skipper(_skipper),
475 nodeset_reader(*reader, _graph, std::string(), skipper),
476 undir_edgeset_reader(*reader, _graph, nodeset_reader,
477 std::string(), skipper),
478 node_reader(*reader, nodeset_reader, std::string()),
479 undir_edge_reader(*reader, undir_edgeset_reader, std::string()),
480 attribute_reader(*reader, std::string()) {}
482 /// \brief Construct a new UndirGraphReader.
484 /// Construct a new UndirGraphReader. It reads into the given graph
485 /// and it use the given reader as the default skipper.
486 UndirGraphReader(const std::string& _filename, Graph& _graph,
487 const DefaultSkipper& _skipper = DefaultSkipper())
488 : reader(new LemonReader(_filename)), own_reader(true),
490 nodeset_reader(*reader, _graph, std::string(), skipper),
491 undir_edgeset_reader(*reader, _graph, nodeset_reader,
492 std::string(), skipper),
493 node_reader(*reader, nodeset_reader, std::string()),
494 undir_edge_reader(*reader, undir_edgeset_reader, std::string()),
495 attribute_reader(*reader, std::string()) {}
497 /// \brief Construct a new UndirGraphReader.
499 /// Construct a new UndirGraphReader. It reads into the given graph
500 /// and it use the given reader as the default skipper.
501 UndirGraphReader(LemonReader& _reader, Graph& _graph,
502 const DefaultSkipper& _skipper = DefaultSkipper())
503 : reader(_reader), own_reader(false), skipper(_skipper),
504 nodeset_reader(*reader, _graph, std::string(), skipper),
505 undir_edgeset_reader(*reader, _graph, nodeset_reader,
506 std::string(), skipper),
507 node_reader(*reader, nodeset_reader, std::string()),
508 undir_edge_reader(*reader, undir_edgeset_reader, std::string()),
509 attribute_reader(*reader, std::string()) {}
511 /// \brief Destruct the graph reader.
513 /// Destruct the graph reader.
514 ~UndirGraphReader() {
519 /// \brief Give a new node map reading command to the reader.
521 /// Give a new node map reading command to the reader.
522 template <typename Map>
523 UndirGraphReader& readNodeMap(std::string name, Map& map) {
524 nodeset_reader.readNodeMap(name, map);
528 template <typename Map>
529 UndirGraphReader& readNodeMap(std::string name, const Map& map) {
530 nodeset_reader.readNodeMap(name, map);
534 /// \brief Give a new node map reading command to the reader.
536 /// Give a new node map reading command to the reader.
537 template <typename Reader, typename Map>
538 UndirGraphReader& readNodeMap(std::string name, Map& map,
539 const Reader& reader = Reader()) {
540 nodeset_reader.readNodeMap(name, map, reader);
544 template <typename Reader, typename Map>
545 UndirGraphReader& readNodeMap(std::string name, const Map& map,
546 const Reader& reader = Reader()) {
547 nodeset_reader.readNodeMap(name, map, reader);
551 /// \brief Give a new node map skipping command to the reader.
553 /// Give a new node map skipping command to the reader.
554 template <typename Reader>
555 UndirGraphReader& skipNodeMap(std::string name,
556 const Reader& reader = Reader()) {
557 nodeset_reader.skipNodeMap(name, reader);
561 /// \brief Give a new undirected edge map reading command to the reader.
563 /// Give a new undirected edge map reading command to the reader.
564 template <typename Map>
565 UndirGraphReader& readUndirEdgeMap(std::string name, Map& map) {
566 undir_edgeset_reader.readUndirEdgeMap(name, map);
570 template <typename Map>
571 UndirGraphReader& readUndirEdgeMap(std::string name, const Map& map) {
572 undir_edgeset_reader.readUndirEdgeMap(name, map);
577 /// \brief Give a new undirected edge map reading command to the reader.
579 /// Give a new undirected edge map reading command to the reader.
580 template <typename Reader, typename Map>
581 UndirGraphReader& readUndirEdgeMap(std::string name, Map& map,
582 const Reader& reader = Reader()) {
583 undir_edgeset_reader.readUndirEdgeMap(name, map, reader);
587 template <typename Reader, typename Map>
588 UndirGraphReader& readUndirEdgeMap(std::string name, const Map& map,
589 const Reader& reader = Reader()) {
590 undir_edgeset_reader.readUndirEdgeMap(name, map, reader);
594 /// \brief Give a new undirected edge map skipping command to the reader.
596 /// Give a new undirected edge map skipping command to the reader.
597 template <typename Reader>
598 UndirGraphReader& skipUndirEdgeMap(std::string name,
599 const Reader& reader = Reader()) {
600 undir_edgeset_reader.skipUndirMap(name, reader);
605 /// \brief Give a new edge map reading command to the reader.
607 /// Give a new edge map reading command to the reader.
608 template <typename Map>
609 UndirGraphReader& readEdgeMap(std::string name, Map& map) {
610 undir_edgeset_reader.readEdgeMap(name, map);
614 template <typename Map>
615 UndirGraphReader& readEdgeMap(std::string name, const Map& map) {
616 undir_edgeset_reader.readEdgeMap(name, map);
621 /// \brief Give a new edge map reading command to the reader.
623 /// Give a new edge map reading command to the reader.
624 template <typename Reader, typename Map>
625 UndirGraphReader& readEdgeMap(std::string name, Map& map,
626 const Reader& reader = Reader()) {
627 undir_edgeset_reader.readEdgeMap(name, map, reader);
631 template <typename Reader, typename Map>
632 UndirGraphReader& readEdgeMap(std::string name, const Map& map,
633 const Reader& reader = Reader()) {
634 undir_edgeset_reader.readEdgeMap(name, map, reader);
638 /// \brief Give a new edge map skipping command to the reader.
640 /// Give a new edge map skipping command to the reader.
641 template <typename Reader>
642 UndirGraphReader& skipEdgeMap(std::string name,
643 const Reader& reader = Reader()) {
644 undir_edgeset_reader.skipEdgeMap(name, reader);
648 /// \brief Give a new labeled node reading command to the reader.
650 /// Give a new labeled node reading command to the reader.
651 UndirGraphReader& readNode(std::string name, Node& node) {
652 node_reader.readNode(name, node);
656 /// \brief Give a new labeled edge reading command to the reader.
658 /// Give a new labeled edge reading command to the reader.
659 UndirGraphReader& readEdge(std::string name, Edge& edge) {
660 undir_edge_reader.readEdge(name, edge);
663 /// \brief Give a new labeled undirected edge reading command to the
666 /// Give a new labeled undirected edge reading command to the reader.
667 UndirGraphReader& readUndirEdge(std::string name, UndirEdge& edge) {
668 undir_edge_reader.readUndirEdge(name, edge);
671 /// \brief Give a new attribute reading command.
673 /// Give a new attribute reading command.
674 template <typename Value>
675 UndirGraphReader& readAttribute(std::string name, Value& value) {
676 attribute_reader.readAttribute(name, value);
680 /// \brief Give a new attribute reading command.
682 /// Give a new attribute reading command.
683 template <typename Reader, typename Value>
684 UndirGraphReader& readAttribute(std::string name, Value& value,
685 const Reader& reader) {
686 attribute_reader.readAttribute<Reader>(name, value, reader);
690 /// \brief Conversion operator to LemonReader.
692 /// Conversion operator to LemonReader. It make possible
693 /// to access the encapsulated \e LemonReader, this way
694 /// you can attach to this reader new instances of
695 /// \e LemonReader::SectionReader.
696 operator LemonReader&() {
700 /// \brief Executes the reading commands.
702 /// Executes the reading commands.
707 /// \brief Gives back the node by its id.
709 /// It reads an id from the stream and gives back which node belongs to
710 /// it. It is possible only if there was read an "id" named node map.
711 Node readId(std::istream& is, Node) const {
712 return nodeset_reader.readId(is, Node());
715 /// \brief Gives back the edge by its id.
717 /// It reads an id from the stream and gives back which edge belongs to
718 /// it. It is possible only if there was read an "id" named edge map.
719 Edge readId(std::istream& is, Edge) const {
720 return undir_edgeset_reader.readId(is, Edge());
723 /// \brief Gives back the undirected edge by its id.
725 /// It reads an id from the stream and gives back which undirected edge
726 /// belongs to it. It is possible only if there was read an "id" named
728 UndirEdge readId(std::istream& is, UndirEdge) const {
729 return undir_edgeset_reader.readId(is, UndirEdge());
738 DefaultSkipper skipper;
740 NodeSetReader<Graph, ReaderTraits> nodeset_reader;
741 UndirEdgeSetReader<Graph, ReaderTraits> undir_edgeset_reader;
743 NodeReader<Graph> node_reader;
744 UndirEdgeReader<Graph> undir_edge_reader;
746 AttributeReader<ReaderTraits> attribute_reader;
749 /// \brief Read an undirected graph from the input.
751 /// It is a helper function to read an undirected graph from the given input
752 /// stream. It gives back an UndirGraphReader object and this object
753 /// can read more maps, labeled nodes, edges, undirected edges and
756 /// \warning Do not forget to call the \c run() function.
758 /// \param is The input stream.
759 /// \param g The graph.
760 template<typename Graph>
761 UndirGraphReader<Graph> undirGraphReader(std::istream& is, Graph &g) {
762 return GraphReader<Graph>(is, g);
765 /// \brief Read an undirected graph from the input.
767 /// It is a helper function to read an undirected graph from the given input
768 /// file. It gives back an UndirGraphReader object and this object
769 /// can read more maps, labeled nodes, edges, undirected edges and
772 /// \warning Do not forget to call the \c run() function.
774 /// \param fn The input filename.
775 /// \param g The graph.
776 template<typename Graph>
777 UndirGraphReader<Graph> undirGraphReader(const std::string& fn, Graph &g) {
778 return GraphReader<Graph>(fn, g);