COIN-OR::LEMON - Graph Library

Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • lemon/lgf_reader.h

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