COIN-OR::LEMON - Graph Library

source: lemon-0.x/src/lemon/graph_reader.h @ 1408:892c29484414

Last change on this file since 1408:892c29484414 was 1408:892c29484414, checked in by Balazs Dezso, 15 years ago

New graph reader interface.

File size: 11.8 KB
Line 
1/* -*- C++ -*-
2 * src/lemon/graph_reader.h - Part of LEMON, a generic C++ optimization library
3 *
4 * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
5 * (Egervary Research Group on Combinatorial Optimization, EGRES).
6 *
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.
10 *
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
13 * purpose.
14 *
15 */
16
17///\ingroup io_group
18///\file
19///\brief Lemon Graph Format reader.
20
21#ifndef LEMON_GRAPH_READER_H
22#define LEMON_GRAPH_READER_H
23
24#include <iostream>
25
26#include <lemon/error.h>
27#include <lemon/lemon_reader.h>
28
29namespace lemon {
30
31  /// \addtogroup io_group
32  /// @{
33
34  /// \brief The graph reader class.
35  ///
36  /// The given file format may contain several maps and labeled nodes or
37  /// edges.
38  ///
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
42  /// given commands.
43  ///
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.
47  ///
48  /// \code
49  /// GraphReader<ListGraph> reader(std::cin, graph);
50  /// \endcode
51  ///
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
56  /// parameters.
57  ///
58  /// \code
59  /// reader.readNodeMap("x-coord", xCoordMap);
60  /// reader.readNodeMap("y-coord", yCoordMap);
61  ///
62  /// reader.readNodeMap<QuotedStringReader>("label", labelMap);
63  /// reader.skipNodeMap<QuotedStringReader>("description");
64  ///
65  /// reader.readNodeMap("color", colorMap);
66  /// \endcode
67  ///
68  /// With the \c readEdgeMap() member function you can give an edge map
69  /// reading command similar to the NodeMaps.
70  ///
71  /// \code
72  /// reader.readEdgeMap("weight", weightMap);
73  /// reader.readEdgeMap("label", labelMap);
74  /// \endcode
75  ///
76  /// With \c readNode() and \c readEdge() functions you can read
77  /// labeled Nodes and Edges.
78  ///
79  /// \code
80  /// reader.readNode("source", sourceNode);
81  /// reader.readNode("target", targetNode);
82  ///
83  /// reader.readEdge("observed", edge);
84  /// \endcode
85  ///
86  /// With the \c readAttribute() functions you can read an attribute
87  /// in a variable. You can specify the reader for the attribute as
88  /// the nodemaps.
89  ///
90  /// After you give all read commands you must call the \c run() member
91  /// function, which execute all the commands.
92  ///
93  /// \code
94  /// reader.run();
95  /// \endcode
96  ///
97  /// \see DefaultReaderTraits
98  /// \see QuotedStringReader
99  /// \see \ref GraphWriter
100  /// \see \ref graph-io-page
101  /// \author Balazs Dezso
102  template <typename _Graph, typename _ReaderTraits = DefaultReaderTraits>
103  class GraphReader {
104  public:
105   
106    typedef _Graph Graph;
107    typedef typename Graph::Node Node;
108    typedef typename Graph::Edge Edge;
109
110    typedef _ReaderTraits ReaderTraits;
111    typedef typename ReaderTraits::Skipper DefaultSkipper;
112
113    /// \brief Construct a new GraphReader.
114    ///
115    /// Construct a new GraphReader. It reads into the given graph
116    /// and it use the given reader as the default skipper.
117    GraphReader(std::istream& _is, Graph& _graph,
118                const DefaultSkipper& _skipper = DefaultSkipper())
119      : reader(new LemonReader(_is)), own_reader(true),
120        graph(_graph), skipper(_skipper),
121        nodeset_reader(*reader, graph, std::string(), skipper),
122        edgeset_reader(*reader, graph, nodeset_reader, 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()) {}
126
127    /// \brief Construct a new GraphReader.
128    ///
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, Graph& _graph,
132                const DefaultSkipper& _skipper = DefaultSkipper())
133      : reader(new LemonReader(_filename)), own_reader(true),
134        graph(_graph), skipper(_skipper),
135        nodeset_reader(*reader, graph, std::string(), skipper),
136        edgeset_reader(*reader, graph, nodeset_reader, std::string(), skipper),
137        node_reader(*reader, nodeset_reader, std::string()),
138        edge_reader(*reader, edgeset_reader, std::string()),
139        attribute_reader(*reader, std::string()) {}
140
141    /// \brief Construct a new GraphReader.
142    ///
143    /// Construct a new GraphReader. It reads into the given graph
144    /// and it use the given reader as the default skipper.
145    GraphReader(LemonReader& _reader, Graph& _graph,
146                const DefaultSkipper& _skipper = DefaultSkipper())
147      : reader(_reader), own_reader(false),
148        graph(_graph), skipper(_skipper),
149        nodeset_reader(*reader, graph, std::string(), skipper),
150        edgeset_reader(*reader, graph, nodeset_reader, std::string(), skipper),
151        node_reader(*reader, nodeset_reader, std::string()),
152        edge_reader(*reader, edgeset_reader, std::string()),
153        attribute_reader(*reader, std::string()) {}
154
155    /// \brief Destruct the graph reader.
156    ///
157    /// Destruct the graph reader.
158    ~GraphReader() {
159      if (own_reader)
160        delete reader;
161    }
162
163    /// \brief Add a new node map reader command for the reader.
164    ///
165    /// Add a new node map reader command for the reader.
166    template <typename Map>
167    GraphReader& readNodeMap(std::string name, Map& map) {
168      nodeset_reader.readMap(name, map);
169      return *this;
170    }
171
172    /// \brief Add a new node map reader command for the reader.
173    ///
174    /// Add a new node map reader command for the reader.
175    template <typename Reader, typename Map>
176    GraphReader& readNodeMap(std::string name, Map& map,
177                             const Reader& reader = Reader()) {
178      nodeset_reader.readMap(name, map, reader);
179      return *this;
180    }
181
182    /// \brief Add a new node map skipper command for the reader.
183    ///
184    /// Add a new node map skipper command for the reader.
185    template <typename Reader>
186    GraphReader& skipNodeMap(std::string name,
187                             const Reader& reader = Reader()) {
188      nodeset_reader.skipMap(name, reader);
189      return *this;
190    }
191
192    /// \brief Add a new edge map reader command for the reader.
193    ///
194    /// Add a new edge map reader command for the reader.
195    template <typename Map>
196    GraphReader& readEdgeMap(std::string name, Map& map) {
197      edgeset_reader.readMap(name, map);
198      return *this;
199    }
200
201
202    /// \brief Add a new edge map reader command for the reader.
203    ///
204    /// Add a new edge map reader command for the reader.
205    template <typename Reader, typename Map>
206    GraphReader& readEdgeMap(std::string name, Map& map,
207                             const Reader& reader = Reader()) {
208      edgeset_reader.readMap(name, map, reader);
209      return *this;
210    }
211
212    /// \brief Add a new edge map skipper command for the reader.
213    ///
214    /// Add a new edge map skipper command for the reader.
215    template <typename Reader>
216    GraphReader& skipEdgeMap(std::string name,
217                             const Reader& reader = Reader()) {
218
219      edgeset_reader.skipMap(name, reader);
220      return *this;
221    }
222
223    /// \brief Add a new labeled node reader for the reader.
224    ///
225    /// Add a new labeled node reader for the reader.
226    GraphReader& readNode(std::string name, Node& node) {
227      node_reader.readNode(name, node);
228      return *this;
229    }
230
231    /// \brief Add a new labeled edge reader for the reader.
232    ///
233    /// Add a new labeled edge reader for the reader.
234    GraphReader& readEdge(std::string name, Edge& edge) {
235      edge_reader.readEdge(name, edge);
236    }
237
238    /// \brief Add a new attribute reader command.
239    ///
240    ///  Add a new attribute reader command.
241    template <typename Value>
242    GraphReader& readAttribute(std::string name, Value& value) {
243      attribute_reader.readAttribute(name, value);
244      return *this;
245    }
246   
247    /// \brief Add a new attribute reader command.
248    ///
249    ///  Add a new attribute reader command.
250    template <typename Reader, typename Value>
251    GraphReader& readAttribute(std::string name, Value& value,
252                               const Reader& reader) {
253      attribute_reader.readAttribute<Reader>(name, value, reader);
254      return *this;
255    }
256
257    /// \brief Conversion operator to LemonReader.
258    ///
259    /// Conversion operator to LemonReader. It make possible
260    /// to access the encapsulated \e LemonReader, this way
261    /// you can attach to this reader new instances of
262    /// \e LemonReader::SectionReader.
263    operator LemonReader&() {
264      return *reader;
265    }
266
267    /// \brief Executes the reader commands.
268    ///
269    /// Executes the reader commands.
270    void run() {
271      reader->run();
272    }
273
274  private:
275
276    LemonReader* reader;
277    bool own_reader;
278
279    Graph& graph;
280
281    DefaultSkipper skipper;
282
283    NodeSetReader<Graph, ReaderTraits> nodeset_reader;
284    EdgeSetReader<Graph, ReaderTraits> edgeset_reader;
285
286    NodeReader<Graph> node_reader;
287    EdgeReader<Graph> edge_reader;
288   
289    AttributeReader<ReaderTraits> attribute_reader;
290  };
291
292  /// \brief Read a graph from the input.
293  ///
294  /// Read a graph from the input.
295  /// \param is The input stream.
296  /// \param g The graph.
297  /// \param capacity The capacity map.
298  /// \param s The source node.
299  /// \param t The target node.
300  /// \param cost The cost map.
301  template<typename Graph, typename CapacityMap, typename CostMap>
302  void readGraph(std::istream& is, Graph &g, CapacityMap& capacity,
303                  typename Graph::Node &s, typename Graph::Node &t,
304                  CostMap& cost) {
305    GraphReader<Graph> reader(is, g);
306    reader.readEdgeMap("capacity", capacity);
307    reader.readEdgeMap("cost", cost);
308    reader.readNode("source", s);
309    reader.readNode("target", t);
310    reader.run();
311  }
312
313  /// \brief Read a graph from the input.
314  ///
315  /// Read a graph from the input.
316  /// \param is The input stream.
317  /// \param g The graph.
318  /// \param capacity The capacity map.
319  /// \param s The source node.
320  /// \param t The target node.
321  template<typename Graph, typename CapacityMap>
322  void readGraph(std::istream& is, Graph &g, CapacityMap& capacity,
323                  typename Graph::Node &s, typename Graph::Node &t) {
324    GraphReader<Graph> reader(is, g);
325    reader.readEdgeMap("capacity", capacity);
326    reader.readNode("source", s);
327    reader.readNode("target", t);
328    reader.run();
329  }
330
331  /// \brief Read a graph from the input.
332  ///
333  /// Read a graph from the input.
334  /// \param is The input stream.
335  /// \param g The graph.
336  /// \param capacity The capacity map.
337  /// \param s The source node.
338  template<typename Graph, typename CapacityMap>
339  void readGraph(std::istream& is, Graph &g, CapacityMap& capacity,
340                  typename Graph::Node &s) {
341    GraphReader<Graph> reader(is, g);
342    reader.readEdgeMap("capacity", capacity);
343    reader.readNode("source", s);
344    reader.run();
345  }
346
347  /// \brief Read a graph from the input.
348  ///
349  /// Read a graph from the input.
350  /// \param is The input stream.
351  /// \param g The graph.
352  /// \param capacity The capacity map.
353  template<typename Graph, typename CapacityMap>
354  void readGraph(std::istream& is, Graph &g, CapacityMap& capacity) {
355    GraphReader<Graph> reader(is, g);
356    reader.readEdgeMap("capacity", capacity);
357    reader.run();
358  }
359
360  /// \brief Read a graph from the input.
361  ///
362  /// Read a graph from the input.
363  /// \param is The input stream.
364  /// \param g The graph.
365  template<typename Graph>
366  void readGraph(std::istream& is, Graph &g) {
367    GraphReader<Graph> reader(is, g);
368    reader.run();
369  }
370
371  /// @}
372}
373
374#endif
Note: See TracBrowser for help on using the repository browser.