COIN-OR::LEMON - Graph Library

Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • lemon/lgf_writer.h

    r1198 r956  
    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,
    195               typename Map = std::map<Value, std::string> >
     194    template <typename Value>
    196195    struct MapLookUpConverter {
    197       const Map& _map;
    198 
    199       MapLookUpConverter(const Map& map)
     196      const std::map<Value, std::string>& _map;
     197
     198      MapLookUpConverter(const std::map<Value, std::string>& map)
    200199        : _map(map) {}
    201200
    202       std::string operator()(const Value& value) {
    203         typename Map::const_iterator it = _map.find(value);
     201      std::string operator()(const Value& str) {
     202        typename std::map<Value, std::string>::const_iterator it =
     203          _map.find(str);
    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         }
    237208      }
    238209    };
     
    1016987  /// \ingroup lemon_io
    1017988  ///
    1018   /// \brief \ref lgf-format "LGF" writer for undirected graphs
     989  /// \brief \ref lgf-format "LGF" writer for directed graphs
    1019990  ///
    1020991  /// This utility writes an \ref lgf-format "LGF" file.
     
    10721043    /// \brief Constructor
    10731044    ///
    1074     /// Construct an undirected graph writer, which writes to the
    1075     /// given output stream.
     1045    /// Construct a directed graph writer, which writes to the given
     1046    /// output stream.
    10761047    GraphWriter(const GR& graph, std::ostream& os = std::cout)
    10771048      : _os(&os), local_os(false), _graph(graph),
     
    10801051    /// \brief Constructor
    10811052    ///
    1082     /// Construct a undirected graph writer, which writes to the given
     1053    /// Construct a directed graph writer, which writes to the given
    10831054    /// output file.
    10841055    GraphWriter(const GR& graph, const std::string& fn)
     
    10931064    /// \brief Constructor
    10941065    ///
    1095     /// Construct a undirected graph writer, which writes to the given
     1066    /// Construct a directed graph writer, which writes to the given
    10961067    /// output file.
    10971068    GraphWriter(const GR& graph, const char* fn)
     
    13191290    }
    13201291
    1321     /// \brief Add an additional caption to the \c \@edges section
    1322     ///
    1323     /// Add an additional caption to the \c \@edges section.
     1292    /// \brief Add an additional caption to the \c \@arcs section
     1293    ///
     1294    /// Add an additional caption to the \c \@arcs section.
    13241295    GraphWriter& edges(const std::string& caption) {
    13251296      _edges_caption = caption;
     
    16351606  GraphWriter<TGR> graphWriter(const TGR& graph, const char* fn) {
    16361607    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);
    24551608    return tmp;
    24561609  }
Note: See TracChangeset for help on using the changeset viewer.