不能满足所有需求的最小成本的最大流量

Posted

技术标签:

【中文标题】不能满足所有需求的最小成本的最大流量【英文标题】:Maximum flow with min cost that doesn't satisfy all demands 【发布时间】:2017-08-19 06:58:55 【问题描述】:

我正在使用NetworkX 解决具有多个源和接收器的最大流量问题。我发现了一个在 NetworkX 中运行良好的函数,名为max_cost_flow,但是我遇到的问题是它要求净需求为零,换句话说,任何接收器都不应低于它的需要,否则会引发错误。

我可以使用什么(或如何修改此算法)来允许它计算出可能的最佳流量,但不一定满足所有条件?

根据 kraskevich 的建议:

import networkx as nx

def convert(graph):

    allNodes = graph.nodes()

    newSource = len(allNodes) + 1
    newSink = len(allNodes) + 2

    graph.add_node(newSource)
    graph.add_node(newSink)


    for currentNode in allNodes:

        demand = graph.node[currentNode]['demand']

        if demand < 0 :
            graph.add_edge(newSource, currentNode, weight=0, capacity=demand)


        if demand > 0:
            graph.add_edge(newSink, currentNode, weight=0, capacity=demand)

    return graph



g = nx.DiGraph()

g.add_node(1, demand = 1)
g.add_node(2, demand = -2)
g.add_node(3, demand = 2)
g.add_node(4, demand = -4)

g.add_edge(1, 2, weight=4, capacity=100)
g.add_edge(1, 4, weight=3, capacity=100)
g.add_edge(3, 2, weight=5, capacity=100)
g.add_edge(3, 4, weight=2, capacity=100)
g.add_edge(3, 1, weight=1)
newGraph = convert(g)
print(nx.max_flow_min_cost(g, newGraph.nodes()[-2],newGraph.nodes()[-1]))

【问题讨论】:

您的代码中有一些错误。我在答案中添加了一个工作示例。 【参考方案1】:

    您可以将多源流问题转换为单源问题,方法是创建一个新源顶点并将零成本的边和来自它的旧需求值添加到所有旧源。

    您可以对所有水槽做同样的事情(但边缘应该从旧水槽到新水槽)。

    之后,您可以使用max_flow_min_cost函数找到成本最小的最大流量(不需要满足所有需求)。

更新:您的代码中存在一些错误。这是一个工作示例(我稍微更改了图表,使流量不为零):

import networkx as nx

def convert(graph):
    allNodes = graph.nodes()
    newSource = len(allNodes) + 1
    newSink = len(allNodes) + 2

    graph.add_node(newSource)
    graph.add_node(newSink)

    for currentNode in allNodes:
        demand = graph.node[currentNode]['demand']
        # Direction matters
        # It goes FROM the new source and TO the new sink
        if demand < 0:
            graph.add_edge(newSource, currentNode, weight=0, capacity=-demand)
        if demand > 0:
            graph.add_edge(currentNode, newSink, weight=0, capacity=demand)
        # We also need to zero out all demands
        graph.node[currentNode]['demand'] = 0
    return graph



g = nx.DiGraph()

g.add_node(1, demand = 1)
g.add_node(2, demand = -2)
g.add_node(3, demand = 2)
g.add_node(4, demand = -4)

g.add_edge(1, 2, weight=4, capacity=100)
g.add_edge(1, 4, weight=3, capacity=100)
g.add_edge(2, 3, weight=5, capacity=100)
g.add_edge(4, 3, weight=2, capacity=100)
g.add_edge(1, 3, weight=1)
newGraph = convert(g)
# The order of s and t matters here, too
print(nx.max_flow_min_cost(g, g.nodes()[-2], g.nodes()[-1]))

【讨论】:

我不明白您所说的“以及从它对所有旧资源的需求的旧值”是什么意思。 假设您有一个来源 s_old 和一个需求 d。你需要一个边 new_source -&gt; s_oldcost = 0capacity = d 哦,所以您的意思是将所有来源连接到“主要”来源,其需求等于其他来源的总需求,并且容量 = 需求。对吗? @Swailem95 是的。尽管max_flow_min_cost 函数不使用对源和接收器的需求(它只计算最大最便宜的流量),但您不需要对新的“主”源的需求。 我刚刚尝试过,但出现错误提示 total node demand is not zero。我现在将在帖子中发布我的代码。

以上是关于不能满足所有需求的最小成本的最大流量的主要内容,如果未能解决你的问题,请参考以下文章

网络流知识点汇总

费用流(bzoj 3130)

BZOJ 3130 [Sdoi2013]费用流

BZOJ3130 [Sdoi2013]费用流 网络流 + 二分

P3305 [SDOI2013]费用流

BZOJ3130: [Sdoi2013]费用流