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

求指导:构造以文件名作为输入的最大流问题求解函数并调试现有代码

Fixing Your Max Flow Implementation with NetworkX and Gurobi

Let's walk through the issues in your code and fix them step by step. Your goal is to build a max flow solver that reads edge data from a file, solves the model, outputs results, and plots only edges with non-zero flow. Here's what needs fixing and the corrected code:

Key Issues in Your Original Code

  • Hardcoded filename: You used "filename" instead of the function parameter filename when reading the edge list, which means it will always look for a file named "filename" instead of the one you pass.
  • Incorrect edge attribute reading: nx.read_edgelist doesn't automatically load the capacity attribute unless you specify it, so accessing G[e[0]][e[1]]['capacity'] would throw an error.
  • Redundant graph reloading: Inside the flow edge filtering loop, you re-read the edge list every iteration, which resets the graph each time—so you'll never properly remove all zero-flow edges.
  • Unfiltered variables: When processing solution variables, you included the v variable (the max flow value) along with edge flows, which would cause errors when trying to parse it as an edge.
  • Missing imports: Your code doesn't include necessary imports for NetworkX, Gurobi, literal_eval, or matplotlib (for plotting).
  • Jupyter-specific command: !cat maxflow.lp only works in Jupyter notebooks; for general Python, use a standard file read instead.

Corrected Code

import networkx as nx
import gurobipy as gp
from gurobipy import GRB
from ast import literal_eval
import matplotlib.pyplot as plt

def maxflow(filename):
    # Read edge list with capacity attribute
    G = nx.read_edgelist(
        filename,
        nodetype=int,
        create_using=nx.DiGraph(),
        data=(('capacity', float),)  # Specify to load capacity as float
    )
    
    # Identify source and sink (min and max nodes)
    source = min(G.nodes)
    print(f"Source={source}")
    sink = max(G.nodes)
    print(f"Sink={sink}")
    
    # Initialize Gurobi model
    m = gp.Model("maxflow")
    
    # Create flow variables for each edge
    x = m.addVars(G.edges(), vtype=GRB.CONTINUOUS, name="x")
    # Variable for total max flow
    v = m.addVar(vtype=GRB.CONTINUOUS, name="v")
    m.update()
    
    # Set objective: maximize total flow v
    m.modelSense = GRB.MAXIMIZE
    m.setObjective(v)
    
    # Capacity constraints: flow <= edge capacity
    for u, v_edge in G.edges():
        capacity = G[u][v_edge]['capacity']
        m.addConstr(x[(u, v_edge)] <= capacity, f"C{u},{v_edge}")
        print(f"Added capacity constraint for edge ({u}, {v_edge}): flow <= {capacity}")
    
    # Source flow constraint: total outflow from source equals v
    m.addConstr(x.sum(source, '*') == v, f"Source{source}")
    # Sink flow constraint: total inflow to sink equals v
    m.addConstr(x.sum('*', sink) == v, f"Sink{sink}")
    
    # Flow conservation for intermediate nodes
    for node in G.nodes():
        if node != source and node != sink:
            m.addConstr(x.sum(node, '*') - x.sum('*', node) == 0.0, f"N{node}")
    
    # Write model to LP file (optional)
    m.write("maxflow.lp")
    # Print LP file content (works in any Python environment)
    with open("maxflow.lp", "r") as f:
        print(f.read())
    
    # Optimize the model
    m.optimize()
    
    # Process and print solution if optimal
    if m.status == GRB.Status.OPTIMAL:
        print(f"\nOptimal Solution Found")
        print(f"Max Flow Value: {m.objVal:.2f}")
        print("\nEdge Flows:")
        for edge in G.edges():
            flow = x[edge].x
            print(f"Edge {edge}: {flow:.2f}")
        
        # Build graph with only non-zero flow edges
        non_zero_flow_G = nx.DiGraph()
        non_zero_flow_G.add_nodes_from(G.nodes())
        for edge in G.edges():
            if x[edge].x > 1e-6:  # Use small epsilon to avoid floating point errors
                non_zero_flow_G.add_edge(edge[0], edge[1], flow=x[edge].x)
        
        # Plot the non-zero flow graph
        plt.figure(figsize=(8, 6))
        pos = nx.spring_layout(non_zero_flow_G, seed=42)  # Seed for consistent layout
        nx.draw(non_zero_flow_G, pos, with_labels=True, node_color='lightblue', node_size=700, font_size=12)
        # Add edge flow labels
        edge_labels = {(u, v): f"{d['flow']:.2f}" for u, v, d in non_zero_flow_G.edges(data=True)}
        nx.draw_networkx_edge_labels(non_zero_flow_G, pos, edge_labels=edge_labels, font_size=10)
        plt.title("Max Flow: Edges with Non-Zero Flow")
        plt.show()
    else:
        print("No optimal solution found.")

How to Use It

Call the function with your edge list file:

maxflow("edge_list_max_flow2.txt")

Explanation of Key Fixes

  1. Proper File Reading: We now use the filename parameter and specify data=(('capacity', float),) to correctly load the edge capacity attribute.
  2. Non-Zero Flow Graph Construction: Instead of reloading the graph repeatedly, we create a new directed graph, add all nodes, then only add edges where the flow is greater than a small epsilon (to handle floating point precision issues).
  3. Variable Filtering: We directly iterate over the edge variables x instead of all model variables, avoiding the v variable entirely.
  4. Cross-Environment Compatibility: Replaced the Jupyter-specific !cat with a standard file read to work in any Python environment.
  5. Better Plotting: Added edge flow labels, consistent layout, and proper matplotlib setup to ensure the plot displays correctly.
  6. Floating Point Precision: Used 1e-6 instead of checking for exactly 0.0, since Gurobi might return very small values (like 1e-15) for edges with zero flow due to numerical precision.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.29 15:17:37