COIN-OR::LEMON - Graph Library

Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • lemon/lgf_writer.h

    r956 r1198  
    186186      ValueStorage(const Value& value, const Converter& converter = Converter())
    187187        : _value(value), _converter(converter) {}
    188 
     188     
    189189      virtual std::string get() {
    190190        return _converter(_value);
     
    192192    };
    193193
    194     template <typename Value>
     194    template <typename Value,
     195              typename Map = std::map<Value, std::string> >
    195196    struct MapLookUpConverter {
    196       const std::map<Value, std::string>& _map;
    197 
    198       MapLookUpConverter(const std::map<Value, std::string>& map)
     197      const Map& _map;
     198
     199      MapLookUpConverter(const Map& map)
    199200        : _map(map) {}
    200201
    201       std::string operator()(const Value& str) {
    202         typename std::map<Value, std::string>::const_iterator it =
    203           _map.find(str);
     202      std::string operator()(const Value& value) {
     203        typename Map::const_iterator it = _map.find(value);
    204204        if (it == _map.end()) {
    205205          throw FormatError("Item not found");
    206206        }
    207207        return it->second;
     208      }
     209    };
     210
     211    template <typename Value,
     212              typename Map1 = std::map<Value, std::string>,
     213              typename Map2 = std::map<Value, std::string> >
     214    struct DoubleMapLookUpConverter {
     215      const Map1& _map1;
     216      const Map2& _map2;
     217
     218      DoubleMapLookUpConverter(const Map1& map1, const Map2& map2)
     219        : _map1(map1), _map2(map2) {}
     220
     221      std::string operator()(const Value& value) {
     222        typename Map1::const_iterator it1 = _map1.find(value);
     223        typename Map1::const_iterator it2 = _map2.find(value);
     224        if (it1 == _map1.end()) {
     225          if (it2 == _map2.end()) {
     226            throw FormatError("Item not found");
     227          } else {
     228            return it2->second;
     229          }
     230        } else {
     231          if (it2 == _map2.end()) {
     232            return it1->second;
     233          } else {
     234            throw FormatError("Item is ambigous");
     235          }
     236        }
    208237      }
    209238    };
     
    9871016  /// \ingroup lemon_io
    9881017  ///
    989   /// \brief \ref lgf-format "LGF" writer for directed graphs
     1018  /// \brief \ref lgf-format "LGF" writer for undirected graphs
    9901019  ///
    9911020  /// This utility writes an \ref lgf-format "LGF" file.
     
    10431072    /// \brief Constructor
    10441073    ///
    1045     /// Construct a directed graph writer, which writes to the given
    1046     /// output stream.
     1074    /// Construct an undirected graph writer, which writes to the
     1075    /// given output stream.
    10471076    GraphWriter(const GR& graph, std::ostream& os = std::cout)
    10481077      : _os(&os), local_os(false), _graph(graph),
     
    10511080    /// \brief Constructor
    10521081    ///
    1053     /// Construct a directed graph writer, which writes to the given
     1082    /// Construct a undirected graph writer, which writes to the given
    10541083    /// output file.
    10551084    GraphWriter(const GR& graph, const std::string& fn)
     
    10641093    /// \brief Constructor
    10651094    ///
    1066     /// Construct a directed graph writer, which writes to the given
     1095    /// Construct a undirected graph writer, which writes to the given
    10671096    /// output file.
    10681097    GraphWriter(const GR& graph, const char* fn)
     
    12901319    }
    12911320
    1292     /// \brief Add an additional caption to the \c \@arcs section
    1293     ///
    1294     /// Add an additional caption to the \c \@arcs section.
     1321    /// \brief Add an additional caption to the \c \@edges section
     1322    ///
     1323    /// Add an additional caption to the \c \@edges section.
    12951324    GraphWriter& edges(const std::string& caption) {
    12961325      _edges_caption = caption;
     
    16061635  GraphWriter<TGR> graphWriter(const TGR& graph, const char* fn) {
    16071636    GraphWriter<TGR> tmp(graph, fn);
     1637    return tmp;
     1638  }
     1639
     1640  template <typename BGR>
     1641  class BpGraphWriter;
     1642
     1643  template <typename TBGR>
     1644  BpGraphWriter<TBGR> bpGraphWriter(const TBGR& graph,
     1645                                    std::ostream& os = std::cout);
     1646  template <typename TBGR>
     1647  BpGraphWriter<TBGR> bpGraphWriter(const TBGR& graph, const std::string& fn);
     1648  template <typename TBGR>
     1649  BpGraphWriter<TBGR> bpGraphWriter(const TBGR& graph, const char* fn);
     1650
     1651  /// \ingroup lemon_io
     1652  ///
     1653  /// \brief \ref lgf-format "LGF" writer for undirected bipartite graphs
     1654  ///
     1655  /// This utility writes an \ref lgf-format "LGF" file.
     1656  ///
     1657  /// It can be used almost the same way as \c GraphWriter, but it
     1658  /// reads the red and blue nodes from separate sections, and these
     1659  /// sections can contain different set of maps.
     1660  ///
     1661  /// The red and blue node maps are written to the corresponding
     1662  /// sections. The node maps are written to both of these sections
     1663  /// with the same map name.
     1664  template <typename BGR>
     1665  class BpGraphWriter {
     1666  public:
     1667
     1668    typedef BGR BpGraph;
     1669    TEMPLATE_BPGRAPH_TYPEDEFS(BGR);
     1670
     1671  private:
     1672
     1673
     1674    std::ostream* _os;
     1675    bool local_os;
     1676
     1677    const BGR& _graph;
     1678
     1679    std::string _nodes_caption;
     1680    std::string _edges_caption;
     1681    std::string _attributes_caption;
     1682
     1683    typedef std::map<Node, std::string> RedNodeIndex;
     1684    RedNodeIndex _red_node_index;
     1685    typedef std::map<Node, std::string> BlueNodeIndex;
     1686    BlueNodeIndex _blue_node_index;
     1687    typedef std::map<Edge, std::string> EdgeIndex;
     1688    EdgeIndex _edge_index;
     1689
     1690    typedef std::vector<std::pair<std::string,
     1691      _writer_bits::MapStorageBase<RedNode>* > > RedNodeMaps;
     1692    RedNodeMaps _red_node_maps;
     1693    typedef std::vector<std::pair<std::string,
     1694      _writer_bits::MapStorageBase<BlueNode>* > > BlueNodeMaps;
     1695    BlueNodeMaps _blue_node_maps;
     1696
     1697    typedef std::vector<std::pair<std::string,
     1698      _writer_bits::MapStorageBase<Edge>* > >EdgeMaps;
     1699    EdgeMaps _edge_maps;
     1700
     1701    typedef std::vector<std::pair<std::string,
     1702      _writer_bits::ValueStorageBase*> > Attributes;
     1703    Attributes _attributes;
     1704
     1705    bool _skip_nodes;
     1706    bool _skip_edges;
     1707
     1708  public:
     1709
     1710    /// \brief Constructor
     1711    ///
     1712    /// Construct a bipartite graph writer, which writes to the given
     1713    /// output stream.
     1714    BpGraphWriter(const BGR& graph, std::ostream& os = std::cout)
     1715      : _os(&os), local_os(false), _graph(graph),
     1716        _skip_nodes(false), _skip_edges(false) {}
     1717
     1718    /// \brief Constructor
     1719    ///
     1720    /// Construct a bipartite graph writer, which writes to the given
     1721    /// output file.
     1722    BpGraphWriter(const BGR& graph, const std::string& fn)
     1723      : _os(new std::ofstream(fn.c_str())), local_os(true), _graph(graph),
     1724        _skip_nodes(false), _skip_edges(false) {
     1725      if (!(*_os)) {
     1726        delete _os;
     1727        throw IoError("Cannot write file", fn);
     1728      }
     1729    }
     1730
     1731    /// \brief Constructor
     1732    ///
     1733    /// Construct a bipartite graph writer, which writes to the given
     1734    /// output file.
     1735    BpGraphWriter(const BGR& graph, const char* fn)
     1736      : _os(new std::ofstream(fn)), local_os(true), _graph(graph),
     1737        _skip_nodes(false), _skip_edges(false) {
     1738      if (!(*_os)) {
     1739        delete _os;
     1740        throw IoError("Cannot write file", fn);
     1741      }
     1742    }
     1743
     1744    /// \brief Destructor
     1745    ~BpGraphWriter() {
     1746      for (typename RedNodeMaps::iterator it = _red_node_maps.begin();
     1747           it != _red_node_maps.end(); ++it) {
     1748        delete it->second;
     1749      }
     1750
     1751      for (typename BlueNodeMaps::iterator it = _blue_node_maps.begin();
     1752           it != _blue_node_maps.end(); ++it) {
     1753        delete it->second;
     1754      }
     1755
     1756      for (typename EdgeMaps::iterator it = _edge_maps.begin();
     1757           it != _edge_maps.end(); ++it) {
     1758        delete it->second;
     1759      }
     1760
     1761      for (typename Attributes::iterator it = _attributes.begin();
     1762           it != _attributes.end(); ++it) {
     1763        delete it->second;
     1764      }
     1765
     1766      if (local_os) {
     1767        delete _os;
     1768      }
     1769    }
     1770
     1771  private:
     1772
     1773    template <typename TBGR>
     1774    friend BpGraphWriter<TBGR> bpGraphWriter(const TBGR& graph,
     1775                                             std::ostream& os);
     1776    template <typename TBGR>
     1777    friend BpGraphWriter<TBGR> bpGraphWriter(const TBGR& graph,
     1778                                             const std::string& fn);
     1779    template <typename TBGR>
     1780    friend BpGraphWriter<TBGR> bpGraphWriter(const TBGR& graph, const char *fn);
     1781
     1782    BpGraphWriter(BpGraphWriter& other)
     1783      : _os(other._os), local_os(other.local_os), _graph(other._graph),
     1784        _skip_nodes(other._skip_nodes), _skip_edges(other._skip_edges) {
     1785
     1786      other._os = 0;
     1787      other.local_os = false;
     1788
     1789      _red_node_index.swap(other._red_node_index);
     1790      _blue_node_index.swap(other._blue_node_index);
     1791      _edge_index.swap(other._edge_index);
     1792
     1793      _red_node_maps.swap(other._red_node_maps);
     1794      _blue_node_maps.swap(other._blue_node_maps);
     1795      _edge_maps.swap(other._edge_maps);
     1796      _attributes.swap(other._attributes);
     1797
     1798      _nodes_caption = other._nodes_caption;
     1799      _edges_caption = other._edges_caption;
     1800      _attributes_caption = other._attributes_caption;
     1801    }
     1802
     1803    BpGraphWriter& operator=(const BpGraphWriter&);
     1804
     1805  public:
     1806
     1807    /// \name Writing Rules
     1808    /// @{
     1809
     1810    /// \brief Node map writing rule
     1811    ///
     1812    /// Add a node map writing rule to the writer.
     1813    template <typename Map>
     1814    BpGraphWriter& nodeMap(const std::string& caption, const Map& map) {
     1815      checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
     1816      _writer_bits::MapStorageBase<RedNode>* red_storage =
     1817        new _writer_bits::MapStorage<RedNode, Map>(map);
     1818      _red_node_maps.push_back(std::make_pair(caption, red_storage));
     1819      _writer_bits::MapStorageBase<BlueNode>* blue_storage =
     1820        new _writer_bits::MapStorage<BlueNode, Map>(map);
     1821      _blue_node_maps.push_back(std::make_pair(caption, blue_storage));
     1822      return *this;
     1823    }
     1824
     1825    /// \brief Node map writing rule
     1826    ///
     1827    /// Add a node map writing rule with specialized converter to the
     1828    /// writer.
     1829    template <typename Map, typename Converter>
     1830    BpGraphWriter& nodeMap(const std::string& caption, const Map& map,
     1831                           const Converter& converter = Converter()) {
     1832      checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
     1833      _writer_bits::MapStorageBase<RedNode>* red_storage =
     1834        new _writer_bits::MapStorage<RedNode, Map, Converter>(map, converter);
     1835      _red_node_maps.push_back(std::make_pair(caption, red_storage));
     1836      _writer_bits::MapStorageBase<BlueNode>* blue_storage =
     1837        new _writer_bits::MapStorage<BlueNode, Map, Converter>(map, converter);
     1838      _blue_node_maps.push_back(std::make_pair(caption, blue_storage));
     1839      return *this;
     1840    }
     1841
     1842    /// \brief Red node map writing rule
     1843    ///
     1844    /// Add a red node map writing rule to the writer.
     1845    template <typename Map>
     1846    BpGraphWriter& redNodeMap(const std::string& caption, const Map& map) {
     1847      checkConcept<concepts::ReadMap<RedNode, typename Map::Value>, Map>();
     1848      _writer_bits::MapStorageBase<RedNode>* storage =
     1849        new _writer_bits::MapStorage<RedNode, Map>(map);
     1850      _red_node_maps.push_back(std::make_pair(caption, storage));
     1851      return *this;
     1852    }
     1853
     1854    /// \brief Red node map writing rule
     1855    ///
     1856    /// Add a red node map writing rule with specialized converter to the
     1857    /// writer.
     1858    template <typename Map, typename Converter>
     1859    BpGraphWriter& redNodeMap(const std::string& caption, const Map& map,
     1860                              const Converter& converter = Converter()) {
     1861      checkConcept<concepts::ReadMap<RedNode, typename Map::Value>, Map>();
     1862      _writer_bits::MapStorageBase<RedNode>* storage =
     1863        new _writer_bits::MapStorage<RedNode, Map, Converter>(map, converter);
     1864      _red_node_maps.push_back(std::make_pair(caption, storage));
     1865      return *this;
     1866    }
     1867
     1868    /// \brief Blue node map writing rule
     1869    ///
     1870    /// Add a blue node map writing rule to the writer.
     1871    template <typename Map>
     1872    BpGraphWriter& blueNodeMap(const std::string& caption, const Map& map) {
     1873      checkConcept<concepts::ReadMap<BlueNode, typename Map::Value>, Map>();
     1874      _writer_bits::MapStorageBase<BlueNode>* storage =
     1875        new _writer_bits::MapStorage<BlueNode, Map>(map);
     1876      _blue_node_maps.push_back(std::make_pair(caption, storage));
     1877      return *this;
     1878    }
     1879
     1880    /// \brief Blue node map writing rule
     1881    ///
     1882    /// Add a blue node map writing rule with specialized converter to the
     1883    /// writer.
     1884    template <typename Map, typename Converter>
     1885    BpGraphWriter& blueNodeMap(const std::string& caption, const Map& map,
     1886                               const Converter& converter = Converter()) {
     1887      checkConcept<concepts::ReadMap<BlueNode, typename Map::Value>, Map>();
     1888      _writer_bits::MapStorageBase<BlueNode>* storage =
     1889        new _writer_bits::MapStorage<BlueNode, Map, Converter>(map, converter);
     1890      _blue_node_maps.push_back(std::make_pair(caption, storage));
     1891      return *this;
     1892    }
     1893
     1894    /// \brief Edge map writing rule
     1895    ///
     1896    /// Add an edge map writing rule to the writer.
     1897    template <typename Map>
     1898    BpGraphWriter& edgeMap(const std::string& caption, const Map& map) {
     1899      checkConcept<concepts::ReadMap<Edge, typename Map::Value>, Map>();
     1900      _writer_bits::MapStorageBase<Edge>* storage =
     1901        new _writer_bits::MapStorage<Edge, Map>(map);
     1902      _edge_maps.push_back(std::make_pair(caption, storage));
     1903      return *this;
     1904    }
     1905
     1906    /// \brief Edge map writing rule
     1907    ///
     1908    /// Add an edge map writing rule with specialized converter to the
     1909    /// writer.
     1910    template <typename Map, typename Converter>
     1911    BpGraphWriter& edgeMap(const std::string& caption, const Map& map,
     1912                          const Converter& converter = Converter()) {
     1913      checkConcept<concepts::ReadMap<Edge, typename Map::Value>, Map>();
     1914      _writer_bits::MapStorageBase<Edge>* storage =
     1915        new _writer_bits::MapStorage<Edge, Map, Converter>(map, converter);
     1916      _edge_maps.push_back(std::make_pair(caption, storage));
     1917      return *this;
     1918    }
     1919
     1920    /// \brief Arc map writing rule
     1921    ///
     1922    /// Add an arc map writing rule to the writer.
     1923    template <typename Map>
     1924    BpGraphWriter& arcMap(const std::string& caption, const Map& map) {
     1925      checkConcept<concepts::ReadMap<Arc, typename Map::Value>, Map>();
     1926      _writer_bits::MapStorageBase<Edge>* forward_storage =
     1927        new _writer_bits::GraphArcMapStorage<BGR, true, Map>(_graph, map);
     1928      _edge_maps.push_back(std::make_pair('+' + caption, forward_storage));
     1929      _writer_bits::MapStorageBase<Edge>* backward_storage =
     1930        new _writer_bits::GraphArcMapStorage<BGR, false, Map>(_graph, map);
     1931      _edge_maps.push_back(std::make_pair('-' + caption, backward_storage));
     1932      return *this;
     1933    }
     1934
     1935    /// \brief Arc map writing rule
     1936    ///
     1937    /// Add an arc map writing rule with specialized converter to the
     1938    /// writer.
     1939    template <typename Map, typename Converter>
     1940    BpGraphWriter& arcMap(const std::string& caption, const Map& map,
     1941                          const Converter& converter = Converter()) {
     1942      checkConcept<concepts::ReadMap<Arc, typename Map::Value>, Map>();
     1943      _writer_bits::MapStorageBase<Edge>* forward_storage =
     1944        new _writer_bits::GraphArcMapStorage<BGR, true, Map, Converter>
     1945        (_graph, map, converter);
     1946      _edge_maps.push_back(std::make_pair('+' + caption, forward_storage));
     1947      _writer_bits::MapStorageBase<Edge>* backward_storage =
     1948        new _writer_bits::GraphArcMapStorage<BGR, false, Map, Converter>
     1949        (_graph, map, converter);
     1950      _edge_maps.push_back(std::make_pair('-' + caption, backward_storage));
     1951      return *this;
     1952    }
     1953
     1954    /// \brief Attribute writing rule
     1955    ///
     1956    /// Add an attribute writing rule to the writer.
     1957    template <typename Value>
     1958    BpGraphWriter& attribute(const std::string& caption, const Value& value) {
     1959      _writer_bits::ValueStorageBase* storage =
     1960        new _writer_bits::ValueStorage<Value>(value);
     1961      _attributes.push_back(std::make_pair(caption, storage));
     1962      return *this;
     1963    }
     1964
     1965    /// \brief Attribute writing rule
     1966    ///
     1967    /// Add an attribute writing rule with specialized converter to the
     1968    /// writer.
     1969    template <typename Value, typename Converter>
     1970    BpGraphWriter& attribute(const std::string& caption, const Value& value,
     1971                             const Converter& converter = Converter()) {
     1972      _writer_bits::ValueStorageBase* storage =
     1973        new _writer_bits::ValueStorage<Value, Converter>(value, converter);
     1974      _attributes.push_back(std::make_pair(caption, storage));
     1975      return *this;
     1976    }
     1977
     1978    /// \brief Node writing rule
     1979    ///
     1980    /// Add a node writing rule to the writer.
     1981    BpGraphWriter& node(const std::string& caption, const Node& node) {
     1982      typedef _writer_bits::DoubleMapLookUpConverter<
     1983        Node, RedNodeIndex, BlueNodeIndex> Converter;
     1984      Converter converter(_red_node_index, _blue_node_index);
     1985      _writer_bits::ValueStorageBase* storage =
     1986        new _writer_bits::ValueStorage<Node, Converter>(node, converter);
     1987      _attributes.push_back(std::make_pair(caption, storage));
     1988      return *this;
     1989    }
     1990
     1991    /// \brief Red node writing rule
     1992    ///
     1993    /// Add a red node writing rule to the writer.
     1994    BpGraphWriter& redNode(const std::string& caption, const RedNode& node) {
     1995      typedef _writer_bits::MapLookUpConverter<Node> Converter;
     1996      Converter converter(_red_node_index);
     1997      _writer_bits::ValueStorageBase* storage =
     1998        new _writer_bits::ValueStorage<Node, Converter>(node, converter);
     1999      _attributes.push_back(std::make_pair(caption, storage));
     2000      return *this;
     2001    }
     2002
     2003    /// \brief Blue node writing rule
     2004    ///
     2005    /// Add a blue node writing rule to the writer.
     2006    BpGraphWriter& blueNode(const std::string& caption, const BlueNode& node) {
     2007      typedef _writer_bits::MapLookUpConverter<Node> Converter;
     2008      Converter converter(_blue_node_index);
     2009      _writer_bits::ValueStorageBase* storage =
     2010        new _writer_bits::ValueStorage<Node, Converter>(node, converter);
     2011      _attributes.push_back(std::make_pair(caption, storage));
     2012      return *this;
     2013    }
     2014
     2015    /// \brief Edge writing rule
     2016    ///
     2017    /// Add an edge writing rule to writer.
     2018    BpGraphWriter& edge(const std::string& caption, const Edge& edge) {
     2019      typedef _writer_bits::MapLookUpConverter<Edge> Converter;
     2020      Converter converter(_edge_index);
     2021      _writer_bits::ValueStorageBase* storage =
     2022        new _writer_bits::ValueStorage<Edge, Converter>(edge, converter);
     2023      _attributes.push_back(std::make_pair(caption, storage));
     2024      return *this;
     2025    }
     2026
     2027    /// \brief Arc writing rule
     2028    ///
     2029    /// Add an arc writing rule to writer.
     2030    BpGraphWriter& arc(const std::string& caption, const Arc& arc) {
     2031      typedef _writer_bits::GraphArcLookUpConverter<BGR> Converter;
     2032      Converter converter(_graph, _edge_index);
     2033      _writer_bits::ValueStorageBase* storage =
     2034        new _writer_bits::ValueStorage<Arc, Converter>(arc, converter);
     2035      _attributes.push_back(std::make_pair(caption, storage));
     2036      return *this;
     2037    }
     2038
     2039    /// \name Section Captions
     2040    /// @{
     2041
     2042    /// \brief Add an additional caption to the \c \@red_nodes and
     2043    /// \c \@blue_nodes section
     2044    ///
     2045    /// Add an additional caption to the \c \@red_nodes and \c
     2046    /// \@blue_nodes section.
     2047    BpGraphWriter& nodes(const std::string& caption) {
     2048      _nodes_caption = caption;
     2049      return *this;
     2050    }
     2051
     2052    /// \brief Add an additional caption to the \c \@edges section
     2053    ///
     2054    /// Add an additional caption to the \c \@edges section.
     2055    BpGraphWriter& edges(const std::string& caption) {
     2056      _edges_caption = caption;
     2057      return *this;
     2058    }
     2059
     2060    /// \brief Add an additional caption to the \c \@attributes section
     2061    ///
     2062    /// Add an additional caption to the \c \@attributes section.
     2063    BpGraphWriter& attributes(const std::string& caption) {
     2064      _attributes_caption = caption;
     2065      return *this;
     2066    }
     2067
     2068    /// \name Skipping Section
     2069    /// @{
     2070
     2071    /// \brief Skip writing the node set
     2072    ///
     2073    /// The \c \@red_nodes and \c \@blue_nodes section will not be
     2074    /// written to the stream.
     2075    BpGraphWriter& skipNodes() {
     2076      LEMON_ASSERT(!_skip_nodes, "Multiple usage of skipNodes() member");
     2077      _skip_nodes = true;
     2078      return *this;
     2079    }
     2080
     2081    /// \brief Skip writing edge set
     2082    ///
     2083    /// The \c \@edges section will not be written to the stream.
     2084    BpGraphWriter& skipEdges() {
     2085      LEMON_ASSERT(!_skip_edges, "Multiple usage of skipEdges() member");
     2086      _skip_edges = true;
     2087      return *this;
     2088    }
     2089
     2090    /// @}
     2091
     2092  private:
     2093
     2094    void writeRedNodes() {
     2095      _writer_bits::MapStorageBase<RedNode>* label = 0;
     2096      for (typename RedNodeMaps::iterator it = _red_node_maps.begin();
     2097           it != _red_node_maps.end(); ++it) {
     2098        if (it->first == "label") {
     2099          label = it->second;
     2100          break;
     2101        }
     2102      }
     2103
     2104      *_os << "@red_nodes";
     2105      if (!_nodes_caption.empty()) {
     2106        _writer_bits::writeToken(*_os << ' ', _nodes_caption);
     2107      }
     2108      *_os << std::endl;
     2109
     2110      if (label == 0) {
     2111        *_os << "label" << '\t';
     2112      }
     2113      for (typename RedNodeMaps::iterator it = _red_node_maps.begin();
     2114           it != _red_node_maps.end(); ++it) {
     2115        _writer_bits::writeToken(*_os, it->first) << '\t';
     2116      }
     2117      *_os << std::endl;
     2118
     2119      std::vector<RedNode> nodes;
     2120      for (RedNodeIt n(_graph); n != INVALID; ++n) {
     2121        nodes.push_back(n);
     2122      }
     2123
     2124      if (label == 0) {
     2125        IdMap<BGR, Node> id_map(_graph);
     2126        _writer_bits::MapLess<IdMap<BGR, Node> > id_less(id_map);
     2127        std::sort(nodes.begin(), nodes.end(), id_less);
     2128      } else {
     2129        label->sort(nodes);
     2130      }
     2131
     2132      for (int i = 0; i < static_cast<int>(nodes.size()); ++i) {
     2133        RedNode n = nodes[i];
     2134        if (label == 0) {
     2135          std::ostringstream os;
     2136          os << _graph.id(static_cast<Node>(n));
     2137          _writer_bits::writeToken(*_os, os.str());
     2138          *_os << '\t';
     2139          _red_node_index.insert(std::make_pair(n, os.str()));
     2140        }
     2141        for (typename RedNodeMaps::iterator it = _red_node_maps.begin();
     2142             it != _red_node_maps.end(); ++it) {
     2143          std::string value = it->second->get(n);
     2144          _writer_bits::writeToken(*_os, value);
     2145          if (it->first == "label") {
     2146            _red_node_index.insert(std::make_pair(n, value));
     2147          }
     2148          *_os << '\t';
     2149        }
     2150        *_os << std::endl;
     2151      }
     2152    }
     2153
     2154    void writeBlueNodes() {
     2155      _writer_bits::MapStorageBase<BlueNode>* label = 0;
     2156      for (typename BlueNodeMaps::iterator it = _blue_node_maps.begin();
     2157           it != _blue_node_maps.end(); ++it) {
     2158        if (it->first == "label") {
     2159          label = it->second;
     2160          break;
     2161        }
     2162      }
     2163
     2164      *_os << "@blue_nodes";
     2165      if (!_nodes_caption.empty()) {
     2166        _writer_bits::writeToken(*_os << ' ', _nodes_caption);
     2167      }
     2168      *_os << std::endl;
     2169
     2170      if (label == 0) {
     2171        *_os << "label" << '\t';
     2172      }
     2173      for (typename BlueNodeMaps::iterator it = _blue_node_maps.begin();
     2174           it != _blue_node_maps.end(); ++it) {
     2175        _writer_bits::writeToken(*_os, it->first) << '\t';
     2176      }
     2177      *_os << std::endl;
     2178
     2179      std::vector<BlueNode> nodes;
     2180      for (BlueNodeIt n(_graph); n != INVALID; ++n) {
     2181        nodes.push_back(n);
     2182      }
     2183
     2184      if (label == 0) {
     2185        IdMap<BGR, Node> id_map(_graph);
     2186        _writer_bits::MapLess<IdMap<BGR, Node> > id_less(id_map);
     2187        std::sort(nodes.begin(), nodes.end(), id_less);
     2188      } else {
     2189        label->sort(nodes);
     2190      }
     2191
     2192      for (int i = 0; i < static_cast<int>(nodes.size()); ++i) {
     2193        BlueNode n = nodes[i];
     2194        if (label == 0) {
     2195          std::ostringstream os;
     2196          os << _graph.id(static_cast<Node>(n));
     2197          _writer_bits::writeToken(*_os, os.str());
     2198          *_os << '\t';
     2199          _blue_node_index.insert(std::make_pair(n, os.str()));
     2200        }
     2201        for (typename BlueNodeMaps::iterator it = _blue_node_maps.begin();
     2202             it != _blue_node_maps.end(); ++it) {
     2203          std::string value = it->second->get(n);
     2204          _writer_bits::writeToken(*_os, value);
     2205          if (it->first == "label") {
     2206            _blue_node_index.insert(std::make_pair(n, value));
     2207          }
     2208          *_os << '\t';
     2209        }
     2210        *_os << std::endl;
     2211      }
     2212    }
     2213
     2214    void createRedNodeIndex() {
     2215      _writer_bits::MapStorageBase<RedNode>* label = 0;
     2216      for (typename RedNodeMaps::iterator it = _red_node_maps.begin();
     2217           it != _red_node_maps.end(); ++it) {
     2218        if (it->first == "label") {
     2219          label = it->second;
     2220          break;
     2221        }
     2222      }
     2223
     2224      if (label == 0) {
     2225        for (RedNodeIt n(_graph); n != INVALID; ++n) {
     2226          std::ostringstream os;
     2227          os << _graph.id(n);
     2228          _red_node_index.insert(std::make_pair(n, os.str()));
     2229        }
     2230      } else {
     2231        for (RedNodeIt n(_graph); n != INVALID; ++n) {
     2232          std::string value = label->get(n);
     2233          _red_node_index.insert(std::make_pair(n, value));
     2234        }
     2235      }
     2236    }
     2237
     2238    void createBlueNodeIndex() {
     2239      _writer_bits::MapStorageBase<BlueNode>* label = 0;
     2240      for (typename BlueNodeMaps::iterator it = _blue_node_maps.begin();
     2241           it != _blue_node_maps.end(); ++it) {
     2242        if (it->first == "label") {
     2243          label = it->second;
     2244          break;
     2245        }
     2246      }
     2247
     2248      if (label == 0) {
     2249        for (BlueNodeIt n(_graph); n != INVALID; ++n) {
     2250          std::ostringstream os;
     2251          os << _graph.id(n);
     2252          _blue_node_index.insert(std::make_pair(n, os.str()));
     2253        }
     2254      } else {
     2255        for (BlueNodeIt n(_graph); n != INVALID; ++n) {
     2256          std::string value = label->get(n);
     2257          _blue_node_index.insert(std::make_pair(n, value));
     2258        }
     2259      }
     2260    }
     2261
     2262    void writeEdges() {
     2263      _writer_bits::MapStorageBase<Edge>* label = 0;
     2264      for (typename EdgeMaps::iterator it = _edge_maps.begin();
     2265           it != _edge_maps.end(); ++it) {
     2266        if (it->first == "label") {
     2267          label = it->second;
     2268          break;
     2269        }
     2270      }
     2271
     2272      *_os << "@edges";
     2273      if (!_edges_caption.empty()) {
     2274        _writer_bits::writeToken(*_os << ' ', _edges_caption);
     2275      }
     2276      *_os << std::endl;
     2277
     2278      *_os << '\t' << '\t';
     2279      if (label == 0) {
     2280        *_os << "label" << '\t';
     2281      }
     2282      for (typename EdgeMaps::iterator it = _edge_maps.begin();
     2283           it != _edge_maps.end(); ++it) {
     2284        _writer_bits::writeToken(*_os, it->first) << '\t';
     2285      }
     2286      *_os << std::endl;
     2287
     2288      std::vector<Edge> edges;
     2289      for (EdgeIt n(_graph); n != INVALID; ++n) {
     2290        edges.push_back(n);
     2291      }
     2292
     2293      if (label == 0) {
     2294        IdMap<BGR, Edge> id_map(_graph);
     2295        _writer_bits::MapLess<IdMap<BGR, Edge> > id_less(id_map);
     2296        std::sort(edges.begin(), edges.end(), id_less);
     2297      } else {
     2298        label->sort(edges);
     2299      }
     2300
     2301      for (int i = 0; i < static_cast<int>(edges.size()); ++i) {
     2302        Edge e = edges[i];
     2303        _writer_bits::writeToken(*_os, _red_node_index.
     2304                                 find(_graph.redNode(e))->second);
     2305        *_os << '\t';
     2306        _writer_bits::writeToken(*_os, _blue_node_index.
     2307                                 find(_graph.blueNode(e))->second);
     2308        *_os << '\t';
     2309        if (label == 0) {
     2310          std::ostringstream os;
     2311          os << _graph.id(e);
     2312          _writer_bits::writeToken(*_os, os.str());
     2313          *_os << '\t';
     2314          _edge_index.insert(std::make_pair(e, os.str()));
     2315        }
     2316        for (typename EdgeMaps::iterator it = _edge_maps.begin();
     2317             it != _edge_maps.end(); ++it) {
     2318          std::string value = it->second->get(e);
     2319          _writer_bits::writeToken(*_os, value);
     2320          if (it->first == "label") {
     2321            _edge_index.insert(std::make_pair(e, value));
     2322          }
     2323          *_os << '\t';
     2324        }
     2325        *_os << std::endl;
     2326      }
     2327    }
     2328
     2329    void createEdgeIndex() {
     2330      _writer_bits::MapStorageBase<Edge>* label = 0;
     2331      for (typename EdgeMaps::iterator it = _edge_maps.begin();
     2332           it != _edge_maps.end(); ++it) {
     2333        if (it->first == "label") {
     2334          label = it->second;
     2335          break;
     2336        }
     2337      }
     2338
     2339      if (label == 0) {
     2340        for (EdgeIt e(_graph); e != INVALID; ++e) {
     2341          std::ostringstream os;
     2342          os << _graph.id(e);
     2343          _edge_index.insert(std::make_pair(e, os.str()));
     2344        }
     2345      } else {
     2346        for (EdgeIt e(_graph); e != INVALID; ++e) {
     2347          std::string value = label->get(e);
     2348          _edge_index.insert(std::make_pair(e, value));
     2349        }
     2350      }
     2351    }
     2352
     2353    void writeAttributes() {
     2354      if (_attributes.empty()) return;
     2355      *_os << "@attributes";
     2356      if (!_attributes_caption.empty()) {
     2357        _writer_bits::writeToken(*_os << ' ', _attributes_caption);
     2358      }
     2359      *_os << std::endl;
     2360      for (typename Attributes::iterator it = _attributes.begin();
     2361           it != _attributes.end(); ++it) {
     2362        _writer_bits::writeToken(*_os, it->first) << ' ';
     2363        _writer_bits::writeToken(*_os, it->second->get());
     2364        *_os << std::endl;
     2365      }
     2366    }
     2367
     2368  public:
     2369
     2370    /// \name Execution of the Writer
     2371    /// @{
     2372
     2373    /// \brief Start the batch processing
     2374    ///
     2375    /// This function starts the batch processing.
     2376    void run() {
     2377      if (!_skip_nodes) {
     2378        writeRedNodes();
     2379        writeBlueNodes();
     2380      } else {
     2381        createRedNodeIndex();
     2382        createBlueNodeIndex();
     2383      }
     2384      if (!_skip_edges) {
     2385        writeEdges();
     2386      } else {
     2387        createEdgeIndex();
     2388      }
     2389      writeAttributes();
     2390    }
     2391
     2392    /// \brief Give back the stream of the writer
     2393    ///
     2394    /// Give back the stream of the writer
     2395    std::ostream& ostream() {
     2396      return *_os;
     2397    }
     2398
     2399    /// @}
     2400  };
     2401
     2402  /// \ingroup lemon_io
     2403  ///
     2404  /// \brief Return a \ref BpGraphWriter class
     2405  ///
     2406  /// This function just returns a \ref BpGraphWriter class.
     2407  ///
     2408  /// With this function a bipartite graph can be write to a file or output
     2409  /// stream in \ref lgf-format "LGF" format with several maps and
     2410  /// attributes. For example, with the following code a bipartite
     2411  /// weighted matching problem can be written to the standard output,
     2412  /// i.e. a graph with a \e weight map on the edges:
     2413  ///
     2414  ///\code
     2415  ///ListBpGraph graph;
     2416  ///ListBpGraph::EdgeMap<int> weight(graph);
     2417  ///  // Setting the weight map
     2418  ///bpGraphWriter(graph, std::cout).
     2419  ///  edgeMap("weight", weight).
     2420  ///  run();
     2421  ///\endcode
     2422  ///
     2423  /// For a complete documentation, please see the \ref BpGraphWriter
     2424  /// class documentation.
     2425  /// \warning Don't forget to put the \ref BpGraphWriter::run() "run()"
     2426  /// to the end of the parameter list.
     2427  /// \relates BpGraphWriter
     2428  /// \sa bpGraphWriter(const TBGR& graph, const std::string& fn)
     2429  /// \sa bpGraphWriter(const TBGR& graph, const char* fn)
     2430  template <typename TBGR>
     2431  BpGraphWriter<TBGR> bpGraphWriter(const TBGR& graph, std::ostream& os) {
     2432    BpGraphWriter<TBGR> tmp(graph, os);
     2433    return tmp;
     2434  }
     2435
     2436  /// \brief Return a \ref BpGraphWriter class
     2437  ///
     2438  /// This function just returns a \ref BpGraphWriter class.
     2439  /// \relates BpGraphWriter
     2440  /// \sa graphWriter(const TBGR& graph, std::ostream& os)
     2441  template <typename TBGR>
     2442  BpGraphWriter<TBGR> bpGraphWriter(const TBGR& graph, const std::string& fn) {
     2443    BpGraphWriter<TBGR> tmp(graph, fn);
     2444    return tmp;
     2445  }
     2446
     2447  /// \brief Return a \ref BpGraphWriter class
     2448  ///
     2449  /// This function just returns a \ref BpGraphWriter class.
     2450  /// \relates BpGraphWriter
     2451  /// \sa graphWriter(const TBGR& graph, std::ostream& os)
     2452  template <typename TBGR>
     2453  BpGraphWriter<TBGR> bpGraphWriter(const TBGR& graph, const char* fn) {
     2454    BpGraphWriter<TBGR> tmp(graph, fn);
    16082455    return tmp;
    16092456  }
Note: See TracChangeset for help on using the changeset viewer.