不能满足所有需求的最小成本的最大流量
Maximum flow with min cost that doesn't satisfy all demands
我正在使用 NetworkX to solve a maximum-flow problem with more than one source and sink. I found a function that works relatively well in NetworkX called 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]))
您可以将多源流问题转换为单源问题,方法是创建一个新的源顶点并添加具有零成本的边以及从它到所有旧源的旧需求值。
你可以对所有水槽做同样的事情(但边缘应该从旧水槽到新水槽)。
之后可以使用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]))
我正在使用 NetworkX to solve a maximum-flow problem with more than one source and sink. I found a function that works relatively well in NetworkX called 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]))
您可以将多源流问题转换为单源问题,方法是创建一个新的源顶点并添加具有零成本的边以及从它到所有旧源的旧需求值。
你可以对所有水槽做同样的事情(但边缘应该从旧水槽到新水槽)。
之后可以使用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]))