COIN-OR::LEMON - Graph Library

Changeset 1192:b84e68af8248 in lemon for lemon/lgf_writer.h


Ignore:
Timestamp:
11/25/10 22:45:29 (10 years ago)
Author:
Balazs Dezso <deba@…>
Branch:
default
Phase:
public
Message:

LGF reader and writer for bipartite graphs (#69)

File:
1 edited

Legend:

Unmodified
Added
Removed
  • lemon/lgf_writer.h

    r956 r1192  
    987987  /// \ingroup lemon_io
    988988  ///
    989   /// \brief \ref lgf-format "LGF" writer for directed graphs
     989  /// \brief \ref lgf-format "LGF" writer for undirected graphs
    990990  ///
    991991  /// This utility writes an \ref lgf-format "LGF" file.
     
    10431043    /// \brief Constructor
    10441044    ///
    1045     /// Construct a directed graph writer, which writes to the given
    1046     /// output stream.
     1045    /// Construct an undirected graph writer, which writes to the
     1046    /// given output stream.
    10471047    GraphWriter(const GR& graph, std::ostream& os = std::cout)
    10481048      : _os(&os), local_os(false), _graph(graph),
     
    10511051    /// \brief Constructor
    10521052    ///
    1053     /// Construct a directed graph writer, which writes to the given
     1053    /// Construct a undirected graph writer, which writes to the given
    10541054    /// output file.
    10551055    GraphWriter(const GR& graph, const std::string& fn)
     
    10641064    /// \brief Constructor
    10651065    ///
    1066     /// Construct a directed graph writer, which writes to the given
     1066    /// Construct a undirected graph writer, which writes to the given
    10671067    /// output file.
    10681068    GraphWriter(const GR& graph, const char* fn)
     
    12901290    }
    12911291
    1292     /// \brief Add an additional caption to the \c \@arcs section
    1293     ///
    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.
    12951295    GraphWriter& edges(const std::string& caption) {
    12961296      _edges_caption = caption;
     
    16061606  GraphWriter<TGR> graphWriter(const TGR& graph, const char* fn) {
    16071607    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);
    16082396    return tmp;
    16092397  }
Note: See TracChangeset for help on using the changeset viewer.