You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何Networkx的Dijkstra算法比Boost的更快?

C++ Boost图库Dijkstra算法性能不如Python NetworkX的问题验证

我最初用Python的NetworkX库实现Dijkstra算法,为提升性能改用C的Boost图库,却意外发现Python版本的最短路径计算速度反而更快。我是C新手,不确定是否存在实现问题,以下是复现问题的示例代码及编译配置,希望有人帮忙验证是否仅我遇到此问题。

Python代码

import networkx as nx
import csv
import time
import numpy as np

def write_graph_to_csv(G):
    # Open a CSV file in write mode
    with open('/Users/robertbenassai/Documents/UOC/k_shortest_path_betweenness/KSP_cpp/graph.csv', 
              'w', newline='') as csvfile:
        # Create a CSV writer object
        csvwriter = csv.writer(csvfile)
    
        # Write the header row (optional)
        csvwriter.writerow(['vertex1', 'vertex2', 'edge_weight'])
    
        # Write edges and their weights to the CSV file
        for u, v, weight in G.edges(data='length'):
            csvwriter.writerow([u, v, weight])

    print('Graph has been written to graph.csv')


graph = nx.random_geometric_graph(100, 0.2)
pos_RG = nx.get_node_attributes(graph, 'pos')
edge_lens = {edge: np.linalg.norm(np.array(pos_RG[edge[1]]) - np.array(pos_RG[edge[0]])) for edge 
              in graph.edges}

nx.set_edge_attributes(graph, edge_lens, name = "length")

nx.draw_networkx(graph, pos_RG)


times_del = []
for i in range(100):
    t1 = time.time()
    nx.single_source_dijkstra(graph, 1, weight = "length")
    times_del.append(time.time()-t1)
    # print(time.time()-t1)
print(np.mean(times_del))

write_graph_to_csv(graph)

C++代码

#include <iostream>
#include <vector>
#include <chrono>
#include <numeric>

#include <boost/property_map/dynamic_property_map.hpp>
#include <boost/property_map/property_map.hpp>
#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/dijkstra_shortest_paths.hpp>
#include <boost/tokenizer.hpp>

using namespace boost;
using namespace std::chrono;

struct NodeProperties {
    int id;

};

typedef boost::adjacency_list<
    boost::listS,                
    boost::vecS,                 
    boost::undirectedS,          
    NodeProperties,              
    boost::property<boost::edge_weight_t, double> 
> Graph;

// typedef adjacency_list<listS, vecS, undirectedS,
//     no_property, property<edge_weight_t, double> > Graph; 

typedef graph_traits<Graph>::vertex_descriptor Vertex;
typedef graph_traits<Graph>::edge_descriptor Edge;
typedef std::pair<int, int> EdgePair;

int main() {

    /*
    
    READING CSV FILE: EDGE[0], EDGE[1], WEIGHT

    */

    Graph delaunay(0);

    std::ifstream file("graph.csv");
    std::string line;
    std::getline(file, line);

    while (std::getline(file, line)) {
        boost::tokenizer<boost::escaped_list_separator<char>> tokens(line);
        auto tokenIterator = tokens.begin();
        int vertex1 = std::stoi(*tokenIterator++);
        int vertex2 = std::stoi(*tokenIterator++);
        double weight = std::stod(*tokenIterator);
        // Add edge to the graph with the given weight
        Edge e = add_edge(vertex1, vertex2, delaunay).first;
        put(edge_weight, delaunay, e, weight);
        // boost::add_edge(vertex1, vertex2, EdgeProperties{weight}, delaunay);
    }


    std::vector<int> path(num_vertices(delaunay), -1);  // Initialize path with -1 for all vertices
    std::vector<double> distances(num_vertices(delaunay));  // Store distances for Dijkstra's algorithm
    std::vector<double> times(100);
    for (int i = 0; 100>i; i++){
        auto t1 = high_resolution_clock::now();

        boost::dijkstra_shortest_paths(delaunay, 1,
                                    predecessor_map(make_iterator_property_map(path.begin(), get(vertex_index, delaunay)))
                                    .distance_map(make_iterator_property_map(distances.begin(), get(vertex_index, delaunay))));
        
        auto t2 = high_resolution_clock::now();
        std::chrono::duration<float> deltat = (t2 - t1);
        std::cout << "Dijkstra time: "
        << deltat.count() << " seconds" << std::endl;
        times[i] = deltat.count();
    }
    double mean_t = std::accumulate(times.begin(), times.end(), 0.0) / times.size();
    printf("mean time: %lf", mean_t);
    return 0;
}

编译配置(Makefile)

INC_DIRS = /opt/homebrew/include
LIB_DIRS = /opt/homebrew/lib

CPPFLAGS += -std=c++17

# Link igraph and other libraries
LDFLAGS = -ligraph -lboost_filesystem -lboost_graph

Yen: k_shortest_paths.cpp
    $(CXX) $(CFLAGS) $(CPPFLAGS) -I$(INC_DIRS) -L$(LIB_DIRS) $(LDFLAGS) $< -o $@

clean:
    rm Yen

内容的提问来源于stack exchange,提问作者Robert Benassai

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.08 17:04:49