[英]Boost Graph Library: Adding vertices with same identification
如何使用 BGL 表示文件路徑? 考慮如下路徑: root/a/a/a/a/a
對應的圖是 'root'->'a'->'a'->...
是否可以添加多個共享相同名稱的頂點? 找不到明確的答案。
當然。 只要名稱不是標識符(身份意味着唯一)。
文件系統路徑的整體思想是路徑是唯一的。 因此,您可能想要的是將唯一名稱作為節點的路徑,並在顯示時選擇要顯示的路徑部分。
對於使用內部頂點名稱的優雅演示¹:
using G = boost::adjacency_list<boost::vecS, boost::vecS, boost::directedS, fs::path>;
using V = G::vertex_descriptor;
現在您可以向圖形添加任何路徑:
void add_path(fs::path p, G& g) {
if (p.empty()) return;
if (!p.has_root_path()) p = fs::absolute(p);
std::optional<V> prev;
fs::path curr;
for (auto const& el : p) {
curr /= el;
auto v = add_vertex(curr, g);
if (prev)
add_edge(*prev, v, g);
prev = v;
}
}
我們必須告訴 BGL 使用std::identity
從fs::path
獲取內部名稱:
template <> struct boost::graph::internal_vertex_name<fs::path> {
struct type : std::identity {
using result_type = fs::path;
};
};
現在,演示:
G g;
add_path("/root/a/a/a/a/a", g);
add_path("test.cpp", g);
要使用頂點 ID 進行打印:
print_graph(g);
要使用唯一節點路徑進行打印:
auto paths = get(boost::vertex_bundle, g);
print_graph(g, paths);
僅使用本地名稱打印:
auto filename = std::mem_fn(&fs::path::filename);
auto local = make_transform_value_property_map(filename, paths);
print_graph(g, local);
#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/graph_utility.hpp>
#include <boost/property_map/transform_value_property_map.hpp>
#include <filesystem>
using std::filesystem::path;
template <>
struct boost::graph::internal_vertex_name<path> {
struct type : std::identity {
using result_type = path;
};
};
using G =
boost::adjacency_list<boost::vecS, boost::vecS, boost::directedS, path>;
using V = G::vertex_descriptor;
void add_path(path p, G& g) {
if (p.empty()) return;
if (!p.has_root_path()) p = absolute(p);
std::optional<V> prev;
path curr;
for (auto const& el : p) {
curr /= el;
auto v = add_vertex(curr, g);
if (prev) add_edge(*prev, v, g);
prev = v;
}
}
int main() {
G g;
add_path("/root/a/a/a/a/a", g);
add_path("test.cpp", g);
// To print using the vertex ids:
print_graph(g, std::cout << " ---- vertex index\n");
// To print using the unique node paths:
auto paths = get(boost::vertex_bundle, g);
print_graph(g, paths, std::cout << " --- node path\n");
// To print using only the local names:
auto filename = std::mem_fn(&path::filename);
auto local = make_transform_value_property_map(filename, paths);
print_graph(g, local, std::cout << " --- local name\n");
}
打印(在我的機器上, test.cpp
存在於/home/sehe/Projects/stackoverflow
中):
---- vertex index
0 --> 1 7
1 --> 2
2 --> 3
3 --> 4
4 --> 5
5 --> 6
6 -->
7 --> 8
8 --> 9
9 --> 10
10 --> 11
11 -->
--- node path
"/" --> "/root" "/home"
"/root" --> "/root/a"
"/root/a" --> "/root/a/a"
"/root/a/a" --> "/root/a/a/a"
"/root/a/a/a" --> "/root/a/a/a/a"
"/root/a/a/a/a" --> "/root/a/a/a/a/a"
"/root/a/a/a/a/a" -->
"/home" --> "/home/sehe"
"/home/sehe" --> "/home/sehe/Projects"
"/home/sehe/Projects" --> "/home/sehe/Projects/stackoverflow"
"/home/sehe/Projects/stackoverflow" --> "/home/sehe/Projects/stackoverflow/test.cpp"
"/home/sehe/Projects/stackoverflow/test.cpp" -->
--- local name
"" --> "root" "home"
"root" --> "a"
"a" --> "a"
"a" --> "a"
"a" --> "a"
"a" --> "a"
"a" -->
"home" --> "sehe"
"sehe" --> "Projects"
"Projects" --> "stackoverflow"
"stackoverflow" --> "test.cpp"
"test.cpp" -->
圖表可視化 output:
write_graphviz(std::cout, g, boost::label_writer{local});
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.