Changes in lemon/lgf_writer.h [956:141f9c0db4a3:1198:4936be66d2f5] in lemon
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
lemon/lgf_writer.h
r956 r1198 186 186 ValueStorage(const Value& value, const Converter& converter = Converter()) 187 187 : _value(value), _converter(converter) {} 188 188 189 189 virtual std::string get() { 190 190 return _converter(_value); … … 192 192 }; 193 193 194 template <typename Value> 194 template <typename Value, 195 typename Map = std::map<Value, std::string> > 195 196 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) 199 200 : _map(map) {} 200 201 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); 204 204 if (it == _map.end()) { 205 205 throw FormatError("Item not found"); 206 206 } 207 207 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 } 208 237 } 209 238 }; … … 987 1016 /// \ingroup lemon_io 988 1017 /// 989 /// \brief \ref lgf-format "LGF" writer for directed graphs1018 /// \brief \ref lgf-format "LGF" writer for undirected graphs 990 1019 /// 991 1020 /// This utility writes an \ref lgf-format "LGF" file. … … 1043 1072 /// \brief Constructor 1044 1073 /// 1045 /// Construct a directed graph writer, which writes to the given1046 /// output stream.1074 /// Construct an undirected graph writer, which writes to the 1075 /// given output stream. 1047 1076 GraphWriter(const GR& graph, std::ostream& os = std::cout) 1048 1077 : _os(&os), local_os(false), _graph(graph), … … 1051 1080 /// \brief Constructor 1052 1081 /// 1053 /// Construct a directed graph writer, which writes to the given1082 /// Construct a undirected graph writer, which writes to the given 1054 1083 /// output file. 1055 1084 GraphWriter(const GR& graph, const std::string& fn) … … 1064 1093 /// \brief Constructor 1065 1094 /// 1066 /// Construct a directed graph writer, which writes to the given1095 /// Construct a undirected graph writer, which writes to the given 1067 1096 /// output file. 1068 1097 GraphWriter(const GR& graph, const char* fn) … … 1290 1319 } 1291 1320 1292 /// \brief Add an additional caption to the \c \@ arcs section1293 /// 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. 1295 1324 GraphWriter& edges(const std::string& caption) { 1296 1325 _edges_caption = caption; … … 1606 1635 GraphWriter<TGR> graphWriter(const TGR& graph, const char* fn) { 1607 1636 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); 1608 2455 return tmp; 1609 2456 }
Note: See TracChangeset
for help on using the changeset viewer.