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

如何将GraphML中的边权重导入至boost::dijkstra_shortest_paths并解决bad_any_cast异常问题

解决Boost GraphML读取与Dijkstra算法的问题

我来帮你梳理下代码里的问题,一步步修正让它正常运行:

核心问题分析

你的代码主要有三个关键问题:

  1. 图类型未定义边权重属性:你用的adjacency_list没有预留存储边权重的位置,导致读取的权重无法关联到图的边。
  2. 属性绑定错误:GraphML里的边权重属性名称是weight(对应<key>的attr.name),但你绑定了d1(这是key的id,不是属性名称),所以无法正确映射权重值。
  3. Dijkstra参数配置错误:你把边权重映射传给了distance_map参数,而distance_map是用来存储顶点到源点的距离的,边权重应该用weight_map参数传入。

修改后的完整代码

#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/dijkstra_shortest_paths.hpp>
#include <boost/graph/graphml.hpp>
#include <boost/property_map/property_map.hpp>
#include <iostream>
#include <fstream>
#include <vector>
#include <map>

using namespace std;

// 定义带有边权重属性的图类型
using EdgeProperty = boost::property<boost::edge_weight_t, double>;
using Graph = boost::adjacency_list<boost::vecS, boost::vecS, boost::undirectedS,
                                    boost::no_property, EdgeProperty>;
using Vertex = boost::graph_traits<Graph>::vertex_descriptor;
using Edge = boost::graph_traits<Graph>::edge_descriptor;
using IndexMap = boost::property_map<Graph, boost::vertex_index_t>::type;
using EdgeWeightMap = boost::property_map<Graph, boost::edge_weight_t>::type;

int main(int argc, char *argv[]) {
    if (argc <= 1) {
        cout << "No GraphML file given." << endl;
        return 1;
    }

    Graph g;
    boost::dynamic_properties dp{boost::ignore_other_properties};

    // 绑定GraphML中的"weight"属性到图的edge_weight_t属性
    EdgeWeightMap edge_weight_map = get(boost::edge_weight, g);
    dp.property("weight", edge_weight_map);

    // 读取GraphML文件
    ifstream in{argv[1]};
    if (!in.is_open()) {
        cout << "Failed to open file: " << argv[1] << endl;
        return 1;
    }
    boost::read_graphml(in, g, dp);

    // --------------------------
    // 调试输出:验证边权重是否正确读取
    // --------------------------
    cout << "Edge weights read from GraphML:" << endl;
    auto edges = boost::edges(g);
    for (auto e_it = edges.first; e_it != edges.second; ++e_it) {
        Edge e = *e_it;
        Vertex u = boost::source(e, g);
        Vertex v = boost::target(e, g);
        double weight = get(edge_weight_map, e);
        cout << "Edge " << u << " -> " << v << ", weight: " << weight << endl;
    }

    // 选择源节点(这里选第一个节点)
    Vertex source_node = *boost::vertices(g).first;
    cout << "\nRunning Dijkstra from vertex " << source_node << endl;

    // 存储每个顶点到源点的距离
    vector<double> distances(num_vertices(g));
    auto distance_map = boost::make_iterator_property_map(
        distances.begin(), get(boost::vertex_index, g));

    // 运行Dijkstra最短路径算法
    boost::dijkstra_shortest_paths(
        g, source_node,
        boost::distance_map(distance_map)
        .weight_map(edge_weight_map));

    // 输出结果
    cout << "Shortest distances from source:" << endl;
    auto vertices = boost::vertices(g);
    for (auto v_it = vertices.first; v_it != vertices.second; ++v_it) {
        Vertex v = *v_it;
        cout << "Vertex " << v << ": " << distances[v] << endl;
    }

    return 0;
}

关键修改说明

1. 图类型定义

我修改了adjacency_list的模板参数,添加了EdgeProperty作为边属性类型,这样图的每条边都能存储double类型的权重值:

using EdgeProperty = boost::property<boost::edge_weight_t, double>;
using Graph = boost::adjacency_list<boost::vecS, boost::vecS, boost::undirectedS,
                                    boost::no_property, EdgeProperty>;

2. 正确绑定GraphML属性

GraphML中<key id="d1" for="edge" attr.name="weight">的attr.name是weight,这才是属性的逻辑名称,所以我们要绑定"weight"到图的edge_weight_t属性:

EdgeWeightMap edge_weight_map = get(boost::edge_weight, g);
dp.property("weight", edge_weight_map);

3. 正确配置Dijkstra参数

  • distance_map:传入存储顶点距离的映射(这里用vector<double>包装的迭代器属性映射)
  • weight_map:传入边权重的映射,告诉Dijkstra算法用这个值作为边的权重

调试方法

代码里添加了遍历所有边并输出权重的代码,你可以通过这个验证GraphML里的权重是否被正确读取。另外,如果你想检查dynamic_properties里的内容,可以尝试遍历它的属性,但更简单的方式是直接验证图的边属性,因为我们已经把属性绑定到了图的内置映射里。

处理GraphML中的默认权重

注意你提供的GraphML里,<edge id="e1">没有指定weight值,Boost会自动用double的默认值0.0填充这条边的权重,如果需要自定义默认值,可以在定义EdgeProperty时指定:

using EdgeProperty = boost::property<boost::edge_weight_t, double, 1.0>; // 默认权重1.0

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.29 00:22:39