Changeset 1192:b84e68af8248 in lemon for lemon/lgf_writer.h
- Timestamp:
- 11/25/10 22:45:29 (14 years ago)
- Branch:
- default
- Phase:
- public
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
lemon/lgf_writer.h
r956 r1192 987 987 /// \ingroup lemon_io 988 988 /// 989 /// \brief \ref lgf-format "LGF" writer for directed graphs989 /// \brief \ref lgf-format "LGF" writer for undirected graphs 990 990 /// 991 991 /// This utility writes an \ref lgf-format "LGF" file. … … 1043 1043 /// \brief Constructor 1044 1044 /// 1045 /// Construct a directed graph writer, which writes to the given1046 /// output stream.1045 /// Construct an undirected graph writer, which writes to the 1046 /// given output stream. 1047 1047 GraphWriter(const GR& graph, std::ostream& os = std::cout) 1048 1048 : _os(&os), local_os(false), _graph(graph), … … 1051 1051 /// \brief Constructor 1052 1052 /// 1053 /// Construct a directed graph writer, which writes to the given1053 /// Construct a undirected graph writer, which writes to the given 1054 1054 /// output file. 1055 1055 GraphWriter(const GR& graph, const std::string& fn) … … 1064 1064 /// \brief Constructor 1065 1065 /// 1066 /// Construct a directed graph writer, which writes to the given1066 /// Construct a undirected graph writer, which writes to the given 1067 1067 /// output file. 1068 1068 GraphWriter(const GR& graph, const char* fn) … … 1290 1290 } 1291 1291 1292 /// \brief Add an additional caption to the \c \@ arcs section1293 /// 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. 1295 1295 GraphWriter& edges(const std::string& caption) { 1296 1296 _edges_caption = caption; … … 1606 1606 GraphWriter<TGR> graphWriter(const TGR& graph, const char* fn) { 1607 1607 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); 1608 2396 return tmp; 1609 2397 }
Note: See TracChangeset
for help on using the changeset viewer.