Changeset 1024:b84e68af8248 in lemon-main
- Timestamp:
- 11/25/10 22:45:29 (14 years ago)
- Branch:
- default
- Phase:
- public
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
doc/lgf.dox
r950 r1024 64 64 \endcode 65 65 66 The \c \@arcs section is very similar to the \c \@nodes section, it 67 again starts with a header line describing the names of the maps, but 68 the \c "label" map is not obligatory here. The following lines 69 describe the arcs. The first two tokens of each line are the source 70 and the target node of the arc, respectively, then come the map 66 The \e LGF files can also contain bipartite graphs, in this case a 67 \c @red_nodes and a \c @blue_nodes sections describe the node set of the 68 graph. If a map is in both of these sections, then it can be used as a 69 regular node map. 70 71 \code 72 @red_nodes 73 label only_red_map name 74 1 "cherry" "John" 75 2 "Santa Claus" "Jack" 76 3 "blood" "Jason" 77 @blue_nodes 78 label name 79 4 "Elisabeth" 80 5 "Eve" 81 \endcode 82 83 The \c \@arcs section is very similar to the \c \@nodes section, 84 it again starts with a header line describing the names of the maps, 85 but the \c "label" map is not obligatory here. The following lines 86 describe the arcs. The first two tokens of each line are 87 the source and the target node of the arc, respectively, then come the map 71 88 values. The source and target tokens must be node labels. 72 89 -
lemon/full_graph.h
r1020 r1024 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
r966 r1024 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
r877 r1024 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.