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

求助:使用boost::dijkstra_shortest_paths计算带顶点权重的最短路径报错

解决Boost Dijkstra算法中自定义顶点+边权重的问题

你的问题出在Boost的weight_map参数要求符合可读属性映射(ReadablePropertyMap)概念,直接传递lambda无法满足这个要求——lambda没有Property Map所需的嵌套类型(如value_type、key_type)和标准接口,导致运行时类型检查失败。

下面是两种可行的解决方案:

方案一:用function_property_map包装lambda

Boost提供了function_property_map工具,可以将普通函数或lambda转换成合法的Property Map。

  1. 先包含对应的头文件:
#include <boost/property_map/function_property_map.hpp>
  1. 修改自定义权重映射的定义:
// 用make_function_property_map包装lambda,明确键类型为Graph::edge_descriptor
auto custom_weight_map = boost::make_function_property_map<Graph::edge_descriptor>(
    [&g](const Graph::edge_descriptor& e) -> float {
        float vertex_weight = g[target(e, g)].weight;
        float edge_weight = get(boost::edge_weight, g, e);
        return vertex_weight + edge_weight;
    }
);
  1. 原Dijkstra调用代码保持不变,此时custom_weight_map已符合要求,可以正常传入。

方案二:预处理合并顶点与边权重

如果不需要保留原始边权重,可以直接遍历所有边,将目标顶点的权重合并到边的权重中,这样无需自定义权重映射。

// 遍历所有边,将目标顶点权重合并到边权重
for (auto e : boost::make_iterator_range(edges(g))) {
    auto target_v = target(e, g);
    float combined = get(boost::edge_weight, g, e) + g[target_v].weight;
    put(boost::edge_weight, g, e, combined);
}

// 直接使用默认的edge_weight_map调用Dijkstra
boost::dijkstra_shortest_paths(
    g, source_vertex,
    boost::predecessor_map(
        boost::make_iterator_property_map(
            predecessors.begin(), boost::get(boost::vertex_index, g)))
        .distance_map(boost::make_iterator_property_map(
            distances.begin(), boost::get(boost::vertex_index, g))));

注意事项

如果需要将起点的顶点权重计入总路径长度,需要手动初始化距离数组:

distances[source_vertex] = g[source_vertex].weight;

因为自定义权重映射只统计每条边目标顶点的权重,起点不会被任何边指向,默认初始距离为0,不会包含其自身权重。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 23:51:09