最小流量,最低成本,不满足所有要求

时间:2017-03-26 16:52:48

标签: algorithm networkx directed-graph max-flow weighted-graph

我正在使用NetworkX来解决多个源和接收器的最大流量问题。我发现一个功能在NetworkX中运行得相当好,称为max_cost_flow但是我遇到的问题是它要求净需求为零,换句话说没有接收器应该少于它需要,否则错误是提高。

我可以使用什么(或者如何修改此算法)以使其能够计算出最佳流量,而不一定能满足所有条件?

Per kraskevich的建议:

Option Explicit

Sub Test()
    Dim rngOrigin As Excel.Range
    Set rngOrigin = Sheet4.Cells(1, 1)

    Dim rng As Excel.Range
    Set rng = Sheet4.Range(rngOrigin, rngOrigin.End(xlDown))

    Dim bToggle As Boolean

    Dim rngLoop As Excel.Range
    For Each rngLoop In rng
        If rngLoop.Row > 1 Then
            If rngLoop.Offset(-1, 0).Value <> rngLoop.Value Then

                bToggle = Not bToggle
            End If
        End If
        rngLoop.Interior.ColorIndex = VBA.IIf(bToggle, 4, 2)

    Next
End Sub

1 个答案:

答案 0 :(得分:1)

  1. 您可以通过创建新的源顶点并将零成本边和旧的需求值添加到所有旧源来将多源流问题转换为单源问题。

  2. 你可以用同样的方法思考所有的水槽(但是边缘应该从旧水槽到新水槽)。

  3. 之后,您可以使用max_flow_min_cost功能以最小的成本查找最大流量(它不需要满足所有要求)。

  4. 更新:您的代码中存在一些错误。这是一个工作示例(我略微更改了图表以使流量非零):

    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]))