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);
266 /// \brief Add a new attribute reader command.
268 /// Add a new attribute reader command.
269 template <typename Value>
270 GraphReader& readAttribute(std::string name, Value& value) {
271 attribute_reader.readAttribute(name, value);
275 /// \brief Add a new attribute reader command.
277 /// Add a new attribute reader command.
278 template <typename Reader, typename Value>
279 GraphReader& readAttribute(std::string name, Value& value,
280 const Reader& reader) {
281 attribute_reader.readAttribute<Reader>(name, value, reader);
285 /// \brief Conversion operator to LemonReader.
287 /// Conversion operator to LemonReader. It make possible
288 /// to access the encapsulated \e LemonReader, this way
289 /// you can attach to this reader new instances of
290 /// \e LemonReader::SectionReader.
291 operator LemonReader&() {
295 /// \brief Executes the reader commands.
297 /// Executes the reader commands.
302 /// \brief Gives back the node by its id.
304 /// It reads an id from the stream and gives back which node belongs to
305 /// it. It is possible only if there was read an "id" named node map.
306 Node readId(std::istream& is, Node) const {
307 return nodeset_reader.readId(is, Node());
310 /// \brief Gives back the edge by its id.
312 /// It reads an id from the stream and gives back which edge belongs to
313 /// it. It is possible only if there was read an "id" named edge map.
314 Edge readId(std::istream& is, Edge) const {
315 return edgeset_reader.readId(is, Edge());
323 DefaultSkipper skipper;
325 NodeSetReader<Graph, ReaderTraits> nodeset_reader;
326 EdgeSetReader<Graph, ReaderTraits> edgeset_reader;
328 NodeReader<Graph> node_reader;
329 EdgeReader<Graph> edge_reader;
331 AttributeReader<ReaderTraits> attribute_reader;
334 /// \brief Read a graph from the input.
336 /// Read a graph from the input.
337 /// \param is The input stream.
338 /// \param g The graph.
339 /// \param capacity The capacity map.
340 /// \param s The source node.
341 /// \param t The target node.
342 /// \param cost The cost map.
343 template<typename Graph, typename CapacityMap, typename CostMap>
344 void readGraph(std::istream& is, Graph &g, CapacityMap& capacity,
345 typename Graph::Node &s, typename Graph::Node &t,
347 GraphReader<Graph> reader(is, g);
348 reader.readEdgeMap("capacity", capacity);
349 reader.readEdgeMap("cost", cost);
350 reader.readNode("source", s);
351 reader.readNode("target", t);
355 /// \brief Read a graph from the input.
357 /// Read a graph from the input.
358 /// \param is The input stream.
359 /// \param g The graph.
360 /// \param capacity The capacity map.
361 /// \param s The source node.
362 /// \param t The target node.
363 template<typename Graph, typename CapacityMap>
364 void readGraph(std::istream& is, Graph &g, CapacityMap& capacity,
365 typename Graph::Node &s, typename Graph::Node &t) {
366 GraphReader<Graph> reader(is, g);
367 reader.readEdgeMap("capacity", capacity);
368 reader.readNode("source", s);
369 reader.readNode("target", t);
373 /// \brief Read a graph from the input.
375 /// Read a graph from the input.
376 /// \param is The input stream.
377 /// \param g The graph.
378 /// \param capacity The capacity map.
379 /// \param s The source node.
380 template<typename Graph, typename CapacityMap>
381 void readGraph(std::istream& is, Graph &g, CapacityMap& capacity,
382 typename Graph::Node &s) {
383 GraphReader<Graph> reader(is, g);
384 reader.readEdgeMap("capacity", capacity);
385 reader.readNode("source", s);
389 /// \brief Read a graph from the input.
391 /// Read a graph from the input.
392 /// \param is The input stream.
393 /// \param g The graph.
394 /// \param capacity The capacity map.
395 template<typename Graph, typename CapacityMap>
396 void readGraph(std::istream& is, Graph &g, CapacityMap& capacity) {
397 GraphReader<Graph> reader(is, g);
398 reader.readEdgeMap("capacity", capacity);
402 /// \brief Read a graph from the input.
404 /// Read a graph from the input.
405 /// \param is The input stream.
406 /// \param g The graph.
407 template<typename Graph>
408 void readGraph(std::istream& is, Graph &g) {
409 GraphReader<Graph> reader(is, g);
413 /// \brief The undir graph reader class.
415 /// The given file format may contain several maps and labeled nodes or
418 /// If you read a graph you need not read all the maps and items just those
419 /// that you need. The interface of the \c GraphReader is very similar to
420 /// the GraphWriter but the reading method does not depend on the order the
423 /// The reader object suppose that each not readed value does not contain
424 /// whitespaces, therefore it has some extra possibilities to control how
425 /// it should skip the values when the string representation contains spaces.
428 /// UndirGraphReader<UndirListGraph> reader(std::cin, graph);
431 /// The \c readNodeMap() function reads a map from the \c \@nodeset section.
432 /// If there is a map that you do not want to read from the file and there is
433 /// whitespace in the string represenation of the values then you should
434 /// call the \c skipNodeMap() template member function with proper
438 /// reader.readNodeMap("coords", coords);
440 /// reader.readNodeMap<QuotedStringReader>("label", labelMap);
441 /// reader.skipNodeMap<QuotedStringReader>("description");
443 /// reader.readNodeMap("color", colorMap);
446 /// With the \c readUndirEdgeMap() member function you can give an
447 /// undir edge map reading command similar to the NodeMaps.
450 /// reader.readUndirEdgeMap("capacity", capacityMap);
453 /// The reading of the directed edge maps is just a syntactical sugar.
454 /// It reads two undirected edgemaps into a directed edge map. The
455 /// undirected edge maps' name should be start with the \c '+' and the
456 /// \c '-' character and the same.
459 /// reader.readEdgeMap("flow", flowMap);
462 /// With \c readNode() and \c readUndirEdge() functions you can read
463 /// labeled Nodes and UndirEdges.
466 /// reader.readNode("source", sourceNode);
467 /// reader.readNode("target", targetNode);
469 /// reader.readUndirEdge("observed", undirEdge);
472 /// With the \c readAttribute() functions you can read an attribute
473 /// in a variable. You can specify the reader for the attribute as
476 /// After you give all read commands you must call the \c run() member
477 /// function, which execute all the commands.
484 /// \see DefaultReaderTraits
485 /// \see \ref UndirGraphWriter
486 /// \see \ref graph-io-page
488 /// \author Balazs Dezso
489 template <typename _Graph, typename _ReaderTraits = DefaultReaderTraits>
490 class UndirGraphReader {
493 typedef _Graph Graph;
494 typedef typename Graph::Node Node;
495 typedef typename Graph::Edge Edge;
496 typedef typename Graph::UndirEdge UndirEdge;
498 typedef _ReaderTraits ReaderTraits;
499 typedef typename ReaderTraits::Skipper DefaultSkipper;
501 /// \brief Construct a new UndirGraphReader.
503 /// Construct a new UndirGraphReader. It reads into the given graph
504 /// and it use the given reader as the default skipper.
505 UndirGraphReader(std::istream& _is, Graph& _graph,
506 const DefaultSkipper& _skipper = DefaultSkipper())
507 : reader(new LemonReader(_is)), own_reader(true), skipper(_skipper),
508 nodeset_reader(*reader, _graph, std::string(), skipper),
509 undir_edgeset_reader(*reader, _graph, nodeset_reader,
510 std::string(), skipper),
511 node_reader(*reader, nodeset_reader, std::string()),
512 undir_edge_reader(*reader, undir_edgeset_reader, std::string()),
513 attribute_reader(*reader, std::string()) {}
515 /// \brief Construct a new UndirGraphReader.
517 /// Construct a new UndirGraphReader. It reads into the given graph
518 /// and it use the given reader as the default skipper.
519 UndirGraphReader(const std::string& _filename, Graph& _graph,
520 const DefaultSkipper& _skipper = DefaultSkipper())
521 : reader(new LemonReader(_filename)), own_reader(true),
523 nodeset_reader(*reader, _graph, std::string(), skipper),
524 undir_edgeset_reader(*reader, _graph, nodeset_reader,
525 std::string(), skipper),
526 node_reader(*reader, nodeset_reader, std::string()),
527 undir_edge_reader(*reader, undir_edgeset_reader, std::string()),
528 attribute_reader(*reader, std::string()) {}
530 /// \brief Construct a new UndirGraphReader.
532 /// Construct a new UndirGraphReader. It reads into the given graph
533 /// and it use the given reader as the default skipper.
534 UndirGraphReader(LemonReader& _reader, Graph& _graph,
535 const DefaultSkipper& _skipper = DefaultSkipper())
536 : reader(_reader), own_reader(false), skipper(_skipper),
537 nodeset_reader(*reader, _graph, std::string(), skipper),
538 undir_edgeset_reader(*reader, _graph, nodeset_reader,
539 std::string(), skipper),
540 node_reader(*reader, nodeset_reader, std::string()),
541 undir_edge_reader(*reader, undir_edgeset_reader, std::string()),
542 attribute_reader(*reader, std::string()) {}
544 /// \brief Destruct the graph reader.
546 /// Destruct the graph reader.
547 ~UndirGraphReader() {
552 /// \brief Add a new node map reader command for the reader.
554 /// Add a new node map reader command for the reader.
555 template <typename Map>
556 UndirGraphReader& readNodeMap(std::string name, Map& map) {
557 nodeset_reader.readNodeMap(name, map);
561 template <typename Map>
562 UndirGraphReader& readNodeMap(std::string name, const Map& map) {
563 nodeset_reader.readNodeMap(name, map);
567 /// \brief Add a new node map reader command for the reader.
569 /// Add a new node map reader command for the reader.
570 template <typename Reader, typename Map>
571 UndirGraphReader& readNodeMap(std::string name, Map& map,
572 const Reader& reader = Reader()) {
573 nodeset_reader.readNodeMap(name, map, reader);
577 template <typename Reader, typename Map>
578 UndirGraphReader& readNodeMap(std::string name, const Map& map,
579 const Reader& reader = Reader()) {
580 nodeset_reader.readNodeMap(name, map, reader);
584 /// \brief Add a new node map skipper command for the reader.
586 /// Add a new node map skipper command for the reader.
587 template <typename Reader>
588 UndirGraphReader& skipNodeMap(std::string name,
589 const Reader& reader = Reader()) {
590 nodeset_reader.skipNodeMap(name, reader);
594 /// \brief Add a new undirected edge map reader command for the reader.
596 /// Add a new undirected edge map reader command for the reader.
597 template <typename Map>
598 UndirGraphReader& readUndirEdgeMap(std::string name, Map& map) {
599 undir_edgeset_reader.readUndirEdgeMap(name, map);
603 template <typename Map>
604 UndirGraphReader& readUndirEdgeMap(std::string name, const Map& map) {
605 undir_edgeset_reader.readUndirEdgeMap(name, map);
610 /// \brief Add a new undirected edge map reader command for the reader.
612 /// Add a new undirected edge map reader command for the reader.
613 template <typename Reader, typename Map>
614 UndirGraphReader& readUndirEdgeMap(std::string name, Map& map,
615 const Reader& reader = Reader()) {
616 undir_edgeset_reader.readUndirEdgeMap(name, map, reader);
620 template <typename Reader, typename Map>
621 UndirGraphReader& readUndirEdgeMap(std::string name, const Map& map,
622 const Reader& reader = Reader()) {
623 undir_edgeset_reader.readUndirEdgeMap(name, map, reader);
627 /// \brief Add a new undirected edge map skipper command for the reader.
629 /// Add a new undirected edge map skipper command for the reader.
630 template <typename Reader>
631 UndirGraphReader& skipUndirEdgeMap(std::string name,
632 const Reader& reader = Reader()) {
633 undir_edgeset_reader.skipUndirMap(name, reader);
638 /// \brief Add a new edge map reader command for the reader.
640 /// Add a new edge map reader command for the reader.
641 template <typename Map>
642 UndirGraphReader& readEdgeMap(std::string name, Map& map) {
643 undir_edgeset_reader.readEdgeMap(name, map);
647 template <typename Map>
648 UndirGraphReader& readEdgeMap(std::string name, const Map& map) {
649 undir_edgeset_reader.readEdgeMap(name, map);
654 /// \brief Add a new edge map reader command for the reader.
656 /// Add a new edge map reader command for the reader.
657 template <typename Reader, typename Map>
658 UndirGraphReader& readEdgeMap(std::string name, Map& map,
659 const Reader& reader = Reader()) {
660 undir_edgeset_reader.readEdgeMap(name, map, reader);
664 template <typename Reader, typename Map>
665 UndirGraphReader& readEdgeMap(std::string name, const Map& map,
666 const Reader& reader = Reader()) {
667 undir_edgeset_reader.readEdgeMap(name, map, reader);
671 /// \brief Add a new edge map skipper command for the reader.
673 /// Add a new edge map skipper command for the reader.
674 template <typename Reader>
675 UndirGraphReader& skipEdgeMap(std::string name,
676 const Reader& reader = Reader()) {
677 undir_edgeset_reader.skipEdgeMap(name, reader);
681 /// \brief Add a new labeled node reader for the reader.
683 /// Add a new labeled node reader for the reader.
684 UndirGraphReader& readNode(std::string name, Node& node) {
685 node_reader.readNode(name, node);
689 /// \brief Add a new labeled edge reader for the reader.
691 /// Add a new labeled edge reader for the reader.
692 UndirGraphReader& readEdge(std::string name, Edge& edge) {
693 undir_edge_reader.readEdge(name, edge);
696 /// \brief Add a new labeled undirected edge reader for the reader.
698 /// Add a new labeled undirected edge reader for the reader.
699 UndirGraphReader& readUndirEdge(std::string name, UndirEdge& edge) {
700 undir_edge_reader.readUndirEdge(name, edge);
703 /// \brief Add a new attribute reader command.
705 /// Add a new attribute reader command.
706 template <typename Value>
707 UndirGraphReader& readAttribute(std::string name, Value& value) {
708 attribute_reader.readAttribute(name, value);
712 /// \brief Add a new attribute reader command.
714 /// Add a new attribute reader command.
715 template <typename Reader, typename Value>
716 UndirGraphReader& readAttribute(std::string name, Value& value,
717 const Reader& reader) {
718 attribute_reader.readAttribute<Reader>(name, value, reader);
722 /// \brief Conversion operator to LemonReader.
724 /// Conversion operator to LemonReader. It make possible
725 /// to access the encapsulated \e LemonReader, this way
726 /// you can attach to this reader new instances of
727 /// \e LemonReader::SectionReader.
728 operator LemonReader&() {
732 /// \brief Executes the reader commands.
734 /// Executes the reader commands.
739 /// \brief Gives back the node by its id.
741 /// It reads an id from the stream and gives back which node belongs to
742 /// it. It is possible only if there was read an "id" named node map.
743 Node readId(std::istream& is, Node) const {
744 return nodeset_reader.readId(is, Node());
747 /// \brief Gives back the edge by its id.
749 /// It reads an id from the stream and gives back which edge belongs to
750 /// it. It is possible only if there was read an "id" named edge map.
751 Edge readId(std::istream& is, Edge) const {
752 return undir_edgeset_reader.readId(is, Edge());
755 /// \brief Gives back the undirected edge by its id.
757 /// It reads an id from the stream and gives back which undirected edge
758 /// belongs to it. It is possible only if there was read an "id" named
760 UndirEdge readId(std::istream& is, UndirEdge) const {
761 return undir_edgeset_reader.readId(is, UndirEdge());
770 DefaultSkipper skipper;
772 NodeSetReader<Graph, ReaderTraits> nodeset_reader;
773 UndirEdgeSetReader<Graph, ReaderTraits> undir_edgeset_reader;
775 NodeReader<Graph> node_reader;
776 UndirEdgeReader<Graph> undir_edge_reader;
778 AttributeReader<ReaderTraits> attribute_reader;
781 /// \brief Read an undir graph from the input.
783 /// Read an undir graph from the input.
784 /// \param is The input stream.
785 /// \param g The graph.
786 /// \param capacity The capacity map.
787 template<typename Graph, typename CapacityMap>
788 void readUndirGraph(std::istream& is, Graph &g, CapacityMap& capacity) {
789 UndirGraphReader<Graph> reader(is, g);
790 reader.readUndirEdgeMap("capacity", capacity);
794 /// \brief Read an undir graph from the input.
796 /// Read an undir graph from the input.
797 /// \param is The input stream.
798 /// \param g The graph.
799 template<typename Graph>
800 void readUndirGraph(std::istream& is, Graph &g) {
801 UndirGraphReader<Graph> reader(is, g);