• C#,计算图最大流量的福特-富尔克森(Ford Fulkerson)算法与源程序


    Ford-Fulkerson算法(FFA)是一种贪婪算法,用于计算流网络中的最大流量。 它被称为“方法”而不是“算法”,因为在残差图中找到增广路径的方法没有完全指定,或者在具有不同运行时间的若干实现中指定。 它由L. R. Ford,Jr。和D. R. Fulkerson于1956年出版。 名称“Ford-Fulkerson”通常也用于Edmonds-Karp算法,该算法是Ford-Fulkerson方法的完全定义的实现。

     Lester Randolph Ford, 1947-1948 MAA President

     

    算法背后的想法如下:只要存在从源(起始节点)到接收器(端节点)的路径,在路径中的所有边缘上具有可用容量,我们就沿着其中一个路径发送流。 然后我们找到另一条路径,依此类推。 具有可用容量的路径称为扩充路径。

    通过将流量增加路径添加到已建立的流量,当不再能够找到流量增加路径时,将达到最大流量。但是,无法确定是否会达到这种情况,因此可以保证的最佳方案是,如果算法终止,答案将是正确的。在算法永远运行的情况下,流可能甚至不会收敛到最大流量。但是,这种情况只发生在不合理的流量值。当容量为整数时,Ford-Fulkerson的运行时间受O(E f)的限制(参见大O表示法),其中E是边和f是最大流量。这是因为每个扩充路径都可以在O(E))时间内找到并且将流量增加至少1 的整数量,其上限f 。
     

     

    给出一个图,该图表示每个边都有容量的流网络。同时在图中给定两个顶点源“s”和汇“t”,在以下约束条件下,找到从s到t的最大可能流:

    a) 边上的流量不会超过边的给定容量。

    b) 除了s和t之外,每个顶点的传入流都等于传出流。

    如何实现上述简单算法?

    让我们首先定义残差图的概念,这是理解实现所需的。

    流量网络的残差图是表示其他可能流量的图。若在残差图中有一条从源到汇的路径,那个么就可以添加流。剩余图的每条边都有一个称为剩余容量的值,该值等于边的原始容量减去当前流量。剩余容量基本上是边缘的当前容量。

    现在让我们谈谈实现细节。如果残差图的两个顶点之间没有边,则残差容量为0。我们可以将残差图初始化为原始图,因为没有初始流,并且初始残差容量等于原始容量。为了找到增广路径,我们可以对残差图进行BFS或DFS。我们在下面的实现中使用了BFS。使用BFS,我们可以发现是否存在从源到汇的路径。BFS还构建父[]数组。使用父[]数组,我们遍历找到的路径,并通过查找路径上的最小剩余容量来查找通过该路径的可能流量。我们稍后将找到的路径流添加到总体流中。

    重要的是,我们需要更新残差图中的残差容量。我们从沿路径的所有边上减去路径流,然后沿反向边添加路径流。我们需要沿反向边添加路径流,因为以后可能需要沿反向发送流(例如,请参见以下链接)。

    参考:

    C#,图(Graph)的数据结构设计与源代码https://blog.csdn.net/beijinghorn/article/details/125133711?spm=1001.2014.3001.5501

    源代码(POWER BY TRUFFER):

    1. using System;
    2. using System.Collections;
    3. using System.Collections.Generic;
    4. namespace Legalsoft.Truffer.Algorithm
    5. {
    6. public partial class Graph
    7. {
    8. private static bool BFS_Ford_Fulkerson(int[,] graph, int s, int t, int[] parent)
    9. {
    10. int N = graph.GetLength(0);
    11. bool[] visited = new bool[N];
    12. for (int i = 0; i < N; i++)
    13. {
    14. visited[i] = false;
    15. }
    16. List<int> queue = new List<int>();
    17. queue.Add(s);
    18. visited[s] = true;
    19. parent[s] = -1;
    20. while (queue.Count != 0)
    21. {
    22. int u = queue[0];
    23. queue.RemoveAt(0);
    24. for (int v = 0; v < N; v++)
    25. {
    26. if (visited[v] == false && graph[u, v] > 0)
    27. {
    28. if (v == t)
    29. {
    30. parent[v] = u;
    31. return true;
    32. }
    33. queue.Add(v);
    34. parent[v] = u;
    35. visited[v] = true;
    36. }
    37. }
    38. }
    39. return false;
    40. }
    41. public int Ford_Fulkerson(int s, int t)
    42. {
    43. int N = Node_Number;
    44. int[,] rGraph = new int[N, N];
    45. int u, v;
    46. for (u = 0; u < N; u++)
    47. {
    48. for (v = 0; v < N; v++)
    49. {
    50. rGraph[u, v] = Matrix[u, v];
    51. }
    52. }
    53. int[] parent = new int[N];
    54. int max_flow = 0;
    55. while (BFS_Ford_Fulkerson(rGraph, s, t, parent))
    56. {
    57. int path_flow = int.MaxValue;
    58. for (v = t; v != s; v = parent[v])
    59. {
    60. u = parent[v];
    61. path_flow = Math.Min(path_flow, rGraph[u, v]);
    62. }
    63. for (v = t; v != s; v = parent[v])
    64. {
    65. u = parent[v];
    66. rGraph[u, v] -= path_flow;
    67. rGraph[v, u] += path_flow;
    68. }
    69. max_flow += path_flow;
    70. }
    71. return max_flow;
    72. }
    73. }
    74. public static partial class GraphDrives
    75. {
    76. public static string MaxFlow()
    77. {
    78. int[,] graph = new int[,] {
    79. { 0, 16, 13, 0, 0, 0 },
    80. { 0, 0, 10, 12, 0, 0 },
    81. { 0, 4, 0, 0, 14, 0 },
    82. { 0, 0, 9, 0, 0, 20 },
    83. { 0, 0, 0, 7, 0, 4 },
    84. { 0, 0, 0, 0, 0, 0 }
    85. };
    86. Graph g = new Graph(graph);
    87. g.AdjacencyMatrix();
    88. return ("The maximum possible flow is " + g.Ford_Fulkerson(0, 5));
    89. }
    90. }
    91. }

  • 相关阅读:
    Web相机和浏览器的二维码扫描方案
    关于我有一个后台可配置blog的系统,我使用nuxt做了一个网站,后台可以更新文章这件事情
    HTML5学习系列之网页图像
    springboot毕设项目社团活动网站b7rjo(java+VUE+Mybatis+Maven+Mysql)
    【零基础学Python】运算符
    Python中内置数据库!SQLite使用指南! ⛵
    DDD领域驱动模型笔记
    Mall微服务版本全面升级,支持最新版SpringCloud
    Selenium+Python系列(一) - 开发环境搭建
    【CVE-2024-38077】核弹级Windows RCE漏洞如何自检并修复该漏洞(附批量漏洞检测工具及分析伪代码)
  • 原文地址:https://blog.csdn.net/beijinghorn/article/details/125289729