简体   繁体   English

BGL - 按上一步加权边缘权重的自定义访问者

[英]BGL - Custom Visitor that weights edge weights by previous step

I have a directed graph, which I know doesn't have any circular dependencies and have "termination" nodes ie they have a custom vertex property, which is a bool that I can check.我有一个有向图,我知道它没有任何循环依赖关系并且有“终止”节点,即它们有一个自定义顶点属性,这是一个我可以检查的布尔值。 Each edge is weighted using the BGL built-in edge weight property.每条边都使用 BGL 内置边权重属性加权。

What I want to do is walk from any vertex along all possible paths, until it hits all the termination nodes that can be reached and track the "weighted" edge weights of each termination node reached.我想要做的是沿着所有可能的路径从任何顶点走,直到它到达所有可以到达的终止节点并跟踪到达的每个终止节点的“加权”边权重。 By this I mean the following is best explained by the following simple example.我的意思是通过以下简单示例可以最好地解释以下内容。

Say from node 4 there are following out edges with weights and if T (a termination)从节点 4 开始,有以下带权重的边,如果 T(终止)

4->1 : 0.25 : T
4->5 : 0.45
4->6 : 0.5
5->2 : 0.65 : T
6->3 : 0.18 
6->7 : 0.44 : T
3->1 : 0.33 : T

I want to return a vector of pairs which is the termination nodes / "weighted" combination of edge weights that were walked on its way to each node, which in this case would be :我想返回一个对的向量,它是在到达每个节点的路上行走的边缘权重的终止节点/“加权”组合,在这种情况下是:

{1, 0.25 + (0.5*0.18*0.33) }
{2, (0.45*0.65)}
{7, (0.5*0.44)}
Final Result : [ {1, 0.2797}, {2, 0.2925}, {7, 0.22}]

By "weighted", i mean each new step is weighted by the product of all previous edge weights walked on a particular path.通过“加权”,我的意思是每个新步骤都由在特定路径上行走的所有先前边缘权重的乘积加权。

So from 4 to termination node 1, there are two paths.所以从4到终端节点1,有两条路径。 An direct edge to 1, weighted by 0.25.直接边为 1,权重为 0.25。 There is also a path that goes 4->6->3->1, so that is 0.5*0.18*0.33.还有一条路径是 4->6->3->1,所以是 0.5*0.18*0.33。 Therefore, for node 1, we have a total resultant weight of 0.25 + (0.5*0.18*0.33) = 0.2797.因此,对于节点 1,我们的总权重为 0.25 + (0.5*0.18*0.33) = 0.2797。

Again from 4 to termination node 2, there is an path to 4->5->2 (0.45*0.65), so node 2 = 0.2925再次从 4 到终止节点 2,有一条到 4->5->2 (0.45*0.65) 的路径,所以节点 2 = 0.2925

And finally 4 to termination node 7, path 4->6->7, (0.5*0.44), so node 7 = 0.22最后 4 到终止节点 7,路径 4->6->7,(0.5*0.44),所以节点 7 = 0.22

Is this possible in BGL, I presume I need some sort of custom visitor / predecessor?这在 BGL 中是否可行,我想我需要某种自定义访问者/前任?

Any help much appreciated.非常感谢任何帮助。

Your example calculations are pretty confusing.您的示例计算非常混乱。 I'm assuming you meant to do what your description says: "sum of weighted edge weights that were walked on its way to each node" , so:我假设您打算按照您的描述进行操作: “在到达每个节点的路上行走的加权边权重的总和” ,因此:

{1, 0.25}
{2, (0.45+0.65)}
{7, (0.5+0.44)}
Final Result : [ {1, 0.25}, {2, 1.1}, {7, 0.94}]

This is a shortest-paths problem.这是一个最短路径问题。 If you eg use dijkstra_shortest_paths the result you are looking for would be in distance_map .例如,如果您使用dijkstra_shortest_paths则您要查找的结果将在distance_map Simply select the "termination vertices" from that map and you're done:只需从该地图中选择“终止顶点”即可:

Live On Coliru 住在 Coliru

//#include <boost/spirit/home/x3.hpp>
#include <boost/graph/adjacency_list.hpp>

using Weight = double;
struct EdgeProps { Weight weight = 0; };

using Graph = boost::adjacency_list<
    boost::vecS, boost::vecS, boost::directedS, boost::no_property, EdgeProps>;

Graph make_sample();

#include <boost/graph/dijkstra_shortest_paths.hpp>
#include <boost/graph/graph_utility.hpp>

int main() {

    auto const g     = make_sample();
    auto const start = vertex(4, g);

    print_graph(g);

    // property-maps maps for dijkstra:
    auto constexpr INF = std::numeric_limits<Weight>::infinity();
    std::vector<Graph::vertex_descriptor> pred(num_vertices(g));
    std::vector<Weight> dist(num_vertices(g), INF);

    dijkstra_shortest_paths(g, start, boost::predecessor_map(pred.data())
            .distance_map(dist.data())
            .weight_map(get(&EdgeProps::weight, g))
            .distance_inf(INF));

    // print results
    std::cout << "Final Result : [ ";

    for (auto vd : boost::make_iterator_range(vertices(g))) {
        if (INF != dist[vd] && 0 == out_degree(vd, g)) {         // if reachable and leaf,
            std::cout << "{" << vd << ", " << dist[vd] << "}, "; // print total distance from start
        }
    }

    std::cout << "}\n";
}

Graph make_sample() {
    Graph g(8);
    add_edge(4, 1, EdgeProps{0.25}, g); // : T
    add_edge(4, 5, EdgeProps{0.45}, g);
    add_edge(4, 6, EdgeProps{0.5},  g);
    add_edge(5, 2, EdgeProps{0.65}, g); // : T
    add_edge(6, 3, EdgeProps{0.18}, g);
    add_edge(6, 7, EdgeProps{0.44}, g); // : T
    add_edge(3, 1, EdgeProps{0.33}, g); // : T
    return g;
}

Prints印刷

0 --> 
1 --> 
2 --> 
3 --> 1 
4 --> 1 5 6 
5 --> 2 
6 --> 3 7 
7 --> 
Final Result : [ {1, 0.25}, {2, 1.1}, {7, 0.94}, }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM