您可以按照您的建议进行操作,这需要使用注册属性标签BOOST_INSTALL_PROPERTY
(参见example/examples/edge_property.cpp 以获取示例)。相关片段:
namespace boost {
enum edge_flow_t { edge_flow };
enum edge_capacity_t { edge_capacity };
BOOST_INSTALL_PROPERTY(edge, flow);
BOOST_INSTALL_PROPERTY(edge, capacity);
}
现在,您可以在属性定义中使用新的属性标记,就像使用内置标记之一一样。
typedef property<capacity_t, int> Cap;
typedef property<flow_t, int, Cap> EdgeProperty;
typedef adjacency_list<vecS, vecS, no_property, EdgeProperty> Graph;
vertex_bundle_t
但是,由于您的用例如此频繁,因此任何用户定义的 struct:和都已经有一个内置标记edge_bundle_t
:
捆绑属性
这是一个使用它的示例。文档:https ://www.boost.org/doc/libs/1_75_0/libs/graph/doc/bundles.html
住在科利鲁
#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/graph_utility.hpp>
struct road_info {
unsigned miles;
bool pothole;
};
using Graph = boost::adjacency_list<boost::listS, boost::vecS,
boost::undirectedS, road_info>;
using Vertex = Graph::vertex_descriptor;
using Edge = Graph::edge_descriptor;
int main() {
Graph roadMap;
Vertex road1 = add_vertex(road_info{15, false}, roadMap);
Vertex road2 = add_vertex(road_info{3, true}, roadMap);
/*Vertex road3 =*/ add_vertex(road_info{27, false}, roadMap);
add_edge(road1, road2, roadMap);
print_graph(roadMap);
auto bmap = get(boost::vertex_bundle, roadMap);
for (Vertex v : boost::make_iterator_range(vertices(roadMap))) {
road_info& bundle = bmap[v];
// or even easier
// road_info& info = roadMap[v];
auto& [miles, pothole] = roadMap[v]; // c++17
std::cout << "Vertex #" << v << " " << miles << " miles, "
<< "pothole:" << std::boolalpha << pothole << "\n";
}
// individual maps
auto miles_map = get(&road_info::miles, roadMap);
auto poth_map = get(&road_info::pothole, roadMap);
for (Vertex v : boost::make_iterator_range(vertices(roadMap))) {
std::cout << "Vertex #" << v << " " << miles_map[v] << " miles, "
<< "pothole:" << std::boolalpha << poth_map[v] << "\n";
put(poth_map, v, false); // reset pothole
}
}
印刷
0 <--> 1
1 <--> 0
2 <-->
Vertex #0 15 miles, pothole:false
Vertex #1 3 miles, pothole:true
Vertex #2 27 miles, pothole:false
Vertex #0 15 miles, pothole:false
Vertex #1 3 miles, pothole:true
Vertex #2 27 miles, pothole:false
更新:边缘捆绑
对于评论,使其成为边缘捆绑是肤浅的修改:
住在科利鲁
#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/graph_utility.hpp>
struct road_info {
unsigned miles;
bool pothole;
};
using Graph =
boost::adjacency_list<boost::listS, boost::vecS, boost::undirectedS,
boost::no_property, road_info>;
using Vertex = Graph::vertex_descriptor;
using Edge = Graph::edge_descriptor;
int main() {
Graph roadMap(3);
add_edge(0, 1, road_info{15, false}, roadMap);
add_edge(1, 2, road_info{3, true}, roadMap);
print_graph(roadMap);
auto bmap = get(boost::edge_bundle, roadMap);
for (Edge e : boost::make_iterator_range(edges(roadMap))) {
road_info& bundle = bmap[e];
// or even easier
// road_info& info = roadMap[e];
auto& [miles, pothole] = roadMap[e]; // c++17
std::cout << "Edge " << e << " " << miles << " miles, "
<< "pothole:" << std::boolalpha << pothole << "\n";
}
// individual maps
auto miles_map = get(&road_info::miles, roadMap);
auto poth_map = get(&road_info::pothole, roadMap);
for (Edge e : boost::make_iterator_range(edges(roadMap))) {
std::cout << "Edge " << e << " " << miles_map[e] << " miles, "
<< "pothole:" << std::boolalpha << poth_map[e] << "\n";
put(poth_map, e, false); // reset pothole
}
}
印刷:
0 <--> 1
1 <--> 0 2
2 <--> 1
Edge (0,1) 15 miles, pothole:false
Edge (1,2) 3 miles, pothole:true
Edge (0,1) 15 miles, pothole:false
Edge (1,2) 3 miles, pothole:true
对于受虐狂
如果您坚持,您当然可以安装属性标签。接触个别成员会很不舒服(并且可能效率低下),但你这样做:
住在科利鲁
#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/graph_utility.hpp>
#include <boost/property_map/transform_value_property_map.hpp>
struct road_info {
unsigned miles;
bool pothole;
};
namespace boost {
struct edge_road_info_t {};
BOOST_INSTALL_PROPERTY(edge, road_info);
static inline constexpr edge_road_info_t road_info{};
}
using Graph =
boost::adjacency_list<boost::listS, boost::vecS, boost::undirectedS,
boost::no_property,
boost::property<boost::edge_road_info_t, road_info> >;
using Vertex = Graph::vertex_descriptor;
using Edge = Graph::edge_descriptor;
int main() {
Graph roadMap(3);
add_edge(0, 1, road_info{15, false}, roadMap);
add_edge(1, 2, road_info{3, true}, roadMap);
print_graph(roadMap);
auto info_map = get(boost::road_info, roadMap);
for (Edge e : boost::make_iterator_range(edges(roadMap))) {
road_info& info = info_map[e];
// or even easier
// road_info& info = roadMap[e];
auto& [miles, pothole] = info; // c++17
std::cout << "Edge " << e << " " << miles << " miles, "
<< "pothole:" << std::boolalpha << pothole << "\n";
}
// individual maps
auto miles_map = boost::make_transform_value_property_map(
std::mem_fn(&road_info::miles), info_map);
auto poth_map = boost::make_transform_value_property_map(
std::mem_fn(&road_info::pothole), info_map);
for (Edge e : boost::make_iterator_range(edges(roadMap))) {
std::cout << "Edge " << e << " " << miles_map[e] << " miles, "
<< "pothole:" << std::boolalpha << poth_map[e] << "\n";
put(poth_map, e, false); // reset pothole
}
}
再次打印相同的输出。