如何使用Java解决最大流
来源:互联网 发布:团伙研发作弊软件 编辑:程序博客网 时间:2024/06/16 06:43
代码
- package maxflow;
- import java.util.ArrayList;
- import java.util.LinkedList;
- import java.util.List;
- import java.util.Queue;
- import util.EdgeUtil;
- import util.NodeUtil;
- import entry.Edge;
- import entry.Node;
- /**
- * Ford Fulkerson方法求最大流,这是一种迭代的方法,开始是,初始流为0,每次迭代中,课通过寻找一条增广路径来增加流值。反复进行这一过程,直至找不到任何增广路径
- * 本算法使用了Edmonds-Karp算法(一种对Ford Fulkerson方法的实现),在寻找增广路径时使用了寻找s到t的最短路径的方法。复杂度O(VE2)
- * @author xhw
- *
- */
- public class FordFulkerson {
- private static double residualNetwork[][]=null;
- private static double flowNetwork[][]=null;
- /**
- * @param args
- */
- public static void main(String[] args) {
- double graph[][]={{0,16,13,0,0,0},
- {0,0,10,12,0,0},
- {0,4,0,0,14,0},
- {0,0,9,0,0,20},
- {0,0,0,7,0,4},
- {0,0,0,0,0,0}};
- System.out.println(edmondsKarpMaxFlow(graph,0,5));
- }
- /**
- * 实现FordFulkerson方法的一种算法——edmondsKarp算法
- * @param graph
- * @param s
- * @param t
- * @return
- */
- public static double edmondsKarpMaxFlow(double graph[][],int s,int t)
- {
- int length=graph.length;
- //List<Node> nodeList=NodeUtil.generateNodeList(graph);
- double f[][]=new double[length][length];
- for(int i=0;i<length;i++)
- {
- for(int j=0;j<length;j++)
- {
- f[i][j]=0;
- }
- }
- double r[][]=residualNetwork(graph,f);
- Node result=augmentPath(r,s,t);
- double sum=0;
- while(result!=null)
- {
- double cfp=0;
- cfp=minimumAugment(r,result);
- //说明已经没有增广路径了
- if(cfp==0)
- {
- break;
- }
- while(result.getParent()!=null)
- {
- Node parent=result.getParent();
- f[parent.nodeId][result.nodeId]+=cfp;
- f[result.nodeId][parent.nodeId]=-f[parent.nodeId][result.nodeId];
- result=parent;
- }
- sum+=cfp;
- r=residualNetwork(graph,f);
- result=augmentPath(r,s,t);
- }
- residualNetwork=r;
- flowNetwork=calculateFlowNetwork(graph,r);
- /*for(int i=0;i<length;i++)
- {
- for(int j=0;j<length;j++)
- {
- System.out.print((flowNetwork[i][j]>0?flowNetwork[i][j]:0.0)+" ");
- }
- System.out.println();
- }*/
- return sum;
- }
- /**
- * 计算最终的流网络,也就是最大流网络
- * @param graph
- * @param r
- * @return
- */
- private static double[][] calculateFlowNetwork(double[][] graph, double[][] r) {
- int length=graph.length;
- double f[][]=new double[graph.length][graph.length];
- for(int i=0;i<length;i++)
- {
- for(int j=0;j<length;j++)
- {
- f[i][j]=graph[i][j]-r[i][j];
- }
- }
- return f;
- }
- /**
- * 确定增广路径可扩充的流值
- * @param graph
- * @param result
- * @return
- */
- public static double minimumAugment(double graph[][],Node result)
- {
- double cfp=Double.MAX_VALUE;
- while(result.getParent()!=null)
- {
- Node parent=result.getParent();
- double weight=graph[parent.nodeId][result.nodeId];
- if(weight<cfp&&weight>0)
- {
- cfp=weight;
- }
- else if(weight<=0)
- {
- cfp=0;
- break;
- }
- result=parent;
- }
- return cfp;
- }
- /**
- * 计算残余网络
- * @param c
- * @param f
- * @return
- */
- private static double[][] residualNetwork(double c[][],double f[][]) {
- int length=c.length;
- double r[][]=new double[length][length];
- for(int i=0;i<length;i++)
- {
- for(int j=0;j<length;j++)
- {
- r[i][j]=c[i][j]-f[i][j];
- }
- }
- return r;
- }
- /**
- * 广度优先遍历,寻找增光路径,也是最短增广路径
- * @param graph
- * @param s
- * @param t
- * @return
- */
- public static Node augmentPath(double graph[][],int s,int t)
- {
- Node result=null;
- List<Node> nodeList=NodeUtil.generateNodeList(graph);
- nodeList.get(s).distance=0;
- nodeList.get(s).state=1;
- Queue<Node> queue=new LinkedList<Node>();
- queue.add(nodeList.get(s));
- while(!queue.isEmpty())
- {
- Node u=queue.poll();
- for(Node n:u.getAdjacentNodes())
- {
- if(n.state==0)
- {
- n.state=1;
- n.distance=u.distance+1;
- n.setParent(u);
- queue.add(n);
- }
- }
- u.state=2;
- if(u.nodeId==t)
- {
- result=u;
- break;
- }
- }
- return result;
- }
- public static double[][] getResidualNetwork() {
- return residualNetwork;
- }
- public static double[][] getFlowNetwork() {
- return flowNetwork;
- }
- }
阅读全文
0 0
- 如何使用Java解决最大流
- 使用远程桌面时超出最大连接数如何解决?
- pku1273EK()解决最大流
- 最大流问题 (使用遗传算法解决 --Python 实现)
- 使用dspmqver -p7时报java.lang.NoClassDefFoundError错误,如何解决?
- 【已经解决】如何编写弹出框(使用java)??
- Java异常如何解决?
- 如何解决 Java 安全问题?
- 如何解决 Java 安全问题?
- 使用Java实现最大堆
- 如何测试java支持最大内存
- 如何测试java支持的最大内存
- 如何解决phpMyAdmin最大2M文件限制问题
- 如何解决终端连接数超过最大连接数
- 如何解决终端服务器超出了最大允许连接数
- 如何解决MySQL超过最大连接数问题
- 如何解决终端服务器超出了最大允许连接数
- 如何解决Java路径问题?
- struts2升级到2.5的配置
- 灰度共生矩阵
- Nginx 四种分配方式
- spring cloud zuul 配置请求并发
- ES6入门,看这篇就够了
- 如何使用Java解决最大流
- 实现从相册中选择图片回显问题可以删除
- 10027---kafka集群环境搭建
- SpringCloud(2):架构流程、Eureka配置、代码
- 2017/12/21 第十二天培训
- Asp.net MVC WebApi项目的自动接口文档及测试功能打开方法
- Pycharm如何添加第三方库和插件
- 使用Vue构建Ionic混合APP系列教程(四):数据存储
- C实现银行家算法(避免死锁)