Changeset 165:b4c336c27a03 in lemon-1.2 for lemon/lgf_writer.h
- Timestamp:
- 05/31/08 12:49:18 (15 years ago)
- Branch:
- default
- Phase:
- public
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
lemon/lgf_writer.h
r163 r165 72 72 }; 73 73 74 template <typename _Graph, bool _dir, typename _Map> 75 class GraphArcMapLess { 76 public: 77 typedef _Map Map; 78 typedef _Graph Graph; 79 typedef typename Graph::Edge Item; 80 81 private: 82 const Graph& _graph; 83 const Map& _map; 84 85 public: 86 GraphArcMapLess(const Graph& graph, const Map& map) 87 : _graph(graph), _map(map) {} 88 89 bool operator()(const Item& left, const Item& right) { 90 return _map[_graph.direct(left, _dir)] < 91 _map[_graph.direct(right, _dir)]; 92 } 93 }; 94 74 95 template <typename _Item> 75 96 class MapStorageBase { … … 107 128 virtual void sort(std::vector<Item>& items) { 108 129 MapLess<Map> less(_map); 130 std::sort(items.begin(), items.end(), less); 131 } 132 }; 133 134 template <typename _Graph, bool _dir, typename _Map, 135 typename _Converter = DefaultConverter<typename _Map::Value> > 136 class GraphArcMapStorage : public MapStorageBase<typename _Graph::Edge> { 137 public: 138 typedef _Map Map; 139 typedef _Converter Converter; 140 typedef _Graph Graph; 141 typedef typename Graph::Edge Item; 142 static const bool dir = _dir; 143 144 private: 145 const Graph& _graph; 146 const Map& _map; 147 Converter _converter; 148 149 public: 150 GraphArcMapStorage(const Graph& graph, const Map& map, 151 const Converter& converter = Converter()) 152 : _graph(graph), _map(map), _converter(converter) {} 153 virtual ~GraphArcMapStorage() {} 154 155 virtual std::string get(const Item& item) { 156 return _converter(_map[_graph.direct(item, dir)]); 157 } 158 virtual void sort(std::vector<Item>& items) { 159 GraphArcMapLess<Graph, dir, Map> less(_graph, _map); 109 160 std::sort(items.begin(), items.end(), less); 110 161 } … … 152 203 } 153 204 return it->second; 205 } 206 }; 207 208 template <typename Graph> 209 struct GraphArcLookUpConverter { 210 const Graph& _graph; 211 const std::map<typename Graph::Edge, std::string>& _map; 212 213 GraphArcLookUpConverter(const Graph& graph, 214 const std::map<typename Graph::Edge, 215 std::string>& map) 216 : _graph(graph), _map(map) {} 217 218 std::string operator()(const typename Graph::Arc& val) { 219 typename std::map<typename Graph::Edge, std::string> 220 ::const_iterator it = _map.find(val); 221 if (it == _map.end()) { 222 throw DataFormatError("Item not found"); 223 } 224 return (_graph.direction(val) ? '+' : '-') + it->second; 154 225 } 155 226 }; … … 739 810 return tmp; 740 811 } 812 813 /// \ingroup lemon_io 814 /// 815 /// \brief LGF writer for directed graphs 816 /// 817 /// This utility writes an \ref lgf-format "LGF" file. 818 template <typename _Graph> 819 class GraphWriter { 820 public: 821 822 typedef _Graph Graph; 823 TEMPLATE_GRAPH_TYPEDEFS(Graph); 824 825 private: 826 827 828 std::ostream* _os; 829 bool local_os; 830 831 Graph& _graph; 832 833 std::string _nodes_caption; 834 std::string _edges_caption; 835 std::string _attributes_caption; 836 837 typedef std::map<Node, std::string> NodeIndex; 838 NodeIndex _node_index; 839 typedef std::map<Edge, std::string> EdgeIndex; 840 EdgeIndex _edge_index; 841 842 typedef std::vector<std::pair<std::string, 843 _writer_bits::MapStorageBase<Node>* > > NodeMaps; 844 NodeMaps _node_maps; 845 846 typedef std::vector<std::pair<std::string, 847 _writer_bits::MapStorageBase<Edge>* > >EdgeMaps; 848 EdgeMaps _edge_maps; 849 850 typedef std::vector<std::pair<std::string, 851 _writer_bits::ValueStorageBase*> > Attributes; 852 Attributes _attributes; 853 854 bool _skip_nodes; 855 bool _skip_edges; 856 857 public: 858 859 /// \brief Constructor 860 /// 861 /// Construct a directed graph writer, which writes to the given 862 /// output stream. 863 GraphWriter(std::ostream& is, Graph& graph) 864 : _os(&is), local_os(false), _graph(graph), 865 _skip_nodes(false), _skip_edges(false) {} 866 867 /// \brief Constructor 868 /// 869 /// Construct a directed graph writer, which writes to the given 870 /// output file. 871 GraphWriter(const std::string& fn, Graph& graph) 872 : _os(new std::ofstream(fn.c_str())), local_os(true), _graph(graph), 873 _skip_nodes(false), _skip_edges(false) {} 874 875 /// \brief Constructor 876 /// 877 /// Construct a directed graph writer, which writes to the given 878 /// output file. 879 GraphWriter(const char* fn, Graph& graph) 880 : _os(new std::ofstream(fn)), local_os(true), _graph(graph), 881 _skip_nodes(false), _skip_edges(false) {} 882 883 /// \brief Copy constructor 884 /// 885 /// The copy constructor transfers all data from the other writer, 886 /// therefore the copied writer will not be usable more. 887 GraphWriter(GraphWriter& other) 888 : _os(other._os), local_os(other.local_os), _graph(other._graph), 889 _skip_nodes(other._skip_nodes), _skip_edges(other._skip_edges) { 890 891 other._os = 0; 892 other.local_os = false; 893 894 _node_index.swap(other._node_index); 895 _edge_index.swap(other._edge_index); 896 897 _node_maps.swap(other._node_maps); 898 _edge_maps.swap(other._edge_maps); 899 _attributes.swap(other._attributes); 900 901 _nodes_caption = other._nodes_caption; 902 _edges_caption = other._edges_caption; 903 _attributes_caption = other._attributes_caption; 904 } 905 906 /// \brief Destructor 907 ~GraphWriter() { 908 for (typename NodeMaps::iterator it = _node_maps.begin(); 909 it != _node_maps.end(); ++it) { 910 delete it->second; 911 } 912 913 for (typename EdgeMaps::iterator it = _edge_maps.begin(); 914 it != _edge_maps.end(); ++it) { 915 delete it->second; 916 } 917 918 for (typename Attributes::iterator it = _attributes.begin(); 919 it != _attributes.end(); ++it) { 920 delete it->second; 921 } 922 923 if (local_os) { 924 delete _os; 925 } 926 } 927 928 private: 929 930 GraphWriter& operator=(const GraphWriter&); 931 932 public: 933 934 /// \name Writing rules 935 /// @{ 936 937 /// \brief Node map reading rule 938 /// 939 /// Add a node map reading rule to the writer. 940 template <typename Map> 941 GraphWriter& nodeMap(const std::string& caption, const Map& map) { 942 checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>(); 943 _writer_bits::MapStorageBase<Node>* storage = 944 new _writer_bits::MapStorage<Node, Map>(map); 945 _node_maps.push_back(std::make_pair(caption, storage)); 946 return *this; 947 } 948 949 /// \brief Node map writing rule 950 /// 951 /// Add a node map writing rule with specialized converter to the 952 /// writer. 953 template <typename Map, typename Converter> 954 GraphWriter& nodeMap(const std::string& caption, const Map& map, 955 const Converter& converter = Converter()) { 956 checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>(); 957 _writer_bits::MapStorageBase<Node>* storage = 958 new _writer_bits::MapStorage<Node, Map, Converter>(map, converter); 959 _node_maps.push_back(std::make_pair(caption, storage)); 960 return *this; 961 } 962 963 /// \brief Edge map writing rule 964 /// 965 /// Add an edge map writing rule to the writer. 966 template <typename Map> 967 GraphWriter& edgeMap(const std::string& caption, const Map& map) { 968 checkConcept<concepts::ReadMap<Edge, typename Map::Value>, Map>(); 969 _writer_bits::MapStorageBase<Edge>* storage = 970 new _writer_bits::MapStorage<Edge, Map>(map); 971 _edge_maps.push_back(std::make_pair(caption, storage)); 972 return *this; 973 } 974 975 /// \brief Edge map writing rule 976 /// 977 /// Add an edge map writing rule with specialized converter to the 978 /// writer. 979 template <typename Map, typename Converter> 980 GraphWriter& edgeMap(const std::string& caption, const Map& map, 981 const Converter& converter = Converter()) { 982 checkConcept<concepts::ReadMap<Edge, typename Map::Value>, Map>(); 983 _writer_bits::MapStorageBase<Edge>* storage = 984 new _writer_bits::MapStorage<Edge, Map, Converter>(map, converter); 985 _edge_maps.push_back(std::make_pair(caption, storage)); 986 return *this; 987 } 988 989 /// \brief Arc map writing rule 990 /// 991 /// Add an arc map writing rule to the writer. 992 template <typename Map> 993 GraphWriter& arcMap(const std::string& caption, const Map& map) { 994 checkConcept<concepts::ReadMap<Arc, typename Map::Value>, Map>(); 995 _writer_bits::MapStorageBase<Edge>* forward_storage = 996 new _writer_bits::GraphArcMapStorage<Graph, true, Map>(_graph, map); 997 _edge_maps.push_back(std::make_pair('+' + caption, forward_storage)); 998 _writer_bits::MapStorageBase<Edge>* backward_storage = 999 new _writer_bits::GraphArcMapStorage<Graph, false, Map>(_graph, map); 1000 _edge_maps.push_back(std::make_pair('-' + caption, backward_storage)); 1001 return *this; 1002 } 1003 1004 /// \brief Arc map writing rule 1005 /// 1006 /// Add an arc map writing rule with specialized converter to the 1007 /// writer. 1008 template <typename Map, typename Converter> 1009 GraphWriter& arcMap(const std::string& caption, const Map& map, 1010 const Converter& converter = Converter()) { 1011 checkConcept<concepts::ReadMap<Arc, typename Map::Value>, Map>(); 1012 _writer_bits::MapStorageBase<Edge>* forward_storage = 1013 new _writer_bits::GraphArcMapStorage<Graph, true, Map, Converter> 1014 (_graph, map, converter); 1015 _edge_maps.push_back(std::make_pair('+' + caption, forward_storage)); 1016 _writer_bits::MapStorageBase<Edge>* backward_storage = 1017 new _writer_bits::GraphArcMapStorage<Graph, false, Map, Converter> 1018 (_graph, map, converter); 1019 _edge_maps.push_back(std::make_pair('-' + caption, backward_storage)); 1020 return *this; 1021 } 1022 1023 /// \brief Attribute writing rule 1024 /// 1025 /// Add an attribute writing rule to the writer. 1026 template <typename Value> 1027 GraphWriter& attribute(const std::string& caption, const Value& value) { 1028 _writer_bits::ValueStorageBase* storage = 1029 new _writer_bits::ValueStorage<Value>(value); 1030 _attributes.push_back(std::make_pair(caption, storage)); 1031 return *this; 1032 } 1033 1034 /// \brief Attribute writing rule 1035 /// 1036 /// Add an attribute writing rule with specialized converter to the 1037 /// writer. 1038 template <typename Value, typename Converter> 1039 GraphWriter& attribute(const std::string& caption, const Value& value, 1040 const Converter& converter = Converter()) { 1041 _writer_bits::ValueStorageBase* storage = 1042 new _writer_bits::ValueStorage<Value, Converter>(value, converter); 1043 _attributes.push_back(std::make_pair(caption, storage)); 1044 return *this; 1045 } 1046 1047 /// \brief Node writing rule 1048 /// 1049 /// Add a node writing rule to the writer. 1050 GraphWriter& node(const std::string& caption, const Node& node) { 1051 typedef _writer_bits::MapLookUpConverter<Node> Converter; 1052 Converter converter(_node_index); 1053 _writer_bits::ValueStorageBase* storage = 1054 new _writer_bits::ValueStorage<Node, Converter>(node, converter); 1055 _attributes.push_back(std::make_pair(caption, storage)); 1056 return *this; 1057 } 1058 1059 /// \brief Edge writing rule 1060 /// 1061 /// Add an edge writing rule to writer. 1062 GraphWriter& edge(const std::string& caption, const Edge& edge) { 1063 typedef _writer_bits::MapLookUpConverter<Edge> Converter; 1064 Converter converter(_edge_index); 1065 _writer_bits::ValueStorageBase* storage = 1066 new _writer_bits::ValueStorage<Edge, Converter>(edge, converter); 1067 _attributes.push_back(std::make_pair(caption, storage)); 1068 return *this; 1069 } 1070 1071 /// \brief Arc writing rule 1072 /// 1073 /// Add an arc writing rule to writer. 1074 GraphWriter& arc(const std::string& caption, const Arc& arc) { 1075 typedef _writer_bits::GraphArcLookUpConverter<Graph> Converter; 1076 Converter converter(_graph, _edge_index); 1077 _writer_bits::ValueStorageBase* storage = 1078 new _writer_bits::ValueStorage<Arc, Converter>(arc, converter); 1079 _attributes.push_back(std::make_pair(caption, storage)); 1080 return *this; 1081 } 1082 1083 /// \name Select section by name 1084 /// @{ 1085 1086 /// \brief Set \c \@nodes section to be read 1087 /// 1088 /// Set \c \@nodes section to be read 1089 GraphWriter& nodes(const std::string& caption) { 1090 _nodes_caption = caption; 1091 return *this; 1092 } 1093 1094 /// \brief Set \c \@edges section to be read 1095 /// 1096 /// Set \c \@edges section to be read 1097 GraphWriter& edges(const std::string& caption) { 1098 _edges_caption = caption; 1099 return *this; 1100 } 1101 1102 /// \brief Set \c \@attributes section to be read 1103 /// 1104 /// Set \c \@attributes section to be read 1105 GraphWriter& attributes(const std::string& caption) { 1106 _attributes_caption = caption; 1107 return *this; 1108 } 1109 1110 /// \name Skipping section 1111 /// @{ 1112 1113 /// \brief Skip writing the node set 1114 /// 1115 /// The \c \@nodes section will be not written to the stream. 1116 GraphWriter& skipNodes() { 1117 LEMON_ASSERT(!_skip_nodes, "Multiple usage of skipNodes() member"); 1118 return *this; 1119 } 1120 1121 /// \brief Skip writing edge set 1122 /// 1123 /// The \c \@edges section will be not written to the stream. 1124 GraphWriter& skipEdges() { 1125 LEMON_ASSERT(!_skip_edges, "Multiple usage of skipEdges() member"); 1126 return *this; 1127 } 1128 1129 /// @} 1130 1131 private: 1132 1133 void writeNodes() { 1134 _writer_bits::MapStorageBase<Node>* label = 0; 1135 for (typename NodeMaps::iterator it = _node_maps.begin(); 1136 it != _node_maps.end(); ++it) { 1137 if (it->first == "label") { 1138 label = it->second; 1139 break; 1140 } 1141 } 1142 1143 *_os << "@nodes"; 1144 if (!_nodes_caption.empty()) { 1145 _writer_bits::writeToken(*_os << ' ', _nodes_caption); 1146 } 1147 *_os << std::endl; 1148 1149 if (label == 0) { 1150 *_os << "label" << '\t'; 1151 } 1152 for (typename NodeMaps::iterator it = _node_maps.begin(); 1153 it != _node_maps.end(); ++it) { 1154 _writer_bits::writeToken(*_os, it->first) << '\t'; 1155 } 1156 *_os << std::endl; 1157 1158 std::vector<Node> nodes; 1159 for (NodeIt n(_graph); n != INVALID; ++n) { 1160 nodes.push_back(n); 1161 } 1162 1163 if (label == 0) { 1164 IdMap<Graph, Node> id_map(_graph); 1165 _writer_bits::MapLess<IdMap<Graph, Node> > id_less(id_map); 1166 std::sort(nodes.begin(), nodes.end(), id_less); 1167 } else { 1168 label->sort(nodes); 1169 } 1170 1171 for (int i = 0; i < static_cast<int>(nodes.size()); ++i) { 1172 Node n = nodes[i]; 1173 if (label == 0) { 1174 std::ostringstream os; 1175 os << _graph.id(n); 1176 _writer_bits::writeToken(*_os, os.str()); 1177 *_os << '\t'; 1178 _node_index.insert(std::make_pair(n, os.str())); 1179 } 1180 for (typename NodeMaps::iterator it = _node_maps.begin(); 1181 it != _node_maps.end(); ++it) { 1182 std::string value = it->second->get(n); 1183 _writer_bits::writeToken(*_os, value); 1184 if (it->first == "label") { 1185 _node_index.insert(std::make_pair(n, value)); 1186 } 1187 *_os << '\t'; 1188 } 1189 *_os << std::endl; 1190 } 1191 } 1192 1193 void writeEdges() { 1194 _writer_bits::MapStorageBase<Edge>* label = 0; 1195 for (typename EdgeMaps::iterator it = _edge_maps.begin(); 1196 it != _edge_maps.end(); ++it) { 1197 if (it->first == "label") { 1198 label = it->second; 1199 break; 1200 } 1201 } 1202 1203 *_os << "@edges"; 1204 if (!_edges_caption.empty()) { 1205 _writer_bits::writeToken(*_os << ' ', _edges_caption); 1206 } 1207 *_os << std::endl; 1208 1209 *_os << '\t' << '\t'; 1210 if (label == 0) { 1211 *_os << "label" << '\t'; 1212 } 1213 for (typename EdgeMaps::iterator it = _edge_maps.begin(); 1214 it != _edge_maps.end(); ++it) { 1215 _writer_bits::writeToken(*_os, it->first) << '\t'; 1216 } 1217 *_os << std::endl; 1218 1219 std::vector<Edge> edges; 1220 for (EdgeIt n(_graph); n != INVALID; ++n) { 1221 edges.push_back(n); 1222 } 1223 1224 if (label == 0) { 1225 IdMap<Graph, Edge> id_map(_graph); 1226 _writer_bits::MapLess<IdMap<Graph, Edge> > id_less(id_map); 1227 std::sort(edges.begin(), edges.end(), id_less); 1228 } else { 1229 label->sort(edges); 1230 } 1231 1232 for (int i = 0; i < static_cast<int>(edges.size()); ++i) { 1233 Edge e = edges[i]; 1234 _writer_bits::writeToken(*_os, _node_index. 1235 find(_graph.u(e))->second); 1236 *_os << '\t'; 1237 _writer_bits::writeToken(*_os, _node_index. 1238 find(_graph.v(e))->second); 1239 *_os << '\t'; 1240 if (label == 0) { 1241 std::ostringstream os; 1242 os << _graph.id(e); 1243 _writer_bits::writeToken(*_os, os.str()); 1244 *_os << '\t'; 1245 _edge_index.insert(std::make_pair(e, os.str())); 1246 } 1247 for (typename EdgeMaps::iterator it = _edge_maps.begin(); 1248 it != _edge_maps.end(); ++it) { 1249 std::string value = it->second->get(e); 1250 _writer_bits::writeToken(*_os, value); 1251 if (it->first == "label") { 1252 _edge_index.insert(std::make_pair(e, value)); 1253 } 1254 *_os << '\t'; 1255 } 1256 *_os << std::endl; 1257 } 1258 } 1259 1260 void writeAttributes() { 1261 if (_attributes.empty()) return; 1262 *_os << "@attributes"; 1263 if (!_attributes_caption.empty()) { 1264 _writer_bits::writeToken(*_os << ' ', _attributes_caption); 1265 } 1266 *_os << std::endl; 1267 for (typename Attributes::iterator it = _attributes.begin(); 1268 it != _attributes.end(); ++it) { 1269 _writer_bits::writeToken(*_os, it->first) << ' '; 1270 _writer_bits::writeToken(*_os, it->second->get()); 1271 *_os << std::endl; 1272 } 1273 } 1274 1275 public: 1276 1277 /// \name Execution of the writer 1278 /// @{ 1279 1280 /// \brief Start the batch processing 1281 /// 1282 /// This function starts the batch processing 1283 void run() { 1284 if (!_skip_nodes) { 1285 writeNodes(); 1286 } 1287 if (!_skip_edges) { 1288 writeEdges(); 1289 } 1290 writeAttributes(); 1291 } 1292 1293 /// \brief Gives back the stream of the writer 1294 /// 1295 /// Gives back the stream of the writer 1296 std::ostream& ostream() { 1297 return *_os; 1298 } 1299 1300 /// @} 1301 }; 1302 1303 /// \relates GraphWriter 1304 template <typename Graph> 1305 GraphWriter<Graph> graphWriter(std::ostream& os, Graph& graph) { 1306 GraphWriter<Graph> tmp(os, graph); 1307 return tmp; 1308 } 1309 1310 /// \relates GraphWriter 1311 template <typename Graph> 1312 GraphWriter<Graph> graphWriter(const std::string& fn, Graph& graph) { 1313 GraphWriter<Graph> tmp(fn, graph); 1314 return tmp; 1315 } 1316 1317 /// \relates GraphWriter 1318 template <typename Graph> 1319 GraphWriter<Graph> graphWriter(const char* fn, Graph& graph) { 1320 GraphWriter<Graph> tmp(fn, graph); 1321 return tmp; 1322 } 741 1323 } 742 1324
Note: See TracChangeset
for help on using the changeset viewer.