Network Flows(借助ortools)

Posted xrszff

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Network Flows(借助ortools)相关的知识,希望对你有一定的参考价值。

Maximum Flows

技术图片

"""From Taha 'Introduction to Operations Research', example 6.4-2."""

from __future__ import print_function
from ortools.graph import pywrapgraph

def main():
  """MaxFlow simple interface example."""

  # Define three parallel arrays: start_nodes, end_nodes, and the capacities
  # between each pair. For instance, the arc from node 0 to node 1 has a
  # capacity of 20.

  start_nodes = [0, 0, 0, 1, 1, 2, 2, 3, 3]
  end_nodes = [1, 2, 3, 2, 4, 3, 4, 2, 4]
  capacities = [20, 30, 10, 40, 30, 10, 20, 5, 20]

  # Instantiate a SimpleMaxFlow solver.
  max_flow = pywrapgraph.SimpleMaxFlow()
  # Add each arc.
  for i in range(0, len(start_nodes)):
    max_flow.AddArcWithCapacity(start_nodes[i], end_nodes[i], capacities[i])

  # Find the maximum flow between node 0 and node 4.
  if max_flow.Solve(0, 4) == max_flow.OPTIMAL:
    print('Max flow:', max_flow.OptimalFlow())
    print('')
    print('  Arc    Flow / Capacity')
    for i in range(max_flow.NumArcs()):
      print('%1s -> %1s   %3s  / %3s' % (
          max_flow.Tail(i),
          max_flow.Head(i),
          max_flow.Flow(i),
          max_flow.Capacity(i)))
    print('Source side min-cut:', max_flow.GetSourceSideMinCut())
    print('Sink side min-cut:', max_flow.GetSinkSideMinCut())
  else:
    print('There was an issue with the max flow input.')

if __name__ == '__main__':
  main()

Minimum Cost Flows

task

欲构造data center的traffic变换仿真,输入为二维矩阵,根据论文中的算法给定一些限定条件,求解得到新的拓扑结构。

单纯算Minimum Cost Flows的Demo

技术图片
与 maximum flows 问题比较,多了 unit_costs 和 supply, 且 supply 流入总和等于流出总和,即 supply 中元素和为0。

supply 中的负数元素即代表了 demand.

or-tools 中的 AddArcWithCapacityAndUnitCost 支持有向图,节点索引和容量(capacity)必须是非负的,花费 unit cost 可以是任意整数,支持自循环和重复弧。

Adds a directed arc from tail to head to the underlying graph with a given capacity and cost per unit of flow. * Node indices and the capacity must be non-negative (>= 0). * The unit cost can take any integer value (even negative). * Self-looping and duplicate arcs are supported. * After the method finishes, NumArcs() == the returned ArcIndex + 1.

# """From Bradley, Hax, and Magnanti, 'Applied Mathematical Programming', figure 8.1."""

from __future__ import print_function
from ortools.graph import pywrapgraph

def main():
  """MinCostFlow simple interface example."""

  # Define four parallel arrays: start_nodes, end_nodes, capacities, and unit costs
  # between each pair. For instance, the arc from node 0 to node 1 has a
  # capacity of 15 and a unit cost of 4.

  start_nodes = [ 0, 0,  1, 1,  1,  2, 2,  3, 4]
  end_nodes   = [ 1, 2,  2, 3,  4,  3, 4,  4, 2]
  capacities  = [15, 8, 20, 4, 10, 15, 4, 20, 5]
  unit_costs  = [ 4, 4,  2, 2,  6,  1, 3,  2, 3]

  # Define an array of supplies at each node.

  supplies = [20, 0, 0, -5, -15]


  # Instantiate a SimpleMinCostFlow solver.
  min_cost_flow = pywrapgraph.SimpleMinCostFlow()

  # Add each arc.
  for i in range(0, len(start_nodes)):
    min_cost_flow.AddArcWithCapacityAndUnitCost(start_nodes[i], end_nodes[i],
                                                capacities[i], unit_costs[i])

  # Add node supplies.

  for i in range(0, len(supplies)):
    min_cost_flow.SetNodeSupply(i, supplies[i])


  # Find the minimum cost flow between node 0 and node 4.
  if min_cost_flow.Solve() == min_cost_flow.OPTIMAL:
    print('Minimum cost:', min_cost_flow.OptimalCost())
    print('')
    print('  Arc    Flow / Capacity  Cost')
    for i in range(min_cost_flow.NumArcs()):
      cost = min_cost_flow.Flow(i) * min_cost_flow.UnitCost(i)
      print('%1s -> %1s   %3s  / %3s       %3s' % (
          min_cost_flow.Tail(i),
          min_cost_flow.Head(i),
          min_cost_flow.Flow(i),
          min_cost_flow.Capacity(i),
          cost))
  else:
    print('There was an issue with the min cost flow input.')

if __name__ == '__main__':
  main()

封装和改造

以上是关于Network Flows(借助ortools)的主要内容,如果未能解决你的问题,请参考以下文章

cf739E Gosha is hunting (flows)

网络流之最大流

Ortools 在求解时设置约束

Python中如何使用ortools求解二次规划?

如何在 ortools 中更改约束参数的类型

orTools 如何从 RoutingModel 获取状态?