2 * src/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.
307 DefaultSkipper skipper;
309 NodeSetReader<Graph, ReaderTraits> nodeset_reader;
310 EdgeSetReader<Graph, ReaderTraits> edgeset_reader;
312 NodeReader<Graph> node_reader;
313 EdgeReader<Graph> edge_reader;
315 AttributeReader<ReaderTraits> attribute_reader;
318 /// \brief Read a graph from the input.
320 /// Read a graph from the input.
321 /// \param is The input stream.
322 /// \param g The graph.
323 /// \param capacity The capacity map.
324 /// \param s The source node.
325 /// \param t The target node.
326 /// \param cost The cost map.
327 template<typename Graph, typename CapacityMap, typename CostMap>
328 void readGraph(std::istream& is, Graph &g, CapacityMap& capacity,
329 typename Graph::Node &s, typename Graph::Node &t,
331 GraphReader<Graph> reader(is, g);
332 reader.readEdgeMap("capacity", capacity);
333 reader.readEdgeMap("cost", cost);
334 reader.readNode("source", s);
335 reader.readNode("target", t);
339 /// \brief Read a graph from the input.
341 /// Read a graph from the input.
342 /// \param is The input stream.
343 /// \param g The graph.
344 /// \param capacity The capacity map.
345 /// \param s The source node.
346 /// \param t The target node.
347 template<typename Graph, typename CapacityMap>
348 void readGraph(std::istream& is, Graph &g, CapacityMap& capacity,
349 typename Graph::Node &s, typename Graph::Node &t) {
350 GraphReader<Graph> reader(is, g);
351 reader.readEdgeMap("capacity", capacity);
352 reader.readNode("source", s);
353 reader.readNode("target", t);
357 /// \brief Read a graph from the input.
359 /// Read a graph from the input.
360 /// \param is The input stream.
361 /// \param g The graph.
362 /// \param capacity The capacity map.
363 /// \param s The source node.
364 template<typename Graph, typename CapacityMap>
365 void readGraph(std::istream& is, Graph &g, CapacityMap& capacity,
366 typename Graph::Node &s) {
367 GraphReader<Graph> reader(is, g);
368 reader.readEdgeMap("capacity", capacity);
369 reader.readNode("source", s);
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 template<typename Graph, typename CapacityMap>
380 void readGraph(std::istream& is, Graph &g, CapacityMap& capacity) {
381 GraphReader<Graph> reader(is, g);
382 reader.readEdgeMap("capacity", capacity);
386 /// \brief Read a graph from the input.
388 /// Read a graph from the input.
389 /// \param is The input stream.
390 /// \param g The graph.
391 template<typename Graph>
392 void readGraph(std::istream& is, Graph &g) {
393 GraphReader<Graph> reader(is, g);
397 /// \brief The undir graph reader class.
399 /// The given file format may contain several maps and labeled nodes or
402 /// If you read a graph you need not read all the maps and items just those
403 /// that you need. The interface of the \c GraphReader is very similar to
404 /// the GraphWriter but the reading method does not depend on the order the
407 /// The reader object suppose that each not readed value does not contain
408 /// whitespaces, therefore it has some extra possibilities to control how
409 /// it should skip the values when the string representation contains spaces.
412 /// UndirGraphReader<UndirListGraph> reader(std::cin, graph);
415 /// The \c readNodeMap() function reads a map from the \c \@nodeset section.
416 /// If there is a map that you do not want to read from the file and there is
417 /// whitespace in the string represenation of the values then you should
418 /// call the \c skipNodeMap() template member function with proper
422 /// reader.readNodeMap("coords", coords);
424 /// reader.readNodeMap<QuotedStringReader>("label", labelMap);
425 /// reader.skipNodeMap<QuotedStringReader>("description");
427 /// reader.readNodeMap("color", colorMap);
430 /// With the \c readUndirEdgeMap() member function you can give an
431 /// undir edge map reading command similar to the NodeMaps.
434 /// reader.readUndirEdgeMap("capacity", capacityMap);
437 /// The reading of the directed edge maps is just a syntactical sugar.
438 /// It reads two undirected edgemaps into a directed edge map. The
439 /// undirected edge maps' name should be start with the \c '+' and the
440 /// \c '-' character and the same.
443 /// reader.readEdgeMap("flow", flowMap);
446 /// With \c readNode() and \c readUndirEdge() functions you can read
447 /// labeled Nodes and UndirEdges.
450 /// reader.readNode("source", sourceNode);
451 /// reader.readNode("target", targetNode);
453 /// reader.readUndirEdge("observed", undirEdge);
456 /// With the \c readAttribute() functions you can read an attribute
457 /// in a variable. You can specify the reader for the attribute as
460 /// After you give all read commands you must call the \c run() member
461 /// function, which execute all the commands.
468 /// \see DefaultReaderTraits
469 /// \see \ref UndirGraphWriter
470 /// \see \ref graph-io-page
472 /// \author Balazs Dezso
473 template <typename _Graph, typename _ReaderTraits = DefaultReaderTraits>
474 class UndirGraphReader {
477 typedef _Graph Graph;
478 typedef typename Graph::Node Node;
479 typedef typename Graph::Edge Edge;
480 typedef typename Graph::UndirEdge UndirEdge;
482 typedef _ReaderTraits ReaderTraits;
483 typedef typename ReaderTraits::Skipper DefaultSkipper;
485 /// \brief Construct a new UndirGraphReader.
487 /// Construct a new UndirGraphReader. It reads into the given graph
488 /// and it use the given reader as the default skipper.
489 UndirGraphReader(std::istream& _is, Graph& _graph,
490 const DefaultSkipper& _skipper = DefaultSkipper())
491 : reader(new LemonReader(_is)), own_reader(true), skipper(_skipper),
492 nodeset_reader(*reader, _graph, std::string(), skipper),
493 undir_edgeset_reader(*reader, _graph, nodeset_reader,
494 std::string(), skipper),
495 node_reader(*reader, nodeset_reader, std::string()),
496 undir_edge_reader(*reader, undir_edgeset_reader, std::string()),
497 attribute_reader(*reader, std::string()) {}
499 /// \brief Construct a new UndirGraphReader.
501 /// Construct a new UndirGraphReader. It reads into the given graph
502 /// and it use the given reader as the default skipper.
503 UndirGraphReader(const std::string& _filename, Graph& _graph,
504 const DefaultSkipper& _skipper = DefaultSkipper())
505 : reader(new LemonReader(_filename)), own_reader(true),
507 nodeset_reader(*reader, _graph, std::string(), skipper),
508 undir_edgeset_reader(*reader, _graph, nodeset_reader,
509 std::string(), skipper),
510 node_reader(*reader, nodeset_reader, std::string()),
511 undir_edge_reader(*reader, undir_edgeset_reader, std::string()),
512 attribute_reader(*reader, std::string()) {}
514 /// \brief Construct a new UndirGraphReader.
516 /// Construct a new UndirGraphReader. It reads into the given graph
517 /// and it use the given reader as the default skipper.
518 UndirGraphReader(LemonReader& _reader, Graph& _graph,
519 const DefaultSkipper& _skipper = DefaultSkipper())
520 : reader(_reader), own_reader(false), skipper(_skipper),
521 nodeset_reader(*reader, _graph, std::string(), skipper),
522 undir_edgeset_reader(*reader, _graph, nodeset_reader,
523 std::string(), skipper),
524 node_reader(*reader, nodeset_reader, std::string()),
525 undir_edge_reader(*reader, undir_edgeset_reader, std::string()),
526 attribute_reader(*reader, std::string()) {}
528 /// \brief Destruct the graph reader.
530 /// Destruct the graph reader.
531 ~UndirGraphReader() {
536 /// \brief Add a new node map reader command for the reader.
538 /// Add a new node map reader command for the reader.
539 template <typename Map>
540 UndirGraphReader& readNodeMap(std::string name, Map& map) {
541 nodeset_reader.readNodeMap(name, map);
545 template <typename Map>
546 UndirGraphReader& readNodeMap(std::string name, const Map& map) {
547 nodeset_reader.readNodeMap(name, map);
551 /// \brief Add a new node map reader command for the reader.
553 /// Add a new node map reader command for the reader.
554 template <typename Reader, typename Map>
555 UndirGraphReader& readNodeMap(std::string name, Map& map,
556 const Reader& reader = Reader()) {
557 nodeset_reader.readNodeMap(name, map, reader);
561 template <typename Reader, typename Map>
562 UndirGraphReader& readNodeMap(std::string name, const Map& map,
563 const Reader& reader = Reader()) {
564 nodeset_reader.readNodeMap(name, map, reader);
568 /// \brief Add a new node map skipper command for the reader.
570 /// Add a new node map skipper command for the reader.
571 template <typename Reader>
572 UndirGraphReader& skipNodeMap(std::string name,
573 const Reader& reader = Reader()) {
574 nodeset_reader.skipNodeMap(name, reader);
578 /// \brief Add a new undirected edge map reader command for the reader.
580 /// Add a new undirected edge map reader command for the reader.
581 template <typename Map>
582 UndirGraphReader& readUndirEdgeMap(std::string name, Map& map) {
583 undir_edgeset_reader.readUndirEdgeMap(name, map);
587 template <typename Map>
588 UndirGraphReader& readUndirEdgeMap(std::string name, const Map& map) {
589 undir_edgeset_reader.readUndirEdgeMap(name, map);
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 Reader, typename Map>
598 UndirGraphReader& readUndirEdgeMap(std::string name, Map& map,
599 const Reader& reader = Reader()) {
600 undir_edgeset_reader.readUndirEdgeMap(name, map, reader);
604 template <typename Reader, typename Map>
605 UndirGraphReader& readUndirEdgeMap(std::string name, const Map& map,
606 const Reader& reader = Reader()) {
607 undir_edgeset_reader.readUndirEdgeMap(name, map, reader);
611 /// \brief Add a new undirected edge map skipper command for the reader.
613 /// Add a new undirected edge map skipper command for the reader.
614 template <typename Reader>
615 UndirGraphReader& skipUndirEdgeMap(std::string name,
616 const Reader& reader = Reader()) {
617 undir_edgeset_reader.skipUndirMap(name, reader);
622 /// \brief Add a new edge map reader command for the reader.
624 /// Add a new edge map reader command for the reader.
625 template <typename Map>
626 UndirGraphReader& readEdgeMap(std::string name, Map& map) {
627 undir_edgeset_reader.readEdgeMap(name, map);
631 template <typename Map>
632 UndirGraphReader& readEdgeMap(std::string name, const Map& map) {
633 undir_edgeset_reader.readEdgeMap(name, map);
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 Reader, typename Map>
642 UndirGraphReader& readEdgeMap(std::string name, Map& map,
643 const Reader& reader = Reader()) {
644 undir_edgeset_reader.readEdgeMap(name, map, reader);
648 template <typename Reader, typename Map>
649 UndirGraphReader& readEdgeMap(std::string name, const Map& map,
650 const Reader& reader = Reader()) {
651 undir_edgeset_reader.readEdgeMap(name, map, reader);
655 /// \brief Add a new edge map skipper command for the reader.
657 /// Add a new edge map skipper command for the reader.
658 template <typename Reader>
659 UndirGraphReader& skipEdgeMap(std::string name,
660 const Reader& reader = Reader()) {
661 undir_edgeset_reader.skipEdgeMap(name, reader);
665 /// \brief Add a new labeled node reader for the reader.
667 /// Add a new labeled node reader for the reader.
668 UndirGraphReader& readNode(std::string name, Node& node) {
669 node_reader.readNode(name, node);
673 /// \brief Add a new labeled edge reader for the reader.
675 /// Add a new labeled edge reader for the reader.
676 UndirGraphReader& readUndirEdge(std::string name, UndirEdge& edge) {
677 undir_edge_reader.readUndirEdge(name, edge);
680 /// \brief Add a new attribute reader command.
682 /// Add a new attribute reader command.
683 template <typename Value>
684 UndirGraphReader& readAttribute(std::string name, Value& value) {
685 attribute_reader.readAttribute(name, value);
689 /// \brief Add a new attribute reader command.
691 /// Add a new attribute reader command.
692 template <typename Reader, typename Value>
693 UndirGraphReader& readAttribute(std::string name, Value& value,
694 const Reader& reader) {
695 attribute_reader.readAttribute<Reader>(name, value, reader);
699 /// \brief Conversion operator to LemonReader.
701 /// Conversion operator to LemonReader. It make possible
702 /// to access the encapsulated \e LemonReader, this way
703 /// you can attach to this reader new instances of
704 /// \e LemonReader::SectionReader.
705 operator LemonReader&() {
709 /// \brief Executes the reader commands.
711 /// Executes the reader commands.
721 DefaultSkipper skipper;
723 NodeSetReader<Graph, ReaderTraits> nodeset_reader;
724 UndirEdgeSetReader<Graph, ReaderTraits> undir_edgeset_reader;
726 NodeReader<Graph> node_reader;
727 UndirEdgeReader<Graph> undir_edge_reader;
729 AttributeReader<ReaderTraits> attribute_reader;
732 /// \brief Read an undir graph from the input.
734 /// Read an undir graph from the input.
735 /// \param is The input stream.
736 /// \param g The graph.
737 /// \param capacity The capacity map.
738 template<typename Graph, typename CapacityMap>
739 void readUndirGraph(std::istream& is, Graph &g, CapacityMap& capacity) {
740 UndirGraphReader<Graph> reader(is, g);
741 reader.readUndirEdgeMap("capacity", capacity);
745 /// \brief Read an undir graph from the input.
747 /// Read an undir graph from the input.
748 /// \param is The input stream.
749 /// \param g The graph.
750 template<typename Graph>
751 void readUndirGraph(std::istream& is, Graph &g) {
752 UndirGraphReader<Graph> reader(is, g);