[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