Changeset 1192:b84e68af8248 in lemon for lemon
- Timestamp:
- 11/25/10 22:45:29 (13 years ago)
- Branch:
- default
- Phase:
- public
- Location:
- lemon
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
lemon/full_graph.h
r1188 r1192 992 992 } 993 993 994 using Parent::redNode; 995 using Parent::blueNode; 996 994 997 /// \brief Returns the red node with the given index. 995 998 /// -
lemon/lgf_reader.h
r1110 r1192 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 3171 class SectionReader; 2132 3172 -
lemon/lgf_writer.h
r956 r1192 987 987 /// \ingroup lemon_io 988 988 /// 989 /// \brief \ref lgf-format "LGF" writer for directed graphs989 /// \brief \ref lgf-format "LGF" writer for undirected graphs 990 990 /// 991 991 /// This utility writes an \ref lgf-format "LGF" file. … … 1043 1043 /// \brief Constructor 1044 1044 /// 1045 /// Construct a directed graph writer, which writes to the given1046 /// output stream.1045 /// Construct an undirected graph writer, which writes to the 1046 /// given output stream. 1047 1047 GraphWriter(const GR& graph, std::ostream& os = std::cout) 1048 1048 : _os(&os), local_os(false), _graph(graph), … … 1051 1051 /// \brief Constructor 1052 1052 /// 1053 /// Construct a directed graph writer, which writes to the given1053 /// Construct a undirected graph writer, which writes to the given 1054 1054 /// output file. 1055 1055 GraphWriter(const GR& graph, const std::string& fn) … … 1064 1064 /// \brief Constructor 1065 1065 /// 1066 /// Construct a directed graph writer, which writes to the given1066 /// Construct a undirected graph writer, which writes to the given 1067 1067 /// output file. 1068 1068 GraphWriter(const GR& graph, const char* fn) … … 1290 1290 } 1291 1291 1292 /// \brief Add an additional caption to the \c \@ arcs section1293 /// 1294 /// Add an additional caption to the \c \@ arcs section.1292 /// \brief Add an additional caption to the \c \@edges section 1293 /// 1294 /// Add an additional caption to the \c \@edges section. 1295 1295 GraphWriter& edges(const std::string& caption) { 1296 1296 _edges_caption = caption; … … 1606 1606 GraphWriter<TGR> graphWriter(const TGR& graph, const char* fn) { 1607 1607 GraphWriter<TGR> tmp(graph, fn); 1608 return tmp; 1609 } 1610 1611 template <typename BGR> 1612 class BpGraphWriter; 1613 1614 template <typename TBGR> 1615 BpGraphWriter<TBGR> bpGraphWriter(const TBGR& graph, 1616 std::ostream& os = std::cout); 1617 template <typename TBGR> 1618 BpGraphWriter<TBGR> bpGraphWriter(const TBGR& graph, const std::string& fn); 1619 template <typename TBGR> 1620 BpGraphWriter<TBGR> bpGraphWriter(const TBGR& graph, const char* fn); 1621 1622 /// \ingroup lemon_io 1623 /// 1624 /// \brief \ref lgf-format "LGF" writer for undirected bipartite graphs 1625 /// 1626 /// This utility writes an \ref lgf-format "LGF" file. 1627 /// 1628 /// It can be used almost the same way as \c GraphWriter, but it 1629 /// reads the red and blue nodes from separate sections, and these 1630 /// sections can contain different set of maps. 1631 /// 1632 /// The red and blue maps are written to the corresponding 1633 /// sections. The node maps are written to both of these sections 1634 /// with the same map name. 1635 template <typename BGR> 1636 class BpGraphWriter { 1637 public: 1638 1639 typedef BGR BpGraph; 1640 TEMPLATE_BPGRAPH_TYPEDEFS(BGR); 1641 1642 private: 1643 1644 1645 std::ostream* _os; 1646 bool local_os; 1647 1648 const BGR& _graph; 1649 1650 std::string _nodes_caption; 1651 std::string _edges_caption; 1652 std::string _attributes_caption; 1653 1654 typedef std::map<Node, std::string> NodeIndex; 1655 NodeIndex _node_index; 1656 typedef std::map<Edge, std::string> EdgeIndex; 1657 EdgeIndex _edge_index; 1658 1659 typedef std::vector<std::pair<std::string, 1660 _writer_bits::MapStorageBase<Node>* > > NodeMaps; 1661 NodeMaps _red_maps; 1662 NodeMaps _blue_maps; 1663 1664 typedef std::vector<std::pair<std::string, 1665 _writer_bits::MapStorageBase<Edge>* > >EdgeMaps; 1666 EdgeMaps _edge_maps; 1667 1668 typedef std::vector<std::pair<std::string, 1669 _writer_bits::ValueStorageBase*> > Attributes; 1670 Attributes _attributes; 1671 1672 bool _skip_nodes; 1673 bool _skip_edges; 1674 1675 public: 1676 1677 /// \brief Constructor 1678 /// 1679 /// Construct a bipartite graph writer, which writes to the given 1680 /// output stream. 1681 BpGraphWriter(const BGR& graph, std::ostream& os = std::cout) 1682 : _os(&os), local_os(false), _graph(graph), 1683 _skip_nodes(false), _skip_edges(false) {} 1684 1685 /// \brief Constructor 1686 /// 1687 /// Construct a bipartite graph writer, which writes to the given 1688 /// output file. 1689 BpGraphWriter(const BGR& graph, const std::string& fn) 1690 : _os(new std::ofstream(fn.c_str())), local_os(true), _graph(graph), 1691 _skip_nodes(false), _skip_edges(false) { 1692 if (!(*_os)) { 1693 delete _os; 1694 throw IoError("Cannot write file", fn); 1695 } 1696 } 1697 1698 /// \brief Constructor 1699 /// 1700 /// Construct a bipartite graph writer, which writes to the given 1701 /// output file. 1702 BpGraphWriter(const BGR& graph, const char* fn) 1703 : _os(new std::ofstream(fn)), local_os(true), _graph(graph), 1704 _skip_nodes(false), _skip_edges(false) { 1705 if (!(*_os)) { 1706 delete _os; 1707 throw IoError("Cannot write file", fn); 1708 } 1709 } 1710 1711 /// \brief Destructor 1712 ~BpGraphWriter() { 1713 for (typename NodeMaps::iterator it = _red_maps.begin(); 1714 it != _red_maps.end(); ++it) { 1715 delete it->second; 1716 } 1717 1718 for (typename NodeMaps::iterator it = _blue_maps.begin(); 1719 it != _blue_maps.end(); ++it) { 1720 delete it->second; 1721 } 1722 1723 for (typename EdgeMaps::iterator it = _edge_maps.begin(); 1724 it != _edge_maps.end(); ++it) { 1725 delete it->second; 1726 } 1727 1728 for (typename Attributes::iterator it = _attributes.begin(); 1729 it != _attributes.end(); ++it) { 1730 delete it->second; 1731 } 1732 1733 if (local_os) { 1734 delete _os; 1735 } 1736 } 1737 1738 private: 1739 1740 template <typename TBGR> 1741 friend BpGraphWriter<TBGR> bpGraphWriter(const TBGR& graph, 1742 std::ostream& os); 1743 template <typename TBGR> 1744 friend BpGraphWriter<TBGR> bpGraphWriter(const TBGR& graph, 1745 const std::string& fn); 1746 template <typename TBGR> 1747 friend BpGraphWriter<TBGR> bpGraphWriter(const TBGR& graph, const char *fn); 1748 1749 BpGraphWriter(BpGraphWriter& other) 1750 : _os(other._os), local_os(other.local_os), _graph(other._graph), 1751 _skip_nodes(other._skip_nodes), _skip_edges(other._skip_edges) { 1752 1753 other._os = 0; 1754 other.local_os = false; 1755 1756 _node_index.swap(other._node_index); 1757 _edge_index.swap(other._edge_index); 1758 1759 _red_maps.swap(other._red_maps); 1760 _blue_maps.swap(other._blue_maps); 1761 _edge_maps.swap(other._edge_maps); 1762 _attributes.swap(other._attributes); 1763 1764 _nodes_caption = other._nodes_caption; 1765 _edges_caption = other._edges_caption; 1766 _attributes_caption = other._attributes_caption; 1767 } 1768 1769 BpGraphWriter& operator=(const BpGraphWriter&); 1770 1771 public: 1772 1773 /// \name Writing Rules 1774 /// @{ 1775 1776 /// \brief Node map writing rule 1777 /// 1778 /// Add a node map writing rule to the writer. 1779 template <typename Map> 1780 BpGraphWriter& nodeMap(const std::string& caption, const Map& map) { 1781 checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>(); 1782 _writer_bits::MapStorageBase<Node>* red_storage = 1783 new _writer_bits::MapStorage<Node, Map>(map); 1784 _red_maps.push_back(std::make_pair(caption, red_storage)); 1785 _writer_bits::MapStorageBase<Node>* blue_storage = 1786 new _writer_bits::MapStorage<Node, Map>(map); 1787 _blue_maps.push_back(std::make_pair(caption, blue_storage)); 1788 return *this; 1789 } 1790 1791 /// \brief Node map writing rule 1792 /// 1793 /// Add a node map writing rule with specialized converter to the 1794 /// writer. 1795 template <typename Map, typename Converter> 1796 BpGraphWriter& nodeMap(const std::string& caption, const Map& map, 1797 const Converter& converter = Converter()) { 1798 checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>(); 1799 _writer_bits::MapStorageBase<Node>* red_storage = 1800 new _writer_bits::MapStorage<Node, Map, Converter>(map, converter); 1801 _red_maps.push_back(std::make_pair(caption, red_storage)); 1802 _writer_bits::MapStorageBase<Node>* blue_storage = 1803 new _writer_bits::MapStorage<Node, Map, Converter>(map, converter); 1804 _blue_maps.push_back(std::make_pair(caption, blue_storage)); 1805 return *this; 1806 } 1807 1808 /// \brief Red map writing rule 1809 /// 1810 /// Add a red map writing rule to the writer. 1811 template <typename Map> 1812 BpGraphWriter& redMap(const std::string& caption, const Map& map) { 1813 checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>(); 1814 _writer_bits::MapStorageBase<Node>* storage = 1815 new _writer_bits::MapStorage<Node, Map>(map); 1816 _red_maps.push_back(std::make_pair(caption, storage)); 1817 return *this; 1818 } 1819 1820 /// \brief Red map writing rule 1821 /// 1822 /// Add a red map writing rule with specialized converter to the 1823 /// writer. 1824 template <typename Map, typename Converter> 1825 BpGraphWriter& redMap(const std::string& caption, const Map& map, 1826 const Converter& converter = Converter()) { 1827 checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>(); 1828 _writer_bits::MapStorageBase<Node>* storage = 1829 new _writer_bits::MapStorage<Node, Map, Converter>(map, converter); 1830 _red_maps.push_back(std::make_pair(caption, storage)); 1831 return *this; 1832 } 1833 1834 /// \brief Blue map writing rule 1835 /// 1836 /// Add a blue map writing rule to the writer. 1837 template <typename Map> 1838 BpGraphWriter& blueMap(const std::string& caption, const Map& map) { 1839 checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>(); 1840 _writer_bits::MapStorageBase<Node>* storage = 1841 new _writer_bits::MapStorage<Node, Map>(map); 1842 _blue_maps.push_back(std::make_pair(caption, storage)); 1843 return *this; 1844 } 1845 1846 /// \brief Blue map writing rule 1847 /// 1848 /// Add a blue map writing rule with specialized converter to the 1849 /// writer. 1850 template <typename Map, typename Converter> 1851 BpGraphWriter& blueMap(const std::string& caption, const Map& map, 1852 const Converter& converter = Converter()) { 1853 checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>(); 1854 _writer_bits::MapStorageBase<Node>* storage = 1855 new _writer_bits::MapStorage<Node, Map, Converter>(map, converter); 1856 _blue_maps.push_back(std::make_pair(caption, storage)); 1857 return *this; 1858 } 1859 1860 /// \brief Edge map writing rule 1861 /// 1862 /// Add an edge map writing rule to the writer. 1863 template <typename Map> 1864 BpGraphWriter& edgeMap(const std::string& caption, const Map& map) { 1865 checkConcept<concepts::ReadMap<Edge, typename Map::Value>, Map>(); 1866 _writer_bits::MapStorageBase<Edge>* storage = 1867 new _writer_bits::MapStorage<Edge, Map>(map); 1868 _edge_maps.push_back(std::make_pair(caption, storage)); 1869 return *this; 1870 } 1871 1872 /// \brief Edge map writing rule 1873 /// 1874 /// Add an edge map writing rule with specialized converter to the 1875 /// writer. 1876 template <typename Map, typename Converter> 1877 BpGraphWriter& edgeMap(const std::string& caption, const Map& map, 1878 const Converter& converter = Converter()) { 1879 checkConcept<concepts::ReadMap<Edge, typename Map::Value>, Map>(); 1880 _writer_bits::MapStorageBase<Edge>* storage = 1881 new _writer_bits::MapStorage<Edge, Map, Converter>(map, converter); 1882 _edge_maps.push_back(std::make_pair(caption, storage)); 1883 return *this; 1884 } 1885 1886 /// \brief Arc map writing rule 1887 /// 1888 /// Add an arc map writing rule to the writer. 1889 template <typename Map> 1890 BpGraphWriter& arcMap(const std::string& caption, const Map& map) { 1891 checkConcept<concepts::ReadMap<Arc, typename Map::Value>, Map>(); 1892 _writer_bits::MapStorageBase<Edge>* forward_storage = 1893 new _writer_bits::GraphArcMapStorage<BGR, true, Map>(_graph, map); 1894 _edge_maps.push_back(std::make_pair('+' + caption, forward_storage)); 1895 _writer_bits::MapStorageBase<Edge>* backward_storage = 1896 new _writer_bits::GraphArcMapStorage<BGR, false, Map>(_graph, map); 1897 _edge_maps.push_back(std::make_pair('-' + caption, backward_storage)); 1898 return *this; 1899 } 1900 1901 /// \brief Arc map writing rule 1902 /// 1903 /// Add an arc map writing rule with specialized converter to the 1904 /// writer. 1905 template <typename Map, typename Converter> 1906 BpGraphWriter& arcMap(const std::string& caption, const Map& map, 1907 const Converter& converter = Converter()) { 1908 checkConcept<concepts::ReadMap<Arc, typename Map::Value>, Map>(); 1909 _writer_bits::MapStorageBase<Edge>* forward_storage = 1910 new _writer_bits::GraphArcMapStorage<BGR, true, Map, Converter> 1911 (_graph, map, converter); 1912 _edge_maps.push_back(std::make_pair('+' + caption, forward_storage)); 1913 _writer_bits::MapStorageBase<Edge>* backward_storage = 1914 new _writer_bits::GraphArcMapStorage<BGR, false, Map, Converter> 1915 (_graph, map, converter); 1916 _edge_maps.push_back(std::make_pair('-' + caption, backward_storage)); 1917 return *this; 1918 } 1919 1920 /// \brief Attribute writing rule 1921 /// 1922 /// Add an attribute writing rule to the writer. 1923 template <typename Value> 1924 BpGraphWriter& attribute(const std::string& caption, const Value& value) { 1925 _writer_bits::ValueStorageBase* storage = 1926 new _writer_bits::ValueStorage<Value>(value); 1927 _attributes.push_back(std::make_pair(caption, storage)); 1928 return *this; 1929 } 1930 1931 /// \brief Attribute writing rule 1932 /// 1933 /// Add an attribute writing rule with specialized converter to the 1934 /// writer. 1935 template <typename Value, typename Converter> 1936 BpGraphWriter& attribute(const std::string& caption, const Value& value, 1937 const Converter& converter = Converter()) { 1938 _writer_bits::ValueStorageBase* storage = 1939 new _writer_bits::ValueStorage<Value, Converter>(value, converter); 1940 _attributes.push_back(std::make_pair(caption, storage)); 1941 return *this; 1942 } 1943 1944 /// \brief Node writing rule 1945 /// 1946 /// Add a node writing rule to the writer. 1947 BpGraphWriter& node(const std::string& caption, const Node& node) { 1948 typedef _writer_bits::MapLookUpConverter<Node> Converter; 1949 Converter converter(_node_index); 1950 _writer_bits::ValueStorageBase* storage = 1951 new _writer_bits::ValueStorage<Node, Converter>(node, converter); 1952 _attributes.push_back(std::make_pair(caption, storage)); 1953 return *this; 1954 } 1955 1956 /// \brief Edge writing rule 1957 /// 1958 /// Add an edge writing rule to writer. 1959 BpGraphWriter& edge(const std::string& caption, const Edge& edge) { 1960 typedef _writer_bits::MapLookUpConverter<Edge> Converter; 1961 Converter converter(_edge_index); 1962 _writer_bits::ValueStorageBase* storage = 1963 new _writer_bits::ValueStorage<Edge, Converter>(edge, converter); 1964 _attributes.push_back(std::make_pair(caption, storage)); 1965 return *this; 1966 } 1967 1968 /// \brief Arc writing rule 1969 /// 1970 /// Add an arc writing rule to writer. 1971 BpGraphWriter& arc(const std::string& caption, const Arc& arc) { 1972 typedef _writer_bits::GraphArcLookUpConverter<BGR> Converter; 1973 Converter converter(_graph, _edge_index); 1974 _writer_bits::ValueStorageBase* storage = 1975 new _writer_bits::ValueStorage<Arc, Converter>(arc, converter); 1976 _attributes.push_back(std::make_pair(caption, storage)); 1977 return *this; 1978 } 1979 1980 /// \name Section Captions 1981 /// @{ 1982 1983 /// \brief Add an additional caption to the \c \@red_nodes and 1984 /// \c \@blue_nodes section 1985 /// 1986 /// Add an additional caption to the \c \@red_nodes and \c 1987 /// \@blue_nodes section. 1988 BpGraphWriter& nodes(const std::string& caption) { 1989 _nodes_caption = caption; 1990 return *this; 1991 } 1992 1993 /// \brief Add an additional caption to the \c \@edges section 1994 /// 1995 /// Add an additional caption to the \c \@edges section. 1996 BpGraphWriter& edges(const std::string& caption) { 1997 _edges_caption = caption; 1998 return *this; 1999 } 2000 2001 /// \brief Add an additional caption to the \c \@attributes section 2002 /// 2003 /// Add an additional caption to the \c \@attributes section. 2004 BpGraphWriter& attributes(const std::string& caption) { 2005 _attributes_caption = caption; 2006 return *this; 2007 } 2008 2009 /// \name Skipping Section 2010 /// @{ 2011 2012 /// \brief Skip writing the node set 2013 /// 2014 /// The \c \@red_nodes and \c \@blue_nodes section will not be 2015 /// written to the stream. 2016 BpGraphWriter& skipNodes() { 2017 LEMON_ASSERT(!_skip_nodes, "Multiple usage of skipNodes() member"); 2018 _skip_nodes = true; 2019 return *this; 2020 } 2021 2022 /// \brief Skip writing edge set 2023 /// 2024 /// The \c \@edges section will not be written to the stream. 2025 BpGraphWriter& skipEdges() { 2026 LEMON_ASSERT(!_skip_edges, "Multiple usage of skipEdges() member"); 2027 _skip_edges = true; 2028 return *this; 2029 } 2030 2031 /// @} 2032 2033 private: 2034 2035 void writeRedNodes() { 2036 _writer_bits::MapStorageBase<Node>* label = 0; 2037 for (typename NodeMaps::iterator it = _red_maps.begin(); 2038 it != _red_maps.end(); ++it) { 2039 if (it->first == "label") { 2040 label = it->second; 2041 break; 2042 } 2043 } 2044 2045 *_os << "@red_nodes"; 2046 if (!_nodes_caption.empty()) { 2047 _writer_bits::writeToken(*_os << ' ', _nodes_caption); 2048 } 2049 *_os << std::endl; 2050 2051 if (label == 0) { 2052 *_os << "label" << '\t'; 2053 } 2054 for (typename NodeMaps::iterator it = _red_maps.begin(); 2055 it != _red_maps.end(); ++it) { 2056 _writer_bits::writeToken(*_os, it->first) << '\t'; 2057 } 2058 *_os << std::endl; 2059 2060 std::vector<Node> nodes; 2061 for (RedIt n(_graph); n != INVALID; ++n) { 2062 nodes.push_back(n); 2063 } 2064 2065 if (label == 0) { 2066 IdMap<BGR, Node> id_map(_graph); 2067 _writer_bits::MapLess<IdMap<BGR, Node> > id_less(id_map); 2068 std::sort(nodes.begin(), nodes.end(), id_less); 2069 } else { 2070 label->sort(nodes); 2071 } 2072 2073 for (int i = 0; i < static_cast<int>(nodes.size()); ++i) { 2074 Node n = nodes[i]; 2075 if (label == 0) { 2076 std::ostringstream os; 2077 os << _graph.id(n); 2078 _writer_bits::writeToken(*_os, os.str()); 2079 *_os << '\t'; 2080 _node_index.insert(std::make_pair(n, os.str())); 2081 } 2082 for (typename NodeMaps::iterator it = _red_maps.begin(); 2083 it != _red_maps.end(); ++it) { 2084 std::string value = it->second->get(n); 2085 _writer_bits::writeToken(*_os, value); 2086 if (it->first == "label") { 2087 _node_index.insert(std::make_pair(n, value)); 2088 } 2089 *_os << '\t'; 2090 } 2091 *_os << std::endl; 2092 } 2093 } 2094 2095 void writeBlueNodes() { 2096 _writer_bits::MapStorageBase<Node>* label = 0; 2097 for (typename NodeMaps::iterator it = _blue_maps.begin(); 2098 it != _blue_maps.end(); ++it) { 2099 if (it->first == "label") { 2100 label = it->second; 2101 break; 2102 } 2103 } 2104 2105 *_os << "@blue_nodes"; 2106 if (!_nodes_caption.empty()) { 2107 _writer_bits::writeToken(*_os << ' ', _nodes_caption); 2108 } 2109 *_os << std::endl; 2110 2111 if (label == 0) { 2112 *_os << "label" << '\t'; 2113 } 2114 for (typename NodeMaps::iterator it = _blue_maps.begin(); 2115 it != _blue_maps.end(); ++it) { 2116 _writer_bits::writeToken(*_os, it->first) << '\t'; 2117 } 2118 *_os << std::endl; 2119 2120 std::vector<Node> nodes; 2121 for (BlueIt n(_graph); n != INVALID; ++n) { 2122 nodes.push_back(n); 2123 } 2124 2125 if (label == 0) { 2126 IdMap<BGR, Node> id_map(_graph); 2127 _writer_bits::MapLess<IdMap<BGR, Node> > id_less(id_map); 2128 std::sort(nodes.begin(), nodes.end(), id_less); 2129 } else { 2130 label->sort(nodes); 2131 } 2132 2133 for (int i = 0; i < static_cast<int>(nodes.size()); ++i) { 2134 Node n = nodes[i]; 2135 if (label == 0) { 2136 std::ostringstream os; 2137 os << _graph.id(n); 2138 _writer_bits::writeToken(*_os, os.str()); 2139 *_os << '\t'; 2140 _node_index.insert(std::make_pair(n, os.str())); 2141 } 2142 for (typename NodeMaps::iterator it = _blue_maps.begin(); 2143 it != _blue_maps.end(); ++it) { 2144 std::string value = it->second->get(n); 2145 _writer_bits::writeToken(*_os, value); 2146 if (it->first == "label") { 2147 _node_index.insert(std::make_pair(n, value)); 2148 } 2149 *_os << '\t'; 2150 } 2151 *_os << std::endl; 2152 } 2153 } 2154 2155 void createRedNodeIndex() { 2156 _writer_bits::MapStorageBase<Node>* label = 0; 2157 for (typename NodeMaps::iterator it = _red_maps.begin(); 2158 it != _red_maps.end(); ++it) { 2159 if (it->first == "label") { 2160 label = it->second; 2161 break; 2162 } 2163 } 2164 2165 if (label == 0) { 2166 for (NodeIt n(_graph); n != INVALID; ++n) { 2167 std::ostringstream os; 2168 os << _graph.id(n); 2169 _node_index.insert(std::make_pair(n, os.str())); 2170 } 2171 } else { 2172 for (NodeIt n(_graph); n != INVALID; ++n) { 2173 std::string value = label->get(n); 2174 _node_index.insert(std::make_pair(n, value)); 2175 } 2176 } 2177 } 2178 2179 void createBlueNodeIndex() { 2180 _writer_bits::MapStorageBase<Node>* label = 0; 2181 for (typename NodeMaps::iterator it = _blue_maps.begin(); 2182 it != _blue_maps.end(); ++it) { 2183 if (it->first == "label") { 2184 label = it->second; 2185 break; 2186 } 2187 } 2188 2189 if (label == 0) { 2190 for (NodeIt n(_graph); n != INVALID; ++n) { 2191 std::ostringstream os; 2192 os << _graph.id(n); 2193 _node_index.insert(std::make_pair(n, os.str())); 2194 } 2195 } else { 2196 for (NodeIt n(_graph); n != INVALID; ++n) { 2197 std::string value = label->get(n); 2198 _node_index.insert(std::make_pair(n, value)); 2199 } 2200 } 2201 } 2202 2203 void writeEdges() { 2204 _writer_bits::MapStorageBase<Edge>* label = 0; 2205 for (typename EdgeMaps::iterator it = _edge_maps.begin(); 2206 it != _edge_maps.end(); ++it) { 2207 if (it->first == "label") { 2208 label = it->second; 2209 break; 2210 } 2211 } 2212 2213 *_os << "@edges"; 2214 if (!_edges_caption.empty()) { 2215 _writer_bits::writeToken(*_os << ' ', _edges_caption); 2216 } 2217 *_os << std::endl; 2218 2219 *_os << '\t' << '\t'; 2220 if (label == 0) { 2221 *_os << "label" << '\t'; 2222 } 2223 for (typename EdgeMaps::iterator it = _edge_maps.begin(); 2224 it != _edge_maps.end(); ++it) { 2225 _writer_bits::writeToken(*_os, it->first) << '\t'; 2226 } 2227 *_os << std::endl; 2228 2229 std::vector<Edge> edges; 2230 for (EdgeIt n(_graph); n != INVALID; ++n) { 2231 edges.push_back(n); 2232 } 2233 2234 if (label == 0) { 2235 IdMap<BGR, Edge> id_map(_graph); 2236 _writer_bits::MapLess<IdMap<BGR, Edge> > id_less(id_map); 2237 std::sort(edges.begin(), edges.end(), id_less); 2238 } else { 2239 label->sort(edges); 2240 } 2241 2242 for (int i = 0; i < static_cast<int>(edges.size()); ++i) { 2243 Edge e = edges[i]; 2244 _writer_bits::writeToken(*_os, _node_index. 2245 find(_graph.redNode(e))->second); 2246 *_os << '\t'; 2247 _writer_bits::writeToken(*_os, _node_index. 2248 find(_graph.blueNode(e))->second); 2249 *_os << '\t'; 2250 if (label == 0) { 2251 std::ostringstream os; 2252 os << _graph.id(e); 2253 _writer_bits::writeToken(*_os, os.str()); 2254 *_os << '\t'; 2255 _edge_index.insert(std::make_pair(e, os.str())); 2256 } 2257 for (typename EdgeMaps::iterator it = _edge_maps.begin(); 2258 it != _edge_maps.end(); ++it) { 2259 std::string value = it->second->get(e); 2260 _writer_bits::writeToken(*_os, value); 2261 if (it->first == "label") { 2262 _edge_index.insert(std::make_pair(e, value)); 2263 } 2264 *_os << '\t'; 2265 } 2266 *_os << std::endl; 2267 } 2268 } 2269 2270 void createEdgeIndex() { 2271 _writer_bits::MapStorageBase<Edge>* label = 0; 2272 for (typename EdgeMaps::iterator it = _edge_maps.begin(); 2273 it != _edge_maps.end(); ++it) { 2274 if (it->first == "label") { 2275 label = it->second; 2276 break; 2277 } 2278 } 2279 2280 if (label == 0) { 2281 for (EdgeIt e(_graph); e != INVALID; ++e) { 2282 std::ostringstream os; 2283 os << _graph.id(e); 2284 _edge_index.insert(std::make_pair(e, os.str())); 2285 } 2286 } else { 2287 for (EdgeIt e(_graph); e != INVALID; ++e) { 2288 std::string value = label->get(e); 2289 _edge_index.insert(std::make_pair(e, value)); 2290 } 2291 } 2292 } 2293 2294 void writeAttributes() { 2295 if (_attributes.empty()) return; 2296 *_os << "@attributes"; 2297 if (!_attributes_caption.empty()) { 2298 _writer_bits::writeToken(*_os << ' ', _attributes_caption); 2299 } 2300 *_os << std::endl; 2301 for (typename Attributes::iterator it = _attributes.begin(); 2302 it != _attributes.end(); ++it) { 2303 _writer_bits::writeToken(*_os, it->first) << ' '; 2304 _writer_bits::writeToken(*_os, it->second->get()); 2305 *_os << std::endl; 2306 } 2307 } 2308 2309 public: 2310 2311 /// \name Execution of the Writer 2312 /// @{ 2313 2314 /// \brief Start the batch processing 2315 /// 2316 /// This function starts the batch processing. 2317 void run() { 2318 if (!_skip_nodes) { 2319 writeRedNodes(); 2320 writeBlueNodes(); 2321 } else { 2322 createRedNodeIndex(); 2323 createBlueNodeIndex(); 2324 } 2325 if (!_skip_edges) { 2326 writeEdges(); 2327 } else { 2328 createEdgeIndex(); 2329 } 2330 writeAttributes(); 2331 } 2332 2333 /// \brief Give back the stream of the writer 2334 /// 2335 /// Give back the stream of the writer 2336 std::ostream& ostream() { 2337 return *_os; 2338 } 2339 2340 /// @} 2341 }; 2342 2343 /// \ingroup lemon_io 2344 /// 2345 /// \brief Return a \ref BpGraphWriter class 2346 /// 2347 /// This function just returns a \ref BpGraphWriter class. 2348 /// 2349 /// With this function a bipartite graph can be write to a file or output 2350 /// stream in \ref lgf-format "LGF" format with several maps and 2351 /// attributes. For example, with the following code a bipartite 2352 /// weighted matching problem can be written to the standard output, 2353 /// i.e. a graph with a \e weight map on the edges: 2354 /// 2355 ///\code 2356 ///ListBpGraph graph; 2357 ///ListBpGraph::EdgeMap<int> weight(graph); 2358 /// // Setting the weight map 2359 ///bpGraphWriter(graph, std::cout). 2360 /// edgeMap("weight", weight). 2361 /// run(); 2362 ///\endcode 2363 /// 2364 /// For a complete documentation, please see the \ref BpGraphWriter 2365 /// class documentation. 2366 /// \warning Don't forget to put the \ref BpGraphWriter::run() "run()" 2367 /// to the end of the parameter list. 2368 /// \relates BpGraphWriter 2369 /// \sa bpGraphWriter(const TBGR& graph, const std::string& fn) 2370 /// \sa bpGraphWriter(const TBGR& graph, const char* fn) 2371 template <typename TBGR> 2372 BpGraphWriter<TBGR> bpGraphWriter(const TBGR& graph, std::ostream& os) { 2373 BpGraphWriter<TBGR> tmp(graph, os); 2374 return tmp; 2375 } 2376 2377 /// \brief Return a \ref BpGraphWriter class 2378 /// 2379 /// This function just returns a \ref BpGraphWriter class. 2380 /// \relates BpGraphWriter 2381 /// \sa graphWriter(const TBGR& graph, std::ostream& os) 2382 template <typename TBGR> 2383 BpGraphWriter<TBGR> bpGraphWriter(const TBGR& graph, const std::string& fn) { 2384 BpGraphWriter<TBGR> tmp(graph, fn); 2385 return tmp; 2386 } 2387 2388 /// \brief Return a \ref BpGraphWriter class 2389 /// 2390 /// This function just returns a \ref BpGraphWriter class. 2391 /// \relates BpGraphWriter 2392 /// \sa graphWriter(const TBGR& graph, std::ostream& os) 2393 template <typename TBGR> 2394 BpGraphWriter<TBGR> bpGraphWriter(const TBGR& graph, const char* fn) { 2395 BpGraphWriter<TBGR> tmp(graph, fn); 1608 2396 return tmp; 1609 2397 }
Note: See TracChangeset
for help on using the changeset viewer.