更改提升图中的边缘目标
Change edge target in boost graph
假设我有一个包含三个顶点的简单图形,我如何将输出边 0 更改为 2 而不是 1
注意:我不想在创建图表时这样做。
假设您遗漏的简单图表:
auto simple_graph() {
boost::adjacency_list<> g;
add_edge(0, 1, g);
add_edge(1, 2, g);
return g;
}
现在,您可以做的最简单的 for this graph model 是
// change (0,1) to (0,2):
remove_edge(0, 1, g);
add_edge(0, 2, g);
演示
#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/graphviz.hpp>
auto simple_graph() {
boost::adjacency_list<> g;
add_edge(0, 1, g);
add_edge(1, 2, g);
return g;
}
int main() {
auto g = simple_graph();
write_graphviz(std::cout, g);
// change (0,1) to (0,2):
remove_edge(0, 1, g);
add_edge(0, 2, g);
write_graphviz(std::cout, g);
}
版画
digraph G {
0;
1;
2;
0->1 ;
1->2 ;
}
digraph G {
0;
1;
2;
0->2 ;
1->2 ;
}
所以确实 变成了
其他图表类型
如果您有其他图形类型,其他方法就很自然了:
#include <boost/graph/edge_list.hpp>
#include <boost/graph/graphviz.hpp>
int main() {
std::vector edges{std::pair{0, 1}, {1, 2}};
boost::edge_list g(edges.begin(), edges.end());
// change (0,1) to (0,2):
edges[0].second = 2;
}
更新:奖金保留属性
我会写一个 5 行辅助函数:
template <typename V, typename G>
void update_edge_target(V source, V target, V new_target, G& g) {
if (auto [e, exists] = edge(source, target, g); exists) {
auto prop = std::move(g[e]);
remove_edge(e, g);
add_edge(source, new_target, prop, g);
}
}
Note: I don't think BGL supports move semantics, so splitting the last
line could improve efficiency:
e = add_edge(source, new_target, g);
g[e] = std::move(prop);
#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/graphviz.hpp>
struct EdgeProps {
std::map<int, std::string> lots;
std::string more;
};
auto simple_graph() {
using namespace boost;
adjacency_list<vecS, vecS, directedS, no_property, EdgeProps> g;
add_edge(0, 1,
{{
{1, "one"},
{2, "two"},
{3, "three"},
},
"very heavy data!"},
g);
add_edge(1, 2,
{{
{4, "four"},
{5, "five"},
{6, "size"},
},
"needs preserving"},
g);
return g;
}
template <typename V, typename G>
void update_edge_target(V source, V target, V new_target, G& g) {
if (auto [e, exists] = edge(source, target, g); exists) {
auto prop = std::move(g[e]);
remove_edge(e, g);
add_edge(source, new_target, prop, g);
}
}
// for debug output
#include <fmt/ranges.h>
template <typename G> struct writer : boost::default_writer {
G const& g;
explicit writer(G const& g) : g(g) {}
void operator()(std::ostream& os, auto const& desc) const { handle(os, g[desc]); }
private:
void handle(std::ostream& os, boost::no_property) const { os << "[]"; }
void handle(std::ostream& os, EdgeProps const& ep) const {
os << "[label=" << boost::escape_dot_string(ep.more)
<< ",extra=" << boost::escape_dot_string(fmt::format("{}", ep.lots))
<< "]";
}
};
int main() {
auto g = simple_graph();
writer w{g};
write_graphviz(std::cout, g, w, w);
// change (0,1) to (0,2):
update_edge_target(0, 1, 2, g);
write_graphviz(std::cout, g, w, w);
}
版画
digraph G {
0[];
1[];
2[];
0->1 [label="very heavy data!",extra="{1: \"one\", 2: \"two\", 3: \"three\"}"];
1->2 [label="needs preserving",extra="{4: \"four\", 5: \"five\", 6: \"size\"}"];
}
digraph G {
0[];
1[];
2[];
0->2 [label="very heavy data!",extra="{1: \"one\", 2: \"two\", 3: \"three\"}"];
1->2 [label="needs preserving",extra="{4: \"four\", 5: \"five\", 6: \"size\"}"];
}
呈现:
到
假设我有一个包含三个顶点的简单图形,我如何将输出边 0 更改为 2 而不是 1
注意:我不想在创建图表时这样做。
假设您遗漏的简单图表:
auto simple_graph() {
boost::adjacency_list<> g;
add_edge(0, 1, g);
add_edge(1, 2, g);
return g;
}
现在,您可以做的最简单的 for this graph model 是
// change (0,1) to (0,2):
remove_edge(0, 1, g);
add_edge(0, 2, g);
演示
#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/graphviz.hpp>
auto simple_graph() {
boost::adjacency_list<> g;
add_edge(0, 1, g);
add_edge(1, 2, g);
return g;
}
int main() {
auto g = simple_graph();
write_graphviz(std::cout, g);
// change (0,1) to (0,2):
remove_edge(0, 1, g);
add_edge(0, 2, g);
write_graphviz(std::cout, g);
}
版画
digraph G {
0;
1;
2;
0->1 ;
1->2 ;
}
digraph G {
0;
1;
2;
0->2 ;
1->2 ;
}
所以确实
其他图表类型
如果您有其他图形类型,其他方法就很自然了:
#include <boost/graph/edge_list.hpp>
#include <boost/graph/graphviz.hpp>
int main() {
std::vector edges{std::pair{0, 1}, {1, 2}};
boost::edge_list g(edges.begin(), edges.end());
// change (0,1) to (0,2):
edges[0].second = 2;
}
更新:奖金保留属性
我会写一个 5 行辅助函数:
template <typename V, typename G>
void update_edge_target(V source, V target, V new_target, G& g) {
if (auto [e, exists] = edge(source, target, g); exists) {
auto prop = std::move(g[e]);
remove_edge(e, g);
add_edge(source, new_target, prop, g);
}
}
Note: I don't think BGL supports move semantics, so splitting the last line could improve efficiency:
e = add_edge(source, new_target, g); g[e] = std::move(prop);
#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/graphviz.hpp>
struct EdgeProps {
std::map<int, std::string> lots;
std::string more;
};
auto simple_graph() {
using namespace boost;
adjacency_list<vecS, vecS, directedS, no_property, EdgeProps> g;
add_edge(0, 1,
{{
{1, "one"},
{2, "two"},
{3, "three"},
},
"very heavy data!"},
g);
add_edge(1, 2,
{{
{4, "four"},
{5, "five"},
{6, "size"},
},
"needs preserving"},
g);
return g;
}
template <typename V, typename G>
void update_edge_target(V source, V target, V new_target, G& g) {
if (auto [e, exists] = edge(source, target, g); exists) {
auto prop = std::move(g[e]);
remove_edge(e, g);
add_edge(source, new_target, prop, g);
}
}
// for debug output
#include <fmt/ranges.h>
template <typename G> struct writer : boost::default_writer {
G const& g;
explicit writer(G const& g) : g(g) {}
void operator()(std::ostream& os, auto const& desc) const { handle(os, g[desc]); }
private:
void handle(std::ostream& os, boost::no_property) const { os << "[]"; }
void handle(std::ostream& os, EdgeProps const& ep) const {
os << "[label=" << boost::escape_dot_string(ep.more)
<< ",extra=" << boost::escape_dot_string(fmt::format("{}", ep.lots))
<< "]";
}
};
int main() {
auto g = simple_graph();
writer w{g};
write_graphviz(std::cout, g, w, w);
// change (0,1) to (0,2):
update_edge_target(0, 1, 2, g);
write_graphviz(std::cout, g, w, w);
}
版画
digraph G {
0[];
1[];
2[];
0->1 [label="very heavy data!",extra="{1: \"one\", 2: \"two\", 3: \"three\"}"];
1->2 [label="needs preserving",extra="{4: \"four\", 5: \"five\", 6: \"size\"}"];
}
digraph G {
0[];
1[];
2[];
0->2 [label="very heavy data!",extra="{1: \"one\", 2: \"two\", 3: \"three\"}"];
1->2 [label="needs preserving",extra="{4: \"four\", 5: \"five\", 6: \"size\"}"];
}
呈现: