Changes in lemon/lgf_writer.h [1198:4936be66d2f5:956:141f9c0db4a3] in lemon
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
lemon/lgf_writer.h
r1198 r956 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, 195 typename Map = std::map<Value, std::string> > 194 template <typename Value> 196 195 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) 200 199 : _map(map) {} 201 200 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); 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 }237 208 } 238 209 }; … … 1016 987 /// \ingroup lemon_io 1017 988 /// 1018 /// \brief \ref lgf-format "LGF" writer for undirected graphs989 /// \brief \ref lgf-format "LGF" writer for directed graphs 1019 990 /// 1020 991 /// This utility writes an \ref lgf-format "LGF" file. … … 1072 1043 /// \brief Constructor 1073 1044 /// 1074 /// Construct a n undirected graph writer, which writes to the1075 /// givenoutput stream.1045 /// Construct a directed graph writer, which writes to the given 1046 /// output stream. 1076 1047 GraphWriter(const GR& graph, std::ostream& os = std::cout) 1077 1048 : _os(&os), local_os(false), _graph(graph), … … 1080 1051 /// \brief Constructor 1081 1052 /// 1082 /// Construct a undirected graph writer, which writes to the given1053 /// Construct a directed graph writer, which writes to the given 1083 1054 /// output file. 1084 1055 GraphWriter(const GR& graph, const std::string& fn) … … 1093 1064 /// \brief Constructor 1094 1065 /// 1095 /// Construct a undirected graph writer, which writes to the given1066 /// Construct a directed graph writer, which writes to the given 1096 1067 /// output file. 1097 1068 GraphWriter(const GR& graph, const char* fn) … … 1319 1290 } 1320 1291 1321 /// \brief Add an additional caption to the \c \@ edges section1322 /// 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. 1324 1295 GraphWriter& edges(const std::string& caption) { 1325 1296 _edges_caption = caption; … … 1635 1606 GraphWriter<TGR> graphWriter(const TGR& graph, const char* fn) { 1636 1607 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_io1652 ///1653 /// \brief \ref lgf-format "LGF" writer for undirected bipartite graphs1654 ///1655 /// This utility writes an \ref lgf-format "LGF" file.1656 ///1657 /// It can be used almost the same way as \c GraphWriter, but it1658 /// reads the red and blue nodes from separate sections, and these1659 /// sections can contain different set of maps.1660 ///1661 /// The red and blue node maps are written to the corresponding1662 /// sections. The node maps are written to both of these sections1663 /// 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 Constructor1711 ///1712 /// Construct a bipartite graph writer, which writes to the given1713 /// 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 Constructor1719 ///1720 /// Construct a bipartite graph writer, which writes to the given1721 /// 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 Constructor1732 ///1733 /// Construct a bipartite graph writer, which writes to the given1734 /// 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 Destructor1745 ~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 Rules1808 /// @{1809 1810 /// \brief Node map writing rule1811 ///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 rule1826 ///1827 /// Add a node map writing rule with specialized converter to the1828 /// 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 rule1843 ///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 rule1855 ///1856 /// Add a red node map writing rule with specialized converter to the1857 /// 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 rule1869 ///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 rule1881 ///1882 /// Add a blue node map writing rule with specialized converter to the1883 /// 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 rule1895 ///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 rule1907 ///1908 /// Add an edge map writing rule with specialized converter to the1909 /// 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 rule1921 ///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 rule1936 ///1937 /// Add an arc map writing rule with specialized converter to the1938 /// 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 rule1955 ///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 rule1966 ///1967 /// Add an attribute writing rule with specialized converter to the1968 /// 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 rule1979 ///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 rule1992 ///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 rule2004 ///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 rule2016 ///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 rule2028 ///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 Captions2040 /// @{2041 2042 /// \brief Add an additional caption to the \c \@red_nodes and2043 /// \c \@blue_nodes section2044 ///2045 /// Add an additional caption to the \c \@red_nodes and \c2046 /// \@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 section2053 ///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 section2061 ///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 Section2069 /// @{2070 2071 /// \brief Skip writing the node set2072 ///2073 /// The \c \@red_nodes and \c \@blue_nodes section will not be2074 /// 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 set2082 ///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 Writer2371 /// @{2372 2373 /// \brief Start the batch processing2374 ///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 writer2393 ///2394 /// Give back the stream of the writer2395 std::ostream& ostream() {2396 return *_os;2397 }2398 2399 /// @}2400 };2401 2402 /// \ingroup lemon_io2403 ///2404 /// \brief Return a \ref BpGraphWriter class2405 ///2406 /// This function just returns a \ref BpGraphWriter class.2407 ///2408 /// With this function a bipartite graph can be write to a file or output2409 /// stream in \ref lgf-format "LGF" format with several maps and2410 /// attributes. For example, with the following code a bipartite2411 /// 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 ///\code2415 ///ListBpGraph graph;2416 ///ListBpGraph::EdgeMap<int> weight(graph);2417 /// // Setting the weight map2418 ///bpGraphWriter(graph, std::cout).2419 /// edgeMap("weight", weight).2420 /// run();2421 ///\endcode2422 ///2423 /// For a complete documentation, please see the \ref BpGraphWriter2424 /// class documentation.2425 /// \warning Don't forget to put the \ref BpGraphWriter::run() "run()"2426 /// to the end of the parameter list.2427 /// \relates BpGraphWriter2428 /// \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 class2437 ///2438 /// This function just returns a \ref BpGraphWriter class.2439 /// \relates BpGraphWriter2440 /// \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 class2448 ///2449 /// This function just returns a \ref BpGraphWriter class.2450 /// \relates BpGraphWriter2451 /// \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);2455 1608 return tmp; 2456 1609 }
Note: See TracChangeset
for help on using the changeset viewer.