C++ 贝尔曼-福特算法工作中的奇异性

C++ 贝尔曼-福特算法工作中的奇异性,c++,boost,boost-graph,bellman-ford,C++,Boost,Boost Graph,Bellman Ford,如果specify-log()权重显示为“负循环”,我无法理解会出现什么问题。如果remove log(),则算法可以工作,但不存在负循环 int main() { typedef double Weight; typedef property<edge_weight_t, Weight> WeightProperty; typedef property<vertex_name_t, string> NameProperty; typede

如果specify-log()权重显示为“负循环”,我无法理解会出现什么问题。如果remove log(),则算法可以工作,但不存在负循环

int main() {
    typedef double Weight;
    typedef property<edge_weight_t, Weight> WeightProperty;
    typedef property<vertex_name_t, string> NameProperty;
    typedef adjacency_list < listS, vecS, directedS, NameProperty, WeightProperty > Graph;
    typedef property_map < Graph, vertex_index_t >::type IndexMap;
    typedef property_map < Graph, vertex_name_t >::type NameMap;
    typedef graph_traits < Graph >::vertex_descriptor Vertex;
    typedef iterator_property_map < Vertex*, IndexMap, Vertex, Vertex& > PredecessorMap;
    typedef iterator_property_map < Weight*, IndexMap, Weight, Weight& > DistanceMap;

    // Create a graph
    Graph g;    
    graph_traits<Graph>::vertex_descriptor A = add_vertex(string("A"),g);
    graph_traits<Graph>::vertex_descriptor B = add_vertex(string("B"),g);
    graph_traits<Graph>::vertex_descriptor C = add_vertex(string("C"),g);
    graph_traits<Graph>::vertex_descriptor D = add_vertex(string("D"),g);
    add_edge(A, B, -log(0.741), g);
    add_edge(A, C, -log(0.657), g);
    add_edge(A, D, -log(1.061), g);
    add_edge(B, A, -log(1.350), g);
    add_edge(B, C, -log(0.888), g);
    add_edge(B, D, -log(1.433), g);
    add_edge(C, A, -log(1.521), g);
    add_edge(C, B, -log(1.126), g);
    add_edge(C, D, -log(1.614), g);
    add_edge(D, A, -log(0.943), g);
    add_edge(D, B, -log(0.698), g);
    add_edge(D, C, -log(0.620), g);

    property_map<Graph, edge_weight_t>::type weight_pmap = get(edge_weight_t(), g);

    int nb_vertices = num_vertices(g);
    int  inf = (numeric_limits<int>::max)();
    vector<float> distance(nb_vertices, inf);
    vector<size_t> parent(nb_vertices);
    for (size_t i = 0; i<nb_vertices; ++i)
        parent[i] = i;
    //starting vertex
    distance[B] = 0;

    //bool r = bellman_ford_shortest_paths(g, nb_vertices, weight_pmap, &parent[0], &distance[0],closed_plus<int>(), std::less<int>(), default_bellman_visitor());
    bool r = bellman_ford_shortest_paths(g, nb_vertices, weight_map(weight_pmap).distance_map(&distance[0]).predecessor_map(&parent[0]));

    if (r)
        for (size_t i = 1; i<nb_vertices; ++i)
            cout << distance[i]  << endl;
    else
        cout << "negative cycle" << endl;
    return EXIT_SUCCESS;
}
intmain(){
typedef双倍重量;
typedef属性权重属性;
typedef属性NameProperty;
typedef adjacence_list<列表、向量、定向、名称属性、权重属性>图形;
typedef属性映射::type IndexMap;
typedef property_map<图形,顶点名称_t>::type NameMap;
typedef graph_traits:顶点描述符顶点;
typedef迭代器属性映射PredecessorMap;
typedef迭代器属性映射DistanceMap;
//创建图形
图g;
图特征:顶点描述符A=添加顶点(字符串(“A”),g);
图特征::顶点描述符B=添加顶点(字符串(“B”),g);
图特征:顶点描述符C=添加顶点(字符串(“C”),g);
图特征::顶点描述符D=添加顶点(字符串(“D”),g);
加上边缘(A,B,-对数(0.741),g);
添加_边(A,C,-log(0.657),g);
加上边缘(A,D,-log(1.061),g);
添加_边(B,A,-log(1.350),g);
添加_边(B,C,-log(0.888),g);
添加_边(B,D,-log(1.433),g);
加上边缘(C,A,-log(1.521),g);
添加_边(C,B,-log(1.126),g);
加上边缘(C,D,-log(1.614),g);
加上边缘(D,A,-log(0.943),g);
加上边缘(D,B,-log(0.698),g);
加上边缘(D,C,-log(0.620),g);
属性映射::键入weight\u pmap=get(edge\u weight\u t(),g);
int nb_顶点=num_顶点(g);
int inf=(数值限制::max)();
向量距离(nb_顶点,inf);
向量父(nb_顶点);

对于(size_t i=0;i),对数惩罚函数通常用于独立概率,根据定义,独立概率小于1.0


-log(number\u大于\u-one)=负数,因此您的路径得分为负数。

如果存在负循环,则根据定义,您可以使任何连接的路径的成本为负(只是在循环中无限循环).这是一个错误情况。

这是可以理解的。我不明白如何更改代码,以便贝尔曼·福特工作。在图表中,权重是货币的价格。