[Lemon-commits] Balazs Dezso: LGF reader and writer for bipartit...

Lemon HG hg at lemon.cs.elte.hu
Fri Mar 1 17:49:47 CET 2013


details:   http://lemon.cs.elte.hu/hg/lemon/rev/b84e68af8248
changeset: 1192:b84e68af8248
user:      Balazs Dezso <deba [at] inf.elte.hu>
date:      Thu Nov 25 22:45:29 2010 +0100
description:
	LGF reader and writer for bipartite graphs (#69)

diffstat:

 doc/lgf.dox        |    27 +-
 lemon/full_graph.h |     3 +
 lemon/lgf_reader.h |  1040 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 lemon/lgf_writer.h |   802 +++++++++++++++++++++++++++++++++++++++-
 4 files changed, 1860 insertions(+), 12 deletions(-)

diffs (truncated from 1947 to 300 lines):

diff --git a/doc/lgf.dox b/doc/lgf.dox
--- a/doc/lgf.dox
+++ b/doc/lgf.dox
@@ -63,11 +63,28 @@
  3      (40,10)      10      "Third node"
 \endcode
 
-The \c \@arcs section is very similar to the \c \@nodes section, it
-again starts with a header line describing the names of the maps, but
-the \c "label" map is not obligatory here. The following lines
-describe the arcs. The first two tokens of each line are the source
-and the target node of the arc, respectively, then come the map
+The \e LGF files can also contain bipartite graphs, in this case a
+\c @red_nodes and a \c @blue_nodes sections describe the node set of the
+graph. If a map is in both of these sections, then it can be used as a
+regular node map.
+
+\code
+ @red_nodes
+ label  only_red_map   name
+ 1      "cherry"       "John"
+ 2      "Santa Claus"  "Jack"
+ 3      "blood"        "Jason"
+ @blue_nodes
+ label  name
+ 4      "Elisabeth"
+ 5      "Eve"
+\endcode
+
+The \c \@arcs section is very similar to the \c \@nodes section,
+it again starts with a header line describing the names of the maps,
+but the \c "label" map is not obligatory here. The following lines
+describe the arcs. The first two tokens of each line are
+the source and the target node of the arc, respectively, then come the map
 values. The source and target tokens must be node labels.
 
 \code
diff --git a/lemon/full_graph.h b/lemon/full_graph.h
--- a/lemon/full_graph.h
+++ b/lemon/full_graph.h
@@ -991,6 +991,9 @@
       Parent::notifier(Arc()).build();
     }
 
+    using Parent::redNode;
+    using Parent::blueNode;
+
     /// \brief Returns the red node with the given index.
     ///
     /// Returns the red node with the given index. Since this
diff --git a/lemon/lgf_reader.h b/lemon/lgf_reader.h
--- a/lemon/lgf_reader.h
+++ b/lemon/lgf_reader.h
@@ -2128,6 +2128,1046 @@
     return tmp;
   }
 
+  template <typename BGR>
+  class BpGraphReader;
+
+  template <typename TBGR>
+  BpGraphReader<TBGR> bpGraphReader(TBGR& graph, std::istream& is = std::cin);
+  template <typename TBGR>
+  BpGraphReader<TBGR> bpGraphReader(TBGR& graph, const std::string& fn);
+  template <typename TBGR>
+  BpGraphReader<TBGR> bpGraphReader(TBGR& graph, const char *fn);
+
+  /// \ingroup lemon_io
+  ///
+  /// \brief \ref lgf-format "LGF" reader for bipartite graphs
+  ///
+  /// This utility reads an \ref lgf-format "LGF" file.
+  ///
+  /// It can be used almost the same way as \c GraphReader, but it
+  /// reads the red and blue nodes from separate sections, and these
+  /// sections can contain different set of maps.
+  ///
+  /// The red and blue maps are read from the corresponding
+  /// sections. If a map is defined with the same name in both of
+  /// these sections, then it can be read as a node map.
+  template <typename BGR>
+  class BpGraphReader {
+  public:
+
+    typedef BGR Graph;
+
+  private:
+
+    TEMPLATE_BPGRAPH_TYPEDEFS(BGR);
+
+    std::istream* _is;
+    bool local_is;
+    std::string _filename;
+
+    BGR& _graph;
+
+    std::string _nodes_caption;
+    std::string _edges_caption;
+    std::string _attributes_caption;
+
+    typedef std::map<std::string, Node> NodeIndex;
+    NodeIndex _node_index;
+    typedef std::map<std::string, Edge> EdgeIndex;
+    EdgeIndex _edge_index;
+
+    typedef std::vector<std::pair<std::string,
+      _reader_bits::MapStorageBase<Node>*> > NodeMaps;
+    NodeMaps _red_maps;
+    NodeMaps _blue_maps;
+
+    typedef std::vector<std::pair<std::string,
+      _reader_bits::MapStorageBase<Edge>*> > EdgeMaps;
+    EdgeMaps _edge_maps;
+
+    typedef std::multimap<std::string, _reader_bits::ValueStorageBase*>
+      Attributes;
+    Attributes _attributes;
+
+    bool _use_nodes;
+    bool _use_edges;
+
+    bool _skip_nodes;
+    bool _skip_edges;
+
+    int line_num;
+    std::istringstream line;
+
+  public:
+
+    /// \brief Constructor
+    ///
+    /// Construct an undirected graph reader, which reads from the given
+    /// input stream.
+    BpGraphReader(BGR& graph, std::istream& is = std::cin)
+      : _is(&is), local_is(false), _graph(graph),
+        _use_nodes(false), _use_edges(false),
+        _skip_nodes(false), _skip_edges(false) {}
+
+    /// \brief Constructor
+    ///
+    /// Construct an undirected graph reader, which reads from the given
+    /// file.
+    BpGraphReader(BGR& graph, const std::string& fn)
+      : _is(new std::ifstream(fn.c_str())), local_is(true),
+        _filename(fn), _graph(graph),
+        _use_nodes(false), _use_edges(false),
+        _skip_nodes(false), _skip_edges(false) {
+      if (!(*_is)) {
+        delete _is;
+        throw IoError("Cannot open file", fn);
+      }
+    }
+
+    /// \brief Constructor
+    ///
+    /// Construct an undirected graph reader, which reads from the given
+    /// file.
+    BpGraphReader(BGR& graph, const char* fn)
+      : _is(new std::ifstream(fn)), local_is(true),
+        _filename(fn), _graph(graph),
+        _use_nodes(false), _use_edges(false),
+        _skip_nodes(false), _skip_edges(false) {
+      if (!(*_is)) {
+        delete _is;
+        throw IoError("Cannot open file", fn);
+      }
+    }
+
+    /// \brief Destructor
+    ~BpGraphReader() {
+      for (typename NodeMaps::iterator it = _red_maps.begin();
+           it != _red_maps.end(); ++it) {
+        delete it->second;
+      }
+
+      for (typename NodeMaps::iterator it = _blue_maps.begin();
+           it != _blue_maps.end(); ++it) {
+        delete it->second;
+      }
+
+      for (typename EdgeMaps::iterator it = _edge_maps.begin();
+           it != _edge_maps.end(); ++it) {
+        delete it->second;
+      }
+
+      for (typename Attributes::iterator it = _attributes.begin();
+           it != _attributes.end(); ++it) {
+        delete it->second;
+      }
+
+      if (local_is) {
+        delete _is;
+      }
+
+    }
+
+  private:
+    template <typename TBGR>
+    friend BpGraphReader<TBGR> bpGraphReader(TBGR& graph, std::istream& is);
+    template <typename TBGR>
+    friend BpGraphReader<TBGR> bpGraphReader(TBGR& graph,
+                                             const std::string& fn);
+    template <typename TBGR>
+    friend BpGraphReader<TBGR> bpGraphReader(TBGR& graph, const char *fn);
+
+    BpGraphReader(BpGraphReader& other)
+      : _is(other._is), local_is(other.local_is), _graph(other._graph),
+        _use_nodes(other._use_nodes), _use_edges(other._use_edges),
+        _skip_nodes(other._skip_nodes), _skip_edges(other._skip_edges) {
+
+      other._is = 0;
+      other.local_is = false;
+
+      _node_index.swap(other._node_index);
+      _edge_index.swap(other._edge_index);
+
+      _red_maps.swap(other._red_maps);
+      _blue_maps.swap(other._blue_maps);
+      _edge_maps.swap(other._edge_maps);
+      _attributes.swap(other._attributes);
+
+      _nodes_caption = other._nodes_caption;
+      _edges_caption = other._edges_caption;
+      _attributes_caption = other._attributes_caption;
+
+    }
+
+    BpGraphReader& operator=(const BpGraphReader&);
+
+  public:
+
+    /// \name Reading Rules
+    /// @{
+
+    /// \brief Node map reading rule
+    ///
+    /// Add a node map reading rule to the reader.
+    template <typename Map>
+    BpGraphReader& nodeMap(const std::string& caption, Map& map) {
+      checkConcept<concepts::WriteMap<Node, typename Map::Value>, Map>();
+      _reader_bits::MapStorageBase<Node>* red_storage =
+        new _reader_bits::MapStorage<Node, Map>(map);
+      _red_maps.push_back(std::make_pair(caption, red_storage));
+      _reader_bits::MapStorageBase<Node>* blue_storage =
+        new _reader_bits::MapStorage<Node, Map>(map);
+      _blue_maps.push_back(std::make_pair(caption, blue_storage));
+      return *this;
+    }
+
+    /// \brief Node map reading rule
+    ///
+    /// Add a node map reading rule with specialized converter to the
+    /// reader.
+    template <typename Map, typename Converter>
+    BpGraphReader& nodeMap(const std::string& caption, Map& map,
+                           const Converter& converter = Converter()) {
+      checkConcept<concepts::WriteMap<Node, typename Map::Value>, Map>();
+      _reader_bits::MapStorageBase<Node>* red_storage =
+        new _reader_bits::MapStorage<Node, Map, Converter>(map, converter);
+      _red_maps.push_back(std::make_pair(caption, red_storage));
+      _reader_bits::MapStorageBase<Node>* blue_storage =
+        new _reader_bits::MapStorage<Node, Map, Converter>(map, converter);
+      _blue_maps.push_back(std::make_pair(caption, blue_storage));
+      return *this;
+    }
+
+    /// Add a red map reading rule to the reader.
+    template <typename Map>
+    BpGraphReader& redMap(const std::string& caption, Map& map) {
+      checkConcept<concepts::WriteMap<Node, typename Map::Value>, Map>();
+      _reader_bits::MapStorageBase<Node>* storage =
+        new _reader_bits::MapStorage<Node, Map>(map);
+      _red_maps.push_back(std::make_pair(caption, storage));
+      return *this;
+    }
+
+    /// \brief Red map reading rule
+    ///
+    /// Add a red map reading rule with specialized converter to the
+    /// reader.
+    template <typename Map, typename Converter>
+    BpGraphReader& redMap(const std::string& caption, Map& map,
+                          const Converter& converter = Converter()) {
+      checkConcept<concepts::WriteMap<Node, typename Map::Value>, Map>();
+      _reader_bits::MapStorageBase<Node>* storage =
+        new _reader_bits::MapStorage<Node, Map, Converter>(map, converter);
+      _red_maps.push_back(std::make_pair(caption, storage));
+      return *this;
+    }
+
+    /// Add a blue map reading rule to the reader.
+    template <typename Map>
+    BpGraphReader& blueMap(const std::string& caption, Map& map) {
+      checkConcept<concepts::WriteMap<Node, typename Map::Value>, Map>();
+      _reader_bits::MapStorageBase<Node>* storage =
+        new _reader_bits::MapStorage<Node, Map>(map);
+      _blue_maps.push_back(std::make_pair(caption, storage));
+      return *this;
+    }
+



More information about the Lemon-commits mailing list