【问题标题】:How do I define a custom distance in Boost Dijkstra?如何在 Boost Dijkstra 中定义自定义距离?
【发布时间】:2012-12-03 17:23:38
【问题描述】:

我目前正在查看 Boost Dijkstra 的文档 - http://www.boost.org/doc/libs/1_52_0/libs/graph/doc/dijkstra_shortest_paths.html;我的目标是在计算我的距离时修改距离组合以获得“最大值”而不是“加号”。文档是这样说的:

IN: distance_combine(CombineFunction cmb)
This function is used to combine distances to compute the distance of a path. The
CombineFunction type must be a model of Binary Function. The first argument typ
of the binary function must match the value type of the DistanceMap property map
and the second argument type must match the value type of the WeightMap property
map. The result type must be the same type as the distance value type.
Default: closed_plus<D> with D=typename property_traits<DistanceMap>::value_type

定义这样的组合函数的语法是什么?我试过摸索 std::max,但我的编译器似乎对此并不满意。

【问题讨论】:

    标签: c++ boost graph dijkstra boost-graph


    【解决方案1】:

    我会采用懒惰的方式,只是提供一些代码来说明如何做到这一点:)

    #include <boost/graph/dijkstra_shortest_paths.hpp>
    #include <boost/graph/adjacency_list.hpp>
    
    struct Edge {
            Edge(float weight_) : weight(weight_) {}
            float weight;
    };
    
    // simple function
    float combine(float a, float b){
            return std::max(a, b);
    }
    
    // functor
    struct Combine{
            // Some internal state
    
            float operator()(float a, float b) const {
                    return std::max(a, b);
            }
    };
    
    int main(int, char**){
            typedef boost::adjacency_list < boost::vecS, boost::vecS, boost::directedS, boost::no_property, Edge > graph_t;
            typedef boost::graph_traits < graph_t >::vertex_descriptor vertex_t;
            graph_t g;
            vertex_t a = boost::add_vertex(g);
            vertex_t b = boost::add_vertex(g);
            vertex_t c = boost::add_vertex(g);
            vertex_t d = boost::add_vertex(g);
            boost::add_edge(a, b, Edge(3), g);
            boost::add_edge(b, c, Edge(3), g);
            boost::add_edge(a, d, Edge(1), g);
            boost::add_edge(d, c, Edge(4), g);
    
            std::vector<vertex_t> preds(4);
    
            // Traditional dijsktra (sum)
            boost::dijkstra_shortest_paths(g, a, boost::predecessor_map(&preds[0]).weight_map(boost::get(&Edge::weight,g)));
            assert(preds[c] == d);
            assert(preds[d] == a);
    
            // Dijkstra with custom combine as a function
            boost::dijkstra_shortest_paths(g, a, boost::predecessor_map(&preds[0]).weight_map(boost::get(&Edge::weight,g)).distance_combine(&combine));
            assert(preds[c] == b);
            assert(preds[b] == a);
    
            // Dijkstra with custom combine as a functior
            boost::dijkstra_shortest_paths(g, a, boost::predecessor_map(&preds[0]).weight_map(boost::get(&Edge::weight,g)).distance_combine(Combine()));
            // Dijkstra with custom combine as a lambda
            boost::dijkstra_shortest_paths(g, a, boost::predecessor_map(&preds[0]).weight_map(boost::get(&Edge::weight,g)).distance_combine([](float a, float b){return std::max(a,b);}));
    
            return 0;
    }
    

    【讨论】:

      【解决方案2】:

      可能将其参数设为模板可能会使事情变得有些困难......

      尝试(其中 T 是您的距离类型)

      T comb(T& a, T& b) { return std::max(a, b); }
      

      并通过梳子。

      【讨论】:

      • 确实,结果有点摸不着头脑。我定义了template &lt;class T&gt; T comb(T&amp; a, T&amp; b) { return std::max(a, b); },并在我的 Dijkstra 中传递了 comb。谢谢!
      猜你喜欢
      • 2015-04-30
      • 2016-02-19
      • 1970-01-01
      • 2015-05-12
      • 1970-01-01
      • 2017-02-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多