2126 GraphReader<TGR> graphReader(TGR& graph, const char* fn) { |
2126 GraphReader<TGR> graphReader(TGR& graph, const char* fn) { |
2127 GraphReader<TGR> tmp(graph, fn); |
2127 GraphReader<TGR> tmp(graph, fn); |
2128 return tmp; |
2128 return tmp; |
2129 } |
2129 } |
2130 |
2130 |
|
2131 template <typename BGR> |
|
2132 class BpGraphReader; |
|
2133 |
|
2134 template <typename TBGR> |
|
2135 BpGraphReader<TBGR> bpGraphReader(TBGR& graph, std::istream& is = std::cin); |
|
2136 template <typename TBGR> |
|
2137 BpGraphReader<TBGR> bpGraphReader(TBGR& graph, const std::string& fn); |
|
2138 template <typename TBGR> |
|
2139 BpGraphReader<TBGR> bpGraphReader(TBGR& graph, const char *fn); |
|
2140 |
|
2141 /// \ingroup lemon_io |
|
2142 /// |
|
2143 /// \brief \ref lgf-format "LGF" reader for bipartite graphs |
|
2144 /// |
|
2145 /// This utility reads an \ref lgf-format "LGF" file. |
|
2146 /// |
|
2147 /// It can be used almost the same way as \c GraphReader, but it |
|
2148 /// reads the red and blue nodes from separate sections, and these |
|
2149 /// sections can contain different set of maps. |
|
2150 /// |
|
2151 /// The red and blue maps are read from the corresponding |
|
2152 /// sections. If a map is defined with the same name in both of |
|
2153 /// these sections, then it can be read as a node map. |
|
2154 template <typename BGR> |
|
2155 class BpGraphReader { |
|
2156 public: |
|
2157 |
|
2158 typedef BGR Graph; |
|
2159 |
|
2160 private: |
|
2161 |
|
2162 TEMPLATE_BPGRAPH_TYPEDEFS(BGR); |
|
2163 |
|
2164 std::istream* _is; |
|
2165 bool local_is; |
|
2166 std::string _filename; |
|
2167 |
|
2168 BGR& _graph; |
|
2169 |
|
2170 std::string _nodes_caption; |
|
2171 std::string _edges_caption; |
|
2172 std::string _attributes_caption; |
|
2173 |
|
2174 typedef std::map<std::string, Node> NodeIndex; |
|
2175 NodeIndex _node_index; |
|
2176 typedef std::map<std::string, Edge> EdgeIndex; |
|
2177 EdgeIndex _edge_index; |
|
2178 |
|
2179 typedef std::vector<std::pair<std::string, |
|
2180 _reader_bits::MapStorageBase<Node>*> > NodeMaps; |
|
2181 NodeMaps _red_maps; |
|
2182 NodeMaps _blue_maps; |
|
2183 |
|
2184 typedef std::vector<std::pair<std::string, |
|
2185 _reader_bits::MapStorageBase<Edge>*> > EdgeMaps; |
|
2186 EdgeMaps _edge_maps; |
|
2187 |
|
2188 typedef std::multimap<std::string, _reader_bits::ValueStorageBase*> |
|
2189 Attributes; |
|
2190 Attributes _attributes; |
|
2191 |
|
2192 bool _use_nodes; |
|
2193 bool _use_edges; |
|
2194 |
|
2195 bool _skip_nodes; |
|
2196 bool _skip_edges; |
|
2197 |
|
2198 int line_num; |
|
2199 std::istringstream line; |
|
2200 |
|
2201 public: |
|
2202 |
|
2203 /// \brief Constructor |
|
2204 /// |
|
2205 /// Construct an undirected graph reader, which reads from the given |
|
2206 /// input stream. |
|
2207 BpGraphReader(BGR& graph, std::istream& is = std::cin) |
|
2208 : _is(&is), local_is(false), _graph(graph), |
|
2209 _use_nodes(false), _use_edges(false), |
|
2210 _skip_nodes(false), _skip_edges(false) {} |
|
2211 |
|
2212 /// \brief Constructor |
|
2213 /// |
|
2214 /// Construct an undirected graph reader, which reads from the given |
|
2215 /// file. |
|
2216 BpGraphReader(BGR& graph, const std::string& fn) |
|
2217 : _is(new std::ifstream(fn.c_str())), local_is(true), |
|
2218 _filename(fn), _graph(graph), |
|
2219 _use_nodes(false), _use_edges(false), |
|
2220 _skip_nodes(false), _skip_edges(false) { |
|
2221 if (!(*_is)) { |
|
2222 delete _is; |
|
2223 throw IoError("Cannot open file", fn); |
|
2224 } |
|
2225 } |
|
2226 |
|
2227 /// \brief Constructor |
|
2228 /// |
|
2229 /// Construct an undirected graph reader, which reads from the given |
|
2230 /// file. |
|
2231 BpGraphReader(BGR& graph, const char* fn) |
|
2232 : _is(new std::ifstream(fn)), local_is(true), |
|
2233 _filename(fn), _graph(graph), |
|
2234 _use_nodes(false), _use_edges(false), |
|
2235 _skip_nodes(false), _skip_edges(false) { |
|
2236 if (!(*_is)) { |
|
2237 delete _is; |
|
2238 throw IoError("Cannot open file", fn); |
|
2239 } |
|
2240 } |
|
2241 |
|
2242 /// \brief Destructor |
|
2243 ~BpGraphReader() { |
|
2244 for (typename NodeMaps::iterator it = _red_maps.begin(); |
|
2245 it != _red_maps.end(); ++it) { |
|
2246 delete it->second; |
|
2247 } |
|
2248 |
|
2249 for (typename NodeMaps::iterator it = _blue_maps.begin(); |
|
2250 it != _blue_maps.end(); ++it) { |
|
2251 delete it->second; |
|
2252 } |
|
2253 |
|
2254 for (typename EdgeMaps::iterator it = _edge_maps.begin(); |
|
2255 it != _edge_maps.end(); ++it) { |
|
2256 delete it->second; |
|
2257 } |
|
2258 |
|
2259 for (typename Attributes::iterator it = _attributes.begin(); |
|
2260 it != _attributes.end(); ++it) { |
|
2261 delete it->second; |
|
2262 } |
|
2263 |
|
2264 if (local_is) { |
|
2265 delete _is; |
|
2266 } |
|
2267 |
|
2268 } |
|
2269 |
|
2270 private: |
|
2271 template <typename TBGR> |
|
2272 friend BpGraphReader<TBGR> bpGraphReader(TBGR& graph, std::istream& is); |
|
2273 template <typename TBGR> |
|
2274 friend BpGraphReader<TBGR> bpGraphReader(TBGR& graph, |
|
2275 const std::string& fn); |
|
2276 template <typename TBGR> |
|
2277 friend BpGraphReader<TBGR> bpGraphReader(TBGR& graph, const char *fn); |
|
2278 |
|
2279 BpGraphReader(BpGraphReader& other) |
|
2280 : _is(other._is), local_is(other.local_is), _graph(other._graph), |
|
2281 _use_nodes(other._use_nodes), _use_edges(other._use_edges), |
|
2282 _skip_nodes(other._skip_nodes), _skip_edges(other._skip_edges) { |
|
2283 |
|
2284 other._is = 0; |
|
2285 other.local_is = false; |
|
2286 |
|
2287 _node_index.swap(other._node_index); |
|
2288 _edge_index.swap(other._edge_index); |
|
2289 |
|
2290 _red_maps.swap(other._red_maps); |
|
2291 _blue_maps.swap(other._blue_maps); |
|
2292 _edge_maps.swap(other._edge_maps); |
|
2293 _attributes.swap(other._attributes); |
|
2294 |
|
2295 _nodes_caption = other._nodes_caption; |
|
2296 _edges_caption = other._edges_caption; |
|
2297 _attributes_caption = other._attributes_caption; |
|
2298 |
|
2299 } |
|
2300 |
|
2301 BpGraphReader& operator=(const BpGraphReader&); |
|
2302 |
|
2303 public: |
|
2304 |
|
2305 /// \name Reading Rules |
|
2306 /// @{ |
|
2307 |
|
2308 /// \brief Node map reading rule |
|
2309 /// |
|
2310 /// Add a node map reading rule to the reader. |
|
2311 template <typename Map> |
|
2312 BpGraphReader& nodeMap(const std::string& caption, Map& map) { |
|
2313 checkConcept<concepts::WriteMap<Node, typename Map::Value>, Map>(); |
|
2314 _reader_bits::MapStorageBase<Node>* red_storage = |
|
2315 new _reader_bits::MapStorage<Node, Map>(map); |
|
2316 _red_maps.push_back(std::make_pair(caption, red_storage)); |
|
2317 _reader_bits::MapStorageBase<Node>* blue_storage = |
|
2318 new _reader_bits::MapStorage<Node, Map>(map); |
|
2319 _blue_maps.push_back(std::make_pair(caption, blue_storage)); |
|
2320 return *this; |
|
2321 } |
|
2322 |
|
2323 /// \brief Node map reading rule |
|
2324 /// |
|
2325 /// Add a node map reading rule with specialized converter to the |
|
2326 /// reader. |
|
2327 template <typename Map, typename Converter> |
|
2328 BpGraphReader& nodeMap(const std::string& caption, Map& map, |
|
2329 const Converter& converter = Converter()) { |
|
2330 checkConcept<concepts::WriteMap<Node, typename Map::Value>, Map>(); |
|
2331 _reader_bits::MapStorageBase<Node>* red_storage = |
|
2332 new _reader_bits::MapStorage<Node, Map, Converter>(map, converter); |
|
2333 _red_maps.push_back(std::make_pair(caption, red_storage)); |
|
2334 _reader_bits::MapStorageBase<Node>* blue_storage = |
|
2335 new _reader_bits::MapStorage<Node, Map, Converter>(map, converter); |
|
2336 _blue_maps.push_back(std::make_pair(caption, blue_storage)); |
|
2337 return *this; |
|
2338 } |
|
2339 |
|
2340 /// Add a red map reading rule to the reader. |
|
2341 template <typename Map> |
|
2342 BpGraphReader& redMap(const std::string& caption, Map& map) { |
|
2343 checkConcept<concepts::WriteMap<Node, typename Map::Value>, Map>(); |
|
2344 _reader_bits::MapStorageBase<Node>* storage = |
|
2345 new _reader_bits::MapStorage<Node, Map>(map); |
|
2346 _red_maps.push_back(std::make_pair(caption, storage)); |
|
2347 return *this; |
|
2348 } |
|
2349 |
|
2350 /// \brief Red map reading rule |
|
2351 /// |
|
2352 /// Add a red map reading rule with specialized converter to the |
|
2353 /// reader. |
|
2354 template <typename Map, typename Converter> |
|
2355 BpGraphReader& redMap(const std::string& caption, Map& map, |
|
2356 const Converter& converter = Converter()) { |
|
2357 checkConcept<concepts::WriteMap<Node, typename Map::Value>, Map>(); |
|
2358 _reader_bits::MapStorageBase<Node>* storage = |
|
2359 new _reader_bits::MapStorage<Node, Map, Converter>(map, converter); |
|
2360 _red_maps.push_back(std::make_pair(caption, storage)); |
|
2361 return *this; |
|
2362 } |
|
2363 |
|
2364 /// Add a blue map reading rule to the reader. |
|
2365 template <typename Map> |
|
2366 BpGraphReader& blueMap(const std::string& caption, Map& map) { |
|
2367 checkConcept<concepts::WriteMap<Node, typename Map::Value>, Map>(); |
|
2368 _reader_bits::MapStorageBase<Node>* storage = |
|
2369 new _reader_bits::MapStorage<Node, Map>(map); |
|
2370 _blue_maps.push_back(std::make_pair(caption, storage)); |
|
2371 return *this; |
|
2372 } |
|
2373 |
|
2374 /// \brief Blue map reading rule |
|
2375 /// |
|
2376 /// Add a blue map reading rule with specialized converter to the |
|
2377 /// reader. |
|
2378 template <typename Map, typename Converter> |
|
2379 BpGraphReader& blueMap(const std::string& caption, Map& map, |
|
2380 const Converter& converter = Converter()) { |
|
2381 checkConcept<concepts::WriteMap<Node, typename Map::Value>, Map>(); |
|
2382 _reader_bits::MapStorageBase<Node>* storage = |
|
2383 new _reader_bits::MapStorage<Node, Map, Converter>(map, converter); |
|
2384 _blue_maps.push_back(std::make_pair(caption, storage)); |
|
2385 return *this; |
|
2386 } |
|
2387 |
|
2388 /// \brief Edge map reading rule |
|
2389 /// |
|
2390 /// Add an edge map reading rule to the reader. |
|
2391 template <typename Map> |
|
2392 BpGraphReader& edgeMap(const std::string& caption, Map& map) { |
|
2393 checkConcept<concepts::WriteMap<Edge, typename Map::Value>, Map>(); |
|
2394 _reader_bits::MapStorageBase<Edge>* storage = |
|
2395 new _reader_bits::MapStorage<Edge, Map>(map); |
|
2396 _edge_maps.push_back(std::make_pair(caption, storage)); |
|
2397 return *this; |
|
2398 } |
|
2399 |
|
2400 /// \brief Edge map reading rule |
|
2401 /// |
|
2402 /// Add an edge map reading rule with specialized converter to the |
|
2403 /// reader. |
|
2404 template <typename Map, typename Converter> |
|
2405 BpGraphReader& edgeMap(const std::string& caption, Map& map, |
|
2406 const Converter& converter = Converter()) { |
|
2407 checkConcept<concepts::WriteMap<Edge, typename Map::Value>, Map>(); |
|
2408 _reader_bits::MapStorageBase<Edge>* storage = |
|
2409 new _reader_bits::MapStorage<Edge, Map, Converter>(map, converter); |
|
2410 _edge_maps.push_back(std::make_pair(caption, storage)); |
|
2411 return *this; |
|
2412 } |
|
2413 |
|
2414 /// \brief Arc map reading rule |
|
2415 /// |
|
2416 /// Add an arc map reading rule to the reader. |
|
2417 template <typename Map> |
|
2418 BpGraphReader& arcMap(const std::string& caption, Map& map) { |
|
2419 checkConcept<concepts::WriteMap<Arc, typename Map::Value>, Map>(); |
|
2420 _reader_bits::MapStorageBase<Edge>* forward_storage = |
|
2421 new _reader_bits::GraphArcMapStorage<Graph, true, Map>(_graph, map); |
|
2422 _edge_maps.push_back(std::make_pair('+' + caption, forward_storage)); |
|
2423 _reader_bits::MapStorageBase<Edge>* backward_storage = |
|
2424 new _reader_bits::GraphArcMapStorage<BGR, false, Map>(_graph, map); |
|
2425 _edge_maps.push_back(std::make_pair('-' + caption, backward_storage)); |
|
2426 return *this; |
|
2427 } |
|
2428 |
|
2429 /// \brief Arc map reading rule |
|
2430 /// |
|
2431 /// Add an arc map reading rule with specialized converter to the |
|
2432 /// reader. |
|
2433 template <typename Map, typename Converter> |
|
2434 BpGraphReader& arcMap(const std::string& caption, Map& map, |
|
2435 const Converter& converter = Converter()) { |
|
2436 checkConcept<concepts::WriteMap<Arc, typename Map::Value>, Map>(); |
|
2437 _reader_bits::MapStorageBase<Edge>* forward_storage = |
|
2438 new _reader_bits::GraphArcMapStorage<BGR, true, Map, Converter> |
|
2439 (_graph, map, converter); |
|
2440 _edge_maps.push_back(std::make_pair('+' + caption, forward_storage)); |
|
2441 _reader_bits::MapStorageBase<Edge>* backward_storage = |
|
2442 new _reader_bits::GraphArcMapStorage<BGR, false, Map, Converter> |
|
2443 (_graph, map, converter); |
|
2444 _edge_maps.push_back(std::make_pair('-' + caption, backward_storage)); |
|
2445 return *this; |
|
2446 } |
|
2447 |
|
2448 /// \brief Attribute reading rule |
|
2449 /// |
|
2450 /// Add an attribute reading rule to the reader. |
|
2451 template <typename Value> |
|
2452 BpGraphReader& attribute(const std::string& caption, Value& value) { |
|
2453 _reader_bits::ValueStorageBase* storage = |
|
2454 new _reader_bits::ValueStorage<Value>(value); |
|
2455 _attributes.insert(std::make_pair(caption, storage)); |
|
2456 return *this; |
|
2457 } |
|
2458 |
|
2459 /// \brief Attribute reading rule |
|
2460 /// |
|
2461 /// Add an attribute reading rule with specialized converter to the |
|
2462 /// reader. |
|
2463 template <typename Value, typename Converter> |
|
2464 BpGraphReader& attribute(const std::string& caption, Value& value, |
|
2465 const Converter& converter = Converter()) { |
|
2466 _reader_bits::ValueStorageBase* storage = |
|
2467 new _reader_bits::ValueStorage<Value, Converter>(value, converter); |
|
2468 _attributes.insert(std::make_pair(caption, storage)); |
|
2469 return *this; |
|
2470 } |
|
2471 |
|
2472 /// \brief Node reading rule |
|
2473 /// |
|
2474 /// Add a node reading rule to reader. |
|
2475 BpGraphReader& node(const std::string& caption, Node& node) { |
|
2476 typedef _reader_bits::MapLookUpConverter<Node> Converter; |
|
2477 Converter converter(_node_index); |
|
2478 _reader_bits::ValueStorageBase* storage = |
|
2479 new _reader_bits::ValueStorage<Node, Converter>(node, converter); |
|
2480 _attributes.insert(std::make_pair(caption, storage)); |
|
2481 return *this; |
|
2482 } |
|
2483 |
|
2484 /// \brief Edge reading rule |
|
2485 /// |
|
2486 /// Add an edge reading rule to reader. |
|
2487 BpGraphReader& edge(const std::string& caption, Edge& edge) { |
|
2488 typedef _reader_bits::MapLookUpConverter<Edge> Converter; |
|
2489 Converter converter(_edge_index); |
|
2490 _reader_bits::ValueStorageBase* storage = |
|
2491 new _reader_bits::ValueStorage<Edge, Converter>(edge, converter); |
|
2492 _attributes.insert(std::make_pair(caption, storage)); |
|
2493 return *this; |
|
2494 } |
|
2495 |
|
2496 /// \brief Arc reading rule |
|
2497 /// |
|
2498 /// Add an arc reading rule to reader. |
|
2499 BpGraphReader& arc(const std::string& caption, Arc& arc) { |
|
2500 typedef _reader_bits::GraphArcLookUpConverter<BGR> Converter; |
|
2501 Converter converter(_graph, _edge_index); |
|
2502 _reader_bits::ValueStorageBase* storage = |
|
2503 new _reader_bits::ValueStorage<Arc, Converter>(arc, converter); |
|
2504 _attributes.insert(std::make_pair(caption, storage)); |
|
2505 return *this; |
|
2506 } |
|
2507 |
|
2508 /// @} |
|
2509 |
|
2510 /// \name Select Section by Name |
|
2511 /// @{ |
|
2512 |
|
2513 /// \brief Set \c \@nodes section to be read |
|
2514 /// |
|
2515 /// Set \c \@nodes section to be read. |
|
2516 BpGraphReader& nodes(const std::string& caption) { |
|
2517 _nodes_caption = caption; |
|
2518 return *this; |
|
2519 } |
|
2520 |
|
2521 /// \brief Set \c \@edges section to be read |
|
2522 /// |
|
2523 /// Set \c \@edges section to be read. |
|
2524 BpGraphReader& edges(const std::string& caption) { |
|
2525 _edges_caption = caption; |
|
2526 return *this; |
|
2527 } |
|
2528 |
|
2529 /// \brief Set \c \@attributes section to be read |
|
2530 /// |
|
2531 /// Set \c \@attributes section to be read. |
|
2532 BpGraphReader& attributes(const std::string& caption) { |
|
2533 _attributes_caption = caption; |
|
2534 return *this; |
|
2535 } |
|
2536 |
|
2537 /// @} |
|
2538 |
|
2539 /// \name Using Previously Constructed Node or Edge Set |
|
2540 /// @{ |
|
2541 |
|
2542 /// \brief Use previously constructed node set |
|
2543 /// |
|
2544 /// Use previously constructed node set, and specify the node |
|
2545 /// label map. |
|
2546 template <typename Map> |
|
2547 BpGraphReader& useNodes(const Map& map) { |
|
2548 checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>(); |
|
2549 LEMON_ASSERT(!_use_nodes, "Multiple usage of useNodes() member"); |
|
2550 _use_nodes = true; |
|
2551 _writer_bits::DefaultConverter<typename Map::Value> converter; |
|
2552 for (NodeIt n(_graph); n != INVALID; ++n) { |
|
2553 _node_index.insert(std::make_pair(converter(map[n]), n)); |
|
2554 } |
|
2555 return *this; |
|
2556 } |
|
2557 |
|
2558 /// \brief Use previously constructed node set |
|
2559 /// |
|
2560 /// Use previously constructed node set, and specify the node |
|
2561 /// label map and a functor which converts the label map values to |
|
2562 /// \c std::string. |
|
2563 template <typename Map, typename Converter> |
|
2564 BpGraphReader& useNodes(const Map& map, |
|
2565 const Converter& converter = Converter()) { |
|
2566 checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>(); |
|
2567 LEMON_ASSERT(!_use_nodes, "Multiple usage of useNodes() member"); |
|
2568 _use_nodes = true; |
|
2569 for (NodeIt n(_graph); n != INVALID; ++n) { |
|
2570 _node_index.insert(std::make_pair(converter(map[n]), n)); |
|
2571 } |
|
2572 return *this; |
|
2573 } |
|
2574 |
|
2575 /// \brief Use previously constructed edge set |
|
2576 /// |
|
2577 /// Use previously constructed edge set, and specify the edge |
|
2578 /// label map. |
|
2579 template <typename Map> |
|
2580 BpGraphReader& useEdges(const Map& map) { |
|
2581 checkConcept<concepts::ReadMap<Edge, typename Map::Value>, Map>(); |
|
2582 LEMON_ASSERT(!_use_edges, "Multiple usage of useEdges() member"); |
|
2583 _use_edges = true; |
|
2584 _writer_bits::DefaultConverter<typename Map::Value> converter; |
|
2585 for (EdgeIt a(_graph); a != INVALID; ++a) { |
|
2586 _edge_index.insert(std::make_pair(converter(map[a]), a)); |
|
2587 } |
|
2588 return *this; |
|
2589 } |
|
2590 |
|
2591 /// \brief Use previously constructed edge set |
|
2592 /// |
|
2593 /// Use previously constructed edge set, and specify the edge |
|
2594 /// label map and a functor which converts the label map values to |
|
2595 /// \c std::string. |
|
2596 template <typename Map, typename Converter> |
|
2597 BpGraphReader& useEdges(const Map& map, |
|
2598 const Converter& converter = Converter()) { |
|
2599 checkConcept<concepts::ReadMap<Edge, typename Map::Value>, Map>(); |
|
2600 LEMON_ASSERT(!_use_edges, "Multiple usage of useEdges() member"); |
|
2601 _use_edges = true; |
|
2602 for (EdgeIt a(_graph); a != INVALID; ++a) { |
|
2603 _edge_index.insert(std::make_pair(converter(map[a]), a)); |
|
2604 } |
|
2605 return *this; |
|
2606 } |
|
2607 |
|
2608 /// \brief Skip the reading of node section |
|
2609 /// |
|
2610 /// Omit the reading of the node section. This implies that each node |
|
2611 /// map reading rule will be abandoned, and the nodes of the graph |
|
2612 /// will not be constructed, which usually cause that the edge set |
|
2613 /// could not be read due to lack of node name |
|
2614 /// could not be read due to lack of node name resolving. |
|
2615 /// Therefore \c skipEdges() function should also be used, or |
|
2616 /// \c useNodes() should be used to specify the label of the nodes. |
|
2617 BpGraphReader& skipNodes() { |
|
2618 LEMON_ASSERT(!_skip_nodes, "Skip nodes already set"); |
|
2619 _skip_nodes = true; |
|
2620 return *this; |
|
2621 } |
|
2622 |
|
2623 /// \brief Skip the reading of edge section |
|
2624 /// |
|
2625 /// Omit the reading of the edge section. This implies that each edge |
|
2626 /// map reading rule will be abandoned, and the edges of the graph |
|
2627 /// will not be constructed. |
|
2628 BpGraphReader& skipEdges() { |
|
2629 LEMON_ASSERT(!_skip_edges, "Skip edges already set"); |
|
2630 _skip_edges = true; |
|
2631 return *this; |
|
2632 } |
|
2633 |
|
2634 /// @} |
|
2635 |
|
2636 private: |
|
2637 |
|
2638 bool readLine() { |
|
2639 std::string str; |
|
2640 while(++line_num, std::getline(*_is, str)) { |
|
2641 line.clear(); line.str(str); |
|
2642 char c; |
|
2643 if (line >> std::ws >> c && c != '#') { |
|
2644 line.putback(c); |
|
2645 return true; |
|
2646 } |
|
2647 } |
|
2648 return false; |
|
2649 } |
|
2650 |
|
2651 bool readSuccess() { |
|
2652 return static_cast<bool>(*_is); |
|
2653 } |
|
2654 |
|
2655 void skipSection() { |
|
2656 char c; |
|
2657 while (readSuccess() && line >> c && c != '@') { |
|
2658 readLine(); |
|
2659 } |
|
2660 if (readSuccess()) { |
|
2661 line.putback(c); |
|
2662 } |
|
2663 } |
|
2664 |
|
2665 void readRedNodes() { |
|
2666 |
|
2667 std::vector<int> map_index(_red_maps.size()); |
|
2668 int map_num, label_index; |
|
2669 |
|
2670 char c; |
|
2671 if (!readLine() || !(line >> c) || c == '@') { |
|
2672 if (readSuccess() && line) line.putback(c); |
|
2673 if (!_red_maps.empty()) |
|
2674 throw FormatError("Cannot find map names"); |
|
2675 return; |
|
2676 } |
|
2677 line.putback(c); |
|
2678 |
|
2679 { |
|
2680 std::map<std::string, int> maps; |
|
2681 |
|
2682 std::string map; |
|
2683 int index = 0; |
|
2684 while (_reader_bits::readToken(line, map)) { |
|
2685 if (maps.find(map) != maps.end()) { |
|
2686 std::ostringstream msg; |
|
2687 msg << "Multiple occurence of red map: " << map; |
|
2688 throw FormatError(msg.str()); |
|
2689 } |
|
2690 maps.insert(std::make_pair(map, index)); |
|
2691 ++index; |
|
2692 } |
|
2693 |
|
2694 for (int i = 0; i < static_cast<int>(_red_maps.size()); ++i) { |
|
2695 std::map<std::string, int>::iterator jt = |
|
2696 maps.find(_red_maps[i].first); |
|
2697 if (jt == maps.end()) { |
|
2698 std::ostringstream msg; |
|
2699 msg << "Map not found: " << _red_maps[i].first; |
|
2700 throw FormatError(msg.str()); |
|
2701 } |
|
2702 map_index[i] = jt->second; |
|
2703 } |
|
2704 |
|
2705 { |
|
2706 std::map<std::string, int>::iterator jt = maps.find("label"); |
|
2707 if (jt != maps.end()) { |
|
2708 label_index = jt->second; |
|
2709 } else { |
|
2710 label_index = -1; |
|
2711 } |
|
2712 } |
|
2713 map_num = maps.size(); |
|
2714 } |
|
2715 |
|
2716 while (readLine() && line >> c && c != '@') { |
|
2717 line.putback(c); |
|
2718 |
|
2719 std::vector<std::string> tokens(map_num); |
|
2720 for (int i = 0; i < map_num; ++i) { |
|
2721 if (!_reader_bits::readToken(line, tokens[i])) { |
|
2722 std::ostringstream msg; |
|
2723 msg << "Column not found (" << i + 1 << ")"; |
|
2724 throw FormatError(msg.str()); |
|
2725 } |
|
2726 } |
|
2727 if (line >> std::ws >> c) |
|
2728 throw FormatError("Extra character at the end of line"); |
|
2729 |
|
2730 Node n; |
|
2731 if (!_use_nodes) { |
|
2732 n = _graph.addRedNode(); |
|
2733 if (label_index != -1) |
|
2734 _node_index.insert(std::make_pair(tokens[label_index], n)); |
|
2735 } else { |
|
2736 if (label_index == -1) |
|
2737 throw FormatError("Label map not found"); |
|
2738 typename std::map<std::string, Node>::iterator it = |
|
2739 _node_index.find(tokens[label_index]); |
|
2740 if (it == _node_index.end()) { |
|
2741 std::ostringstream msg; |
|
2742 msg << "Node with label not found: " << tokens[label_index]; |
|
2743 throw FormatError(msg.str()); |
|
2744 } |
|
2745 n = it->second; |
|
2746 } |
|
2747 |
|
2748 for (int i = 0; i < static_cast<int>(_red_maps.size()); ++i) { |
|
2749 _red_maps[i].second->set(n, tokens[map_index[i]]); |
|
2750 } |
|
2751 |
|
2752 } |
|
2753 if (readSuccess()) { |
|
2754 line.putback(c); |
|
2755 } |
|
2756 } |
|
2757 |
|
2758 void readBlueNodes() { |
|
2759 |
|
2760 std::vector<int> map_index(_blue_maps.size()); |
|
2761 int map_num, label_index; |
|
2762 |
|
2763 char c; |
|
2764 if (!readLine() || !(line >> c) || c == '@') { |
|
2765 if (readSuccess() && line) line.putback(c); |
|
2766 if (!_blue_maps.empty()) |
|
2767 throw FormatError("Cannot find map names"); |
|
2768 return; |
|
2769 } |
|
2770 line.putback(c); |
|
2771 |
|
2772 { |
|
2773 std::map<std::string, int> maps; |
|
2774 |
|
2775 std::string map; |
|
2776 int index = 0; |
|
2777 while (_reader_bits::readToken(line, map)) { |
|
2778 if (maps.find(map) != maps.end()) { |
|
2779 std::ostringstream msg; |
|
2780 msg << "Multiple occurence of blue map: " << map; |
|
2781 throw FormatError(msg.str()); |
|
2782 } |
|
2783 maps.insert(std::make_pair(map, index)); |
|
2784 ++index; |
|
2785 } |
|
2786 |
|
2787 for (int i = 0; i < static_cast<int>(_blue_maps.size()); ++i) { |
|
2788 std::map<std::string, int>::iterator jt = |
|
2789 maps.find(_blue_maps[i].first); |
|
2790 if (jt == maps.end()) { |
|
2791 std::ostringstream msg; |
|
2792 msg << "Map not found: " << _blue_maps[i].first; |
|
2793 throw FormatError(msg.str()); |
|
2794 } |
|
2795 map_index[i] = jt->second; |
|
2796 } |
|
2797 |
|
2798 { |
|
2799 std::map<std::string, int>::iterator jt = maps.find("label"); |
|
2800 if (jt != maps.end()) { |
|
2801 label_index = jt->second; |
|
2802 } else { |
|
2803 label_index = -1; |
|
2804 } |
|
2805 } |
|
2806 map_num = maps.size(); |
|
2807 } |
|
2808 |
|
2809 while (readLine() && line >> c && c != '@') { |
|
2810 line.putback(c); |
|
2811 |
|
2812 std::vector<std::string> tokens(map_num); |
|
2813 for (int i = 0; i < map_num; ++i) { |
|
2814 if (!_reader_bits::readToken(line, tokens[i])) { |
|
2815 std::ostringstream msg; |
|
2816 msg << "Column not found (" << i + 1 << ")"; |
|
2817 throw FormatError(msg.str()); |
|
2818 } |
|
2819 } |
|
2820 if (line >> std::ws >> c) |
|
2821 throw FormatError("Extra character at the end of line"); |
|
2822 |
|
2823 Node n; |
|
2824 if (!_use_nodes) { |
|
2825 n = _graph.addBlueNode(); |
|
2826 if (label_index != -1) |
|
2827 _node_index.insert(std::make_pair(tokens[label_index], n)); |
|
2828 } else { |
|
2829 if (label_index == -1) |
|
2830 throw FormatError("Label map not found"); |
|
2831 typename std::map<std::string, Node>::iterator it = |
|
2832 _node_index.find(tokens[label_index]); |
|
2833 if (it == _node_index.end()) { |
|
2834 std::ostringstream msg; |
|
2835 msg << "Node with label not found: " << tokens[label_index]; |
|
2836 throw FormatError(msg.str()); |
|
2837 } |
|
2838 n = it->second; |
|
2839 } |
|
2840 |
|
2841 for (int i = 0; i < static_cast<int>(_blue_maps.size()); ++i) { |
|
2842 _blue_maps[i].second->set(n, tokens[map_index[i]]); |
|
2843 } |
|
2844 |
|
2845 } |
|
2846 if (readSuccess()) { |
|
2847 line.putback(c); |
|
2848 } |
|
2849 } |
|
2850 |
|
2851 void readEdges() { |
|
2852 |
|
2853 std::vector<int> map_index(_edge_maps.size()); |
|
2854 int map_num, label_index; |
|
2855 |
|
2856 char c; |
|
2857 if (!readLine() || !(line >> c) || c == '@') { |
|
2858 if (readSuccess() && line) line.putback(c); |
|
2859 if (!_edge_maps.empty()) |
|
2860 throw FormatError("Cannot find map names"); |
|
2861 return; |
|
2862 } |
|
2863 line.putback(c); |
|
2864 |
|
2865 { |
|
2866 std::map<std::string, int> maps; |
|
2867 |
|
2868 std::string map; |
|
2869 int index = 0; |
|
2870 while (_reader_bits::readToken(line, map)) { |
|
2871 if (maps.find(map) != maps.end()) { |
|
2872 std::ostringstream msg; |
|
2873 msg << "Multiple occurence of edge map: " << map; |
|
2874 throw FormatError(msg.str()); |
|
2875 } |
|
2876 maps.insert(std::make_pair(map, index)); |
|
2877 ++index; |
|
2878 } |
|
2879 |
|
2880 for (int i = 0; i < static_cast<int>(_edge_maps.size()); ++i) { |
|
2881 std::map<std::string, int>::iterator jt = |
|
2882 maps.find(_edge_maps[i].first); |
|
2883 if (jt == maps.end()) { |
|
2884 std::ostringstream msg; |
|
2885 msg << "Map not found: " << _edge_maps[i].first; |
|
2886 throw FormatError(msg.str()); |
|
2887 } |
|
2888 map_index[i] = jt->second; |
|
2889 } |
|
2890 |
|
2891 { |
|
2892 std::map<std::string, int>::iterator jt = maps.find("label"); |
|
2893 if (jt != maps.end()) { |
|
2894 label_index = jt->second; |
|
2895 } else { |
|
2896 label_index = -1; |
|
2897 } |
|
2898 } |
|
2899 map_num = maps.size(); |
|
2900 } |
|
2901 |
|
2902 while (readLine() && line >> c && c != '@') { |
|
2903 line.putback(c); |
|
2904 |
|
2905 std::string source_token; |
|
2906 std::string target_token; |
|
2907 |
|
2908 if (!_reader_bits::readToken(line, source_token)) |
|
2909 throw FormatError("Red node not found"); |
|
2910 |
|
2911 if (!_reader_bits::readToken(line, target_token)) |
|
2912 throw FormatError("Blue node not found"); |
|
2913 |
|
2914 std::vector<std::string> tokens(map_num); |
|
2915 for (int i = 0; i < map_num; ++i) { |
|
2916 if (!_reader_bits::readToken(line, tokens[i])) { |
|
2917 std::ostringstream msg; |
|
2918 msg << "Column not found (" << i + 1 << ")"; |
|
2919 throw FormatError(msg.str()); |
|
2920 } |
|
2921 } |
|
2922 if (line >> std::ws >> c) |
|
2923 throw FormatError("Extra character at the end of line"); |
|
2924 |
|
2925 Edge e; |
|
2926 if (!_use_edges) { |
|
2927 |
|
2928 typename NodeIndex::iterator it; |
|
2929 |
|
2930 it = _node_index.find(source_token); |
|
2931 if (it == _node_index.end()) { |
|
2932 std::ostringstream msg; |
|
2933 msg << "Item not found: " << source_token; |
|
2934 throw FormatError(msg.str()); |
|
2935 } |
|
2936 Node source = it->second; |
|
2937 if (!_graph.red(source)) { |
|
2938 std::ostringstream msg; |
|
2939 msg << "Item is not red node: " << source_token; |
|
2940 throw FormatError(msg.str()); |
|
2941 } |
|
2942 |
|
2943 it = _node_index.find(target_token); |
|
2944 if (it == _node_index.end()) { |
|
2945 std::ostringstream msg; |
|
2946 msg << "Item not found: " << target_token; |
|
2947 throw FormatError(msg.str()); |
|
2948 } |
|
2949 Node target = it->second; |
|
2950 if (!_graph.blue(target)) { |
|
2951 std::ostringstream msg; |
|
2952 msg << "Item is not red node: " << source_token; |
|
2953 throw FormatError(msg.str()); |
|
2954 } |
|
2955 |
|
2956 e = _graph.addEdge(source, target); |
|
2957 if (label_index != -1) |
|
2958 _edge_index.insert(std::make_pair(tokens[label_index], e)); |
|
2959 } else { |
|
2960 if (label_index == -1) |
|
2961 throw FormatError("Label map not found"); |
|
2962 typename std::map<std::string, Edge>::iterator it = |
|
2963 _edge_index.find(tokens[label_index]); |
|
2964 if (it == _edge_index.end()) { |
|
2965 std::ostringstream msg; |
|
2966 msg << "Edge with label not found: " << tokens[label_index]; |
|
2967 throw FormatError(msg.str()); |
|
2968 } |
|
2969 e = it->second; |
|
2970 } |
|
2971 |
|
2972 for (int i = 0; i < static_cast<int>(_edge_maps.size()); ++i) { |
|
2973 _edge_maps[i].second->set(e, tokens[map_index[i]]); |
|
2974 } |
|
2975 |
|
2976 } |
|
2977 if (readSuccess()) { |
|
2978 line.putback(c); |
|
2979 } |
|
2980 } |
|
2981 |
|
2982 void readAttributes() { |
|
2983 |
|
2984 std::set<std::string> read_attr; |
|
2985 |
|
2986 char c; |
|
2987 while (readLine() && line >> c && c != '@') { |
|
2988 line.putback(c); |
|
2989 |
|
2990 std::string attr, token; |
|
2991 if (!_reader_bits::readToken(line, attr)) |
|
2992 throw FormatError("Attribute name not found"); |
|
2993 if (!_reader_bits::readToken(line, token)) |
|
2994 throw FormatError("Attribute value not found"); |
|
2995 if (line >> c) |
|
2996 throw FormatError("Extra character at the end of line"); |
|
2997 |
|
2998 { |
|
2999 std::set<std::string>::iterator it = read_attr.find(attr); |
|
3000 if (it != read_attr.end()) { |
|
3001 std::ostringstream msg; |
|
3002 msg << "Multiple occurence of attribute: " << attr; |
|
3003 throw FormatError(msg.str()); |
|
3004 } |
|
3005 read_attr.insert(attr); |
|
3006 } |
|
3007 |
|
3008 { |
|
3009 typename Attributes::iterator it = _attributes.lower_bound(attr); |
|
3010 while (it != _attributes.end() && it->first == attr) { |
|
3011 it->second->set(token); |
|
3012 ++it; |
|
3013 } |
|
3014 } |
|
3015 |
|
3016 } |
|
3017 if (readSuccess()) { |
|
3018 line.putback(c); |
|
3019 } |
|
3020 for (typename Attributes::iterator it = _attributes.begin(); |
|
3021 it != _attributes.end(); ++it) { |
|
3022 if (read_attr.find(it->first) == read_attr.end()) { |
|
3023 std::ostringstream msg; |
|
3024 msg << "Attribute not found: " << it->first; |
|
3025 throw FormatError(msg.str()); |
|
3026 } |
|
3027 } |
|
3028 } |
|
3029 |
|
3030 public: |
|
3031 |
|
3032 /// \name Execution of the Reader |
|
3033 /// @{ |
|
3034 |
|
3035 /// \brief Start the batch processing |
|
3036 /// |
|
3037 /// This function starts the batch processing |
|
3038 void run() { |
|
3039 |
|
3040 LEMON_ASSERT(_is != 0, "This reader assigned to an other reader"); |
|
3041 |
|
3042 bool red_nodes_done = _skip_nodes; |
|
3043 bool blue_nodes_done = _skip_nodes; |
|
3044 bool edges_done = _skip_edges; |
|
3045 bool attributes_done = false; |
|
3046 |
|
3047 line_num = 0; |
|
3048 readLine(); |
|
3049 skipSection(); |
|
3050 |
|
3051 while (readSuccess()) { |
|
3052 try { |
|
3053 char c; |
|
3054 std::string section, caption; |
|
3055 line >> c; |
|
3056 _reader_bits::readToken(line, section); |
|
3057 _reader_bits::readToken(line, caption); |
|
3058 |
|
3059 if (line >> c) |
|
3060 throw FormatError("Extra character at the end of line"); |
|
3061 |
|
3062 if (section == "red_nodes" && !red_nodes_done) { |
|
3063 if (_nodes_caption.empty() || _nodes_caption == caption) { |
|
3064 readRedNodes(); |
|
3065 red_nodes_done = true; |
|
3066 } |
|
3067 } else if (section == "blue_nodes" && !blue_nodes_done) { |
|
3068 if (_nodes_caption.empty() || _nodes_caption == caption) { |
|
3069 readBlueNodes(); |
|
3070 blue_nodes_done = true; |
|
3071 } |
|
3072 } else if ((section == "edges" || section == "arcs") && |
|
3073 !edges_done) { |
|
3074 if (_edges_caption.empty() || _edges_caption == caption) { |
|
3075 readEdges(); |
|
3076 edges_done = true; |
|
3077 } |
|
3078 } else if (section == "attributes" && !attributes_done) { |
|
3079 if (_attributes_caption.empty() || _attributes_caption == caption) { |
|
3080 readAttributes(); |
|
3081 attributes_done = true; |
|
3082 } |
|
3083 } else { |
|
3084 readLine(); |
|
3085 skipSection(); |
|
3086 } |
|
3087 } catch (FormatError& error) { |
|
3088 error.line(line_num); |
|
3089 error.file(_filename); |
|
3090 throw; |
|
3091 } |
|
3092 } |
|
3093 |
|
3094 if (!red_nodes_done) { |
|
3095 throw FormatError("Section @red_nodes not found"); |
|
3096 } |
|
3097 |
|
3098 if (!blue_nodes_done) { |
|
3099 throw FormatError("Section @blue_nodes not found"); |
|
3100 } |
|
3101 |
|
3102 if (!edges_done) { |
|
3103 throw FormatError("Section @edges not found"); |
|
3104 } |
|
3105 |
|
3106 if (!attributes_done && !_attributes.empty()) { |
|
3107 throw FormatError("Section @attributes not found"); |
|
3108 } |
|
3109 |
|
3110 } |
|
3111 |
|
3112 /// @} |
|
3113 |
|
3114 }; |
|
3115 |
|
3116 /// \ingroup lemon_io |
|
3117 /// |
|
3118 /// \brief Return a \ref BpGraphReader class |
|
3119 /// |
|
3120 /// This function just returns a \ref BpGraphReader class. |
|
3121 /// |
|
3122 /// With this function a graph can be read from an |
|
3123 /// \ref lgf-format "LGF" file or input stream with several maps and |
|
3124 /// attributes. For example, there is bipartite weighted matching problem |
|
3125 /// on a graph, i.e. a graph with a \e weight map on the edges. This |
|
3126 /// graph can be read with the following code: |
|
3127 /// |
|
3128 ///\code |
|
3129 ///ListBpGraph graph; |
|
3130 ///ListBpGraph::EdgeMap<int> weight(graph); |
|
3131 ///bpGraphReader(graph, std::cin). |
|
3132 /// edgeMap("weight", weight). |
|
3133 /// run(); |
|
3134 ///\endcode |
|
3135 /// |
|
3136 /// For a complete documentation, please see the \ref BpGraphReader |
|
3137 /// class documentation. |
|
3138 /// \warning Don't forget to put the \ref BpGraphReader::run() "run()" |
|
3139 /// to the end of the parameter list. |
|
3140 /// \relates BpGraphReader |
|
3141 /// \sa bpGraphReader(TBGR& graph, const std::string& fn) |
|
3142 /// \sa bpGraphReader(TBGR& graph, const char* fn) |
|
3143 template <typename TBGR> |
|
3144 BpGraphReader<TBGR> bpGraphReader(TBGR& graph, std::istream& is) { |
|
3145 BpGraphReader<TBGR> tmp(graph, is); |
|
3146 return tmp; |
|
3147 } |
|
3148 |
|
3149 /// \brief Return a \ref BpGraphReader class |
|
3150 /// |
|
3151 /// This function just returns a \ref BpGraphReader class. |
|
3152 /// \relates BpGraphReader |
|
3153 /// \sa bpGraphReader(TBGR& graph, std::istream& is) |
|
3154 template <typename TBGR> |
|
3155 BpGraphReader<TBGR> bpGraphReader(TBGR& graph, const std::string& fn) { |
|
3156 BpGraphReader<TBGR> tmp(graph, fn); |
|
3157 return tmp; |
|
3158 } |
|
3159 |
|
3160 /// \brief Return a \ref BpGraphReader class |
|
3161 /// |
|
3162 /// This function just returns a \ref BpGraphReader class. |
|
3163 /// \relates BpGraphReader |
|
3164 /// \sa bpGraphReader(TBGR& graph, std::istream& is) |
|
3165 template <typename TBGR> |
|
3166 BpGraphReader<TBGR> bpGraphReader(TBGR& graph, const char* fn) { |
|
3167 BpGraphReader<TBGR> tmp(graph, fn); |
|
3168 return tmp; |
|
3169 } |
|
3170 |
2131 class SectionReader; |
3171 class SectionReader; |
2132 |
3172 |
2133 SectionReader sectionReader(std::istream& is); |
3173 SectionReader sectionReader(std::istream& is); |
2134 SectionReader sectionReader(const std::string& fn); |
3174 SectionReader sectionReader(const std::string& fn); |
2135 SectionReader sectionReader(const char* fn); |
3175 SectionReader sectionReader(const char* fn); |