Skip to content
旧时的足迹
Go back

NetWork Flow Problem - Maximum Flow

编辑此页

不只是网络流,很多场景都会涉及到流量问题。这里介绍一种计算流系统中最大流的 方法,解法使用Ford-Fulkerson方法的基本思想。

在介绍Ford-Fulkerson方法之前需要先理解几个基本概念: 对于一个流网络,该网络由一个源点s、一个汇点t和源点与汇点间的众节点以及各点间的边组成。

问题的解法思路:

  1. 构建有向图
  2. 使用BFS算法找到一条增广路径(假设起初为0)
  3. 找到这条增广路径中限流最小的边
  4. 该增广路径中每条边流量减掉3中最小边流量
  5. maxflow加3中最小边流量(此路径为有效路径)
  6. 迭代(重复2,3,4,5)
  7. 条件边界:找不到增广路径则退出

上代码:

class GraphTheoryMaxflow
  # edge: 边数
  # spot: 交点数
  # graph: 有向图(二维数组)
  def initialize(edge, spot, graph)
    @graph = graph
    @edge = edge
    @spot = spot
  end

  def max_flow
    max_num = 0
    rgraph = @graph
    boundary, path = augmentation_path(rgraph, 0, @spot-1)
    while boundary
      min_flow = 65535     # 这里给你个限制的最大值(65535为16位int表示最大值)

      v = @spot - 1
      while !path[v].nil?
        u = path[v]
        min_flow = [min_flow, rgraph[u][v]].min
        v = u
        puts v
      end

      v = @spot - 1
      while !path[v].nil?
        u = path[v]
        rgraph[u][v] -= min_flow
        rgraph[v][u] += min_flow
        v = u
        puts v
      end
      max_num += min_flow
      boundary, path = augmentation_path(rgraph, 0, @spot-1)
    end
    max_num
  end

  # s: 源点
  # t: 终点
  def augmentation_path(rgraph, s, t)
    path = {}           # 路径
    visited = {}        # 标记是否访问过点
    queue = []          # 存续bfs中遍历用节点

    queue << s
    visited[s] = true
    # BFS算法找出增广路径
    while queue.size > 0
      top = queue.shift
      (0..@spot-1).each do |i|
        if visited[i] != true && rgraph[top][i] > 0
          path[i] = top
          visited[i] = true
          queue << i
        end
      end
      puts path
    end
    # 此路径是否是通路
    [visited[t] == true, path]
  end
end

# graph = [
#   [0, 40, 0, 20],
#   [0, 0, 30, 20],
#   [0, 0, 0, 10],
#   [0, 0, 0, 0]
# ]
# gtm = GraphTheoryMaxflow.new(5, 4, graph)
# gtm.max_flow

编辑此页
Share this post on:

Previous Post
Mongoid 使用总结之一些查询方法
Next Post
qiniu 音视频处理