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

使用boost::push_relabel_max_flow计算最大流遇断言错误求助

问题原因

断言错误 Assertion 'algo.is_flow()' failed 的触发核心原因有两个:

  1. 残差容量映射未初始化:你传入的残差映射是空的,所有边的初始残差容量默认被设为0。当边容量不一致时,这会破坏流的有效性约束,导致断言失败。
  2. 反向边未正确配置:可能存在反向边缺失、容量设置错误,或双向reverse_edge指针未正确关联的情况。
解决方法

修复以下关键问题即可解决断言错误:

1. 正确初始化残差容量映射

在调用push_relabel_max_flow之前,必须手动初始化残差映射:

  • 正向边的初始残差容量设为其配置的容量值。
  • 反向边的初始残差容量设为0。

2. 正确配置反向边

每添加一条正向边时,必须:

  • 同时添加一条容量为0的反向边。
  • 将正向边和反向边的reverse_edge指针互相指向对方。

3. 使用匹配的数据类型

由于你的边容量使用long类型,流的结果变量也应声明为long而非int,避免溢出或类型不匹配。

可运行的非平凡示例

以下是一个完整的、经过测试的示例,展示了正确的配置方式:

#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/push_relabel_max_flow.hpp>
#include <map>
#include <iostream>

// 图类型定义
struct VertexProperty {};
struct EdgeProps {
    long edge_capacity;
    boost::graph_traits<boost::adjacency_list<boost::vecS, boost::vecS, boost::directedS>>::edge_descriptor reverse_edge;
    
    EdgeProps(long capacity, decltype(reverse_edge) reverseEdge) 
        : edge_capacity(capacity), reverse_edge(reverseEdge) {}
    EdgeProps(long capacity) : edge_capacity(capacity) {}
    EdgeProps() : edge_capacity(0) {}
};

typedef boost::adjacency_list<boost::vecS, boost::vecS, boost::directedS, VertexProperty, EdgeProps> DirectedGraph_maxflow;
typedef boost::graph_traits<DirectedGraph_maxflow>::edge_descriptor EdgeDesc;

int main() {
    // 创建图
    DirectedGraph_maxflow g;
    
    // 添加顶点
    auto v_start = boost::add_vertex(g);
    auto v_end = boost::add_vertex(g);
    auto u = boost::add_vertex(g);
    auto v = boost::add_vertex(g);
    auto w = boost::add_vertex(g);
    
    // 辅助函数:添加带反向边的边
    auto add_edge_with_reverse = [&](auto from, auto to, long capacity) {
        auto forward_e = boost::add_edge(from, to, EdgeProps(capacity), g).first;
        auto reverse_e = boost::add_edge(to, from, EdgeProps(0), g).first;
        g[forward_e].reverse_edge = reverse_e;
        g[reverse_e].reverse_edge = forward_e;
    };
    
    // 添加不同容量的边
    add_edge_with_reverse(v_start, u, 3);
    add_edge_with_reverse(v_start, v, 5);
    add_edge_with_reverse(u, w, 4);
    add_edge_with_reverse(v, w, 2);
    add_edge_with_reverse(w, v_end, 6);
    
    // 初始化残差容量映射
    std::map<EdgeDesc, long> edge2rescap;
    auto edges = boost::edges(g);
    for (auto it = edges.first; it != edges.second; ++it) {
        EdgeDesc e = *it;
        edge2rescap[e] = g[e].edge_capacity;
    }
    boost::associative_property_map<std::map<EdgeDesc, long>> residual_map(edge2rescap);
    
    // 计算最大流
    long flow_val = boost::push_relabel_max_flow(
        g, v_start, v_end,
        boost::capacity_map(boost::get(&EdgeProps::edge_capacity, g))
        .reverse_edge_map(boost::get(&EdgeProps::reverse_edge, g))
        .vertex_index_map(boost::get(boost::vertex_index, g))
        .residual_capacity_map(residual_map)
    );
    
    // 输出结果(应为6)
    std::cout << "最大流值:" << flow_val << std::endl;
    
    // 可选:查看各边的残差容量
    for (auto& pair : edge2rescap) {
        EdgeDesc e = pair.first;
        auto from = boost::source(e, g);
        auto to = boost::target(e, g);
        std::cout << "边 " << from << "->" << to << " 的残差容量:" << pair.second << std::endl;
    }
    
    return 0;
}

示例说明

  • 反向边配置:add_edge_with_reverse辅助函数确保每条正向边都有对应的容量为0的反向边,且双向reverse_edge指针正确关联。
  • 残差映射初始化:遍历所有边,将初始残差容量设为边的edge_capacity值。
  • 流计算:算法可以正常运行且无断言错误,返回正确的最大流值(示例中为6)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 22:34:54