Skip to content

Commit 9e6c627

Browse files
committed
commit
1 parent 6590a22 commit 9e6c627

File tree

126 files changed

+6131
-24
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

126 files changed

+6131
-24
lines changed
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package maxflowMincutBak;
2+
3+
4+
public class TestDijkstraAlgorithm {
5+
6+
public static void main(String[] args) {
7+
int vertex=2;
8+
int end=4;
9+
DijkstraAlgorithm da=new DijkstraAlgorithm(100,0);
10+
da.createGraph("/data.txt");
11+
da.printGraph();
12+
da.printWeightGraph();
13+
da.shortestPathOfBFS(vertex,end); //也可以在printShortestPathOfBFS中调用,在这里不调用,如果两个都调用
14+
//则数据添加了两遍。
15+
da.printShortestPathOfBFS(vertex,end);
16+
17+
}
18+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package MaxflowMincut;
2+
3+
import java.util.List;
4+
5+
/**
6+
* FordFulkerson 方法求最大流问题,每次从残存网路中找到一个最短距离和最小容量,知道最后最小容量为0,结束。
7+
* @author liyafei
8+
*
9+
*/
10+
public class FordFulkersonMethod {
11+
DijkstraAlgorithm da=new DijkstraAlgorithm(100, 0);
12+
int vertex=0,end=5;
13+
public void fordFulkerson(){
14+
List list=da.createGraph("/page425InAlgorithm");
15+
// List list=da.createGraph("/page425InAlgorithm.txt");
16+
List<List> list2=da.shortestPathOfBFS(vertex, end);
17+
double d=da.minValueofPath( list2.get(end));
18+
da.printShortestPathOfBFS(vertex, end);
19+
20+
21+
}
22+
}
Lines changed: 279 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,279 @@
1+
package MaxflowMincut;
2+
3+
import java.io.InputStream;
4+
import java.text.DecimalFormat;
5+
import java.util.ArrayList;
6+
import java.util.List;
7+
import java.util.Scanner;
8+
9+
10+
11+
/**
12+
* Dijkstra算法求单源最短路径。
13+
* @author liyafei
14+
*
15+
*/
16+
public class DijkstraAlgorithm {
17+
protected Node[] graph; // 以数组的方式存储图,需要初始化指定数组的长度
18+
protected List<Node> list = new ArrayList<Node>(); // 以数组列表的形式存放图,可以不用初始化,直接添加
19+
Graph graphObj=new Graph(100,0);
20+
protected int maxSize;
21+
protected int gSize;
22+
public int count = 1;
23+
public double[][] weights;
24+
double[] smallWeight;
25+
int v=0; //定义一个常量,用于记录最小点数
26+
27+
List<List> list2=new ArrayList<>(); //这个列表中的元素为列表,元素列表用来记录查询最短路径过程中,
28+
//保存每个节点被查询到之前所经历的路径的。
29+
30+
/**
31+
* 构造函数
32+
* @param maxSize
33+
* @param gSize
34+
*/
35+
public DijkstraAlgorithm(int maxSize, int gSize) {
36+
this.maxSize = maxSize;
37+
this.gSize = gSize;
38+
graph = new Node[maxSize]; //存放节点的数组初始化,可以用List代替。
39+
}
40+
41+
/**
42+
* 图中的节点
43+
*
44+
* @author liyafei
45+
*
46+
* @param <> 节点中的泛型 有三个属性,下一节点,关键字,两个节点之间的权重, 权重应该以矩阵的方式存储(也就是一个二维数组)
47+
* 可以使用一个开始值(start)和结束值(end)来代表权重(weight)是哪两个节点的。
48+
* 例如:start=2,end=4,weight=8,那么表示2号节点和4号节点之间的权重值为8;
49+
* 可以在data.txt里面每个相邻节点后面跟上权重值。 如果求最短距离时,可以用sumWeight记录到该节点总距离的最短距离
50+
* 在执行广度优先搜索或者深度优先搜索时,可以用color标记每个节点的颜色,代表每个节点是否已经被搜索过。
51+
*/
52+
public class Node {
53+
double weight;
54+
Node link;
55+
int key;
56+
int start;
57+
int end;
58+
double sumWeight=0;
59+
String color="WHITE";
60+
}
61+
62+
/**
63+
* 得到创建的带有权重的图,读出相邻节点之间的距离,然后存储到二维数组weights中。
64+
* 权重图的大小比节点多1,但是角标为0的位置都没用,为了处理存储的位置与节点的编号相一致
65+
*/
66+
public double[][] getWeightArray(){
67+
weights=new double[list.size()][list.size()];
68+
for (int i = 0; i < list.size(); i++) {
69+
Node node=(Node) list.get(i);
70+
while(node!=null){
71+
int row=node.start-1;
72+
int col=node.end-1;
73+
double weight=node.weight;
74+
weights[row][col]=weight;
75+
node=node.link;
76+
}
77+
}
78+
return weights;
79+
}
80+
81+
/**
82+
* 根据权重数组,求最短路径。找出给定节点到所有节点的最短路径
83+
* 单源节点到其它所有节点的最短距离。
84+
*/
85+
public List shortestPathOfBFS(int vertex,int end){
86+
// int v=0; //定义一个常量,用于记录最小点数
87+
double minWeight;//定义一个常量,记录最小权重
88+
double[][] weis=getWeightArray();
89+
90+
int vertexNum=weis.length;
91+
int k=weis[vertex].length;
92+
smallWeight=new double[k];
93+
for (int i = 0; i < smallWeight.length; i++) {
94+
smallWeight[i]=weights[vertex][i];//将与vertex相邻节点的距离复制出来
95+
}
96+
boolean[] weightFound=new boolean[vertexNum];
97+
for (int i = 0; i < weightFound.length; i++) {
98+
weightFound[i]=false;
99+
List li=new ArrayList<>();
100+
li.add(vertex);
101+
list2.add(li);
102+
}
103+
weightFound[vertex]=true;
104+
smallWeight[vertex]=0; //源节点到源节点的距离设为0
105+
106+
for (int i = 0; i < weightFound.length; i++) {
107+
minWeight=Double.MAX_VALUE;
108+
for (int j = 0; j < weightFound.length; j++) {
109+
if(!weightFound[j]){
110+
if(smallWeight[j]<minWeight && smallWeight[j]>0){
111+
v=j;
112+
minWeight=smallWeight[v]; //与vertex相邻的节点最小距离,每次找到一个最小值。
113+
}
114+
}
115+
}
116+
list2.get(v).add(v);
117+
weightFound[v]=true; //最小的距离标记
118+
if(v==end){ //找到终点之后就结束。
119+
//System.out.println(v);
120+
break;
121+
}
122+
123+
for (int j = 0; j < weightFound.length; j++) {
124+
if(!weightFound[j]){
125+
if(minWeight+weis[v][j]<smallWeight[j]){ //如果从源点到v点加上从v点到j点的值,与从源点到j点值比较大小。
126+
smallWeight[j]=minWeight+weis[v][j];
127+
128+
//(v,j)的值记录下来,这是从源节点到j节点经过的路径为v。
129+
list2.get(j).add(v);
130+
}
131+
}
132+
}
133+
134+
}
135+
return list2;
136+
}
137+
138+
/**
139+
* 打印BFS最短距离
140+
* @param vertex 顶点
141+
* @param end 终点
142+
*/
143+
public void printShortestPathOfBFS(int vertex,int end){
144+
shortestPathOfBFS(vertex,end);
145+
DecimalFormat twoDigits=new DecimalFormat("0.00");
146+
// System.out.println("source vertex"+vertex);
147+
// System.out.println("shortest distance from the source to each vertex");
148+
//// for (int i = 0; i < list.size(); i++) {
149+
// System.out.println(" "+(i)+"\t\t"+twoDigits.format(smallWeight[i]));
150+
// System.out.println(" ");
151+
// }
152+
System.out.println();
153+
System.out.println("从源点"+vertex+"到终点"+end+"的最短距离 "+"\t\t"+twoDigits.format(smallWeight[v]));
154+
System.out.println("经过的路径");
155+
for (int i = 0; i < list2.get(end).size(); i++) {
156+
System.out.println(list2.get(end).get(i));//依次打印从源节点到终点的路径。
157+
}
158+
159+
double d=minValueofPath(list2.get(end));//将这条路径上的最小值找出,用于求最大流最小割问题。
160+
System.out.println("路径上的容量最小值"+d);
161+
}
162+
163+
/**
164+
* 找出源节点到终止节点路径上的最小容量。
165+
* @param list3 存放源节点到终止节点路径上节点的列表
166+
* @return 源节点到终止节点路径上最小容量
167+
*/
168+
public double minValueofPath(List list3) {
169+
// TODO Auto-generated method stub
170+
double d =Double.MAX_VALUE;
171+
double weight;
172+
for (int i = 0; i < list3.size()-1; i++) {
173+
weight=weights[(int) list3.get(i)][(int) list3.get(i+1)];
174+
if(weight<d){
175+
d=weight;
176+
}
177+
}
178+
return d;
179+
}
180+
181+
/**
182+
* 得到链表的长度
183+
* @param node
184+
* @return
185+
*/
186+
public int getLength(Node node){
187+
int length=0;
188+
while(node.link!=null){
189+
node=node.link;
190+
length++;
191+
}
192+
return length;
193+
}
194+
195+
/**
196+
* 创建图,以链表的方式创建图
197+
*
198+
* @return 返回图的链表形式,其中数组中每个位置是一个顶点的链表
199+
*/
200+
// public Node[] createGraph(){
201+
public List createGraph() {
202+
Class clazz = this.getClass();
203+
InputStream ins = clazz.getResourceAsStream("/data.txt"); // 通过外部数据创建链表,使用/加载src目录下的文件
204+
// 不使用/是加载类路径下的文件
205+
Scanner scanner = new Scanner(ins); // 流输入。
206+
while (scanner.hasNextLine()) {
207+
String s = scanner.nextLine();
208+
Scanner oneLine = new Scanner(s);
209+
Node first = null;
210+
Node newNode = null, last = null;
211+
while (oneLine.hasNext()) {
212+
String s1 = oneLine.next();
213+
214+
int num = Integer.parseInt(s1);
215+
if (num == 999)
216+
break;
217+
newNode = new Node();
218+
219+
if (first != null && oneLine.hasNext()) { // 创建first之后,读取下一节点时再读取权重
220+
String s2 = oneLine.next();// 读取权重
221+
double weight = Double.parseDouble(s2);
222+
newNode.weight = weight;
223+
newNode.end = num;
224+
}
225+
226+
// newNode.key=num; // 被 newNode.end=num;代替了
227+
228+
newNode.start = count;
229+
230+
newNode.link = null;
231+
if (first == null) {
232+
newNode.weight = 0;
233+
newNode.end = count;
234+
first = newNode;
235+
last = newNode;
236+
} else {
237+
last.link = newNode;
238+
last = newNode;
239+
}
240+
}
241+
graph[count] = first;
242+
list.add(first);
243+
count++;
244+
}
245+
return list;
246+
}
247+
248+
/**
249+
* 打印构建的图,起始节点,终止节点,起始节点到终止节点的权重
250+
*/
251+
public void printGraph(){
252+
for (int i = 0; i < list.size(); i++) {
253+
Node node=(Node) list.get(i);
254+
// System.out.println("以第"+(i+1)+"个节点为头节点的链表");
255+
//System.out.println(node.key);
256+
while(node!=null){
257+
// System.out.print("起始节点"+node.start+" ");
258+
// System.out.print("终止节点"+node.end+" ");
259+
// System.out.println("起始节点到终止节点的权重"+node.weight);
260+
node=node.link;
261+
}
262+
}
263+
}
264+
/**
265+
* 打印权重图
266+
*/
267+
public void printWeightGraph(){
268+
double[][] weightsArray=getWeightArray();
269+
for (int i = 0; i < weightsArray.length; i++) {
270+
System.out.println();
271+
double[] wa=weightsArray[i];
272+
for (int j = 0; j < wa.length; j++) {
273+
System.out.print(wa[j]+" ");
274+
}
275+
276+
}
277+
System.out.println();
278+
}
279+
}

0 commit comments

Comments
 (0)