Skip to content

Commit 375aef2

Browse files
authored
Add files via upload
1 parent 6204a2d commit 375aef2

File tree

1 file changed

+150
-0
lines changed

1 file changed

+150
-0
lines changed
Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
import java.util.ArrayDeque;
2+
import java.util.Queue;
3+
4+
/**
5+
* This implementation of Edmonds-Karp algorithms returns the maximum flow in a
6+
* Flow Network. It makes use of the Ford-Fulkerson method.
7+
*
8+
* @author Lukas Keul
9+
* @author Florian Mercks
10+
*/
11+
public class EdmondsKarpMaxFlow {
12+
13+
private long[][] edgeCapacity;
14+
private int[] parentNode;
15+
private boolean[] visitedNode;
16+
private long[][] maxFlowBetweenNodes;
17+
18+
@SuppressWarnings("unused")
19+
private int numOfN, numOfE;
20+
21+
public EdmondsKarpMaxFlow(int numberOfNodes, int numberOfEdges) {
22+
this.numOfN = numberOfNodes;
23+
this.numOfE = numberOfEdges;
24+
this.parentNode = new int[numOfN];
25+
this.visitedNode = new boolean[numOfN];
26+
this.edgeCapacity = new long[numOfN][numOfN];
27+
this.maxFlowBetweenNodes = new long[numOfN][numOfN];
28+
}
29+
30+
/**
31+
* Returns the maximum Flow in a Flow Network
32+
*
33+
* @param flowSource
34+
* represents the starting point of a maximum flow measurement in
35+
* a flow network
36+
* @param FlowTarget
37+
* represents the end point of a maximum flow measurement in a
38+
* flow network
39+
* @return maximum flow in the considered flow network
40+
*/
41+
public long getMaxFlow(int flowSource, int flowTarget) {
42+
while (true) {
43+
final Queue<Integer> flowSourceQueue = new ArrayDeque<Integer>();
44+
flowSourceQueue.add(flowSource);
45+
46+
// iterate through unvisited flowsources
47+
for (int i = 0; i < this.numOfN; ++i)
48+
visitedNode[i] = false;
49+
visitedNode[flowSource] = true;
50+
51+
boolean isFlowSourceChecked = false;
52+
int currentFlowSource;
53+
54+
// iterate throught the flowSourceQueue
55+
while (!flowSourceQueue.isEmpty()) {
56+
// give out the last Element of the Queue
57+
currentFlowSource = flowSourceQueue.peek();
58+
59+
// if the currentFlowSource is the flowTarget, we are done
60+
// iterating
61+
if (currentFlowSource == flowTarget) {
62+
isFlowSourceChecked = true;
63+
break;
64+
}
65+
66+
// remove last element from flowSourceQueue
67+
flowSourceQueue.remove();
68+
69+
// iterate through the number of nodes to check capacity size
70+
for (int i = 0; i < numOfN; ++i) {
71+
// if capacity is greater than the expected flow
72+
// then add the node to the flowSourceQueue
73+
if (!visitedNode[i]
74+
&& edgeCapacity[currentFlowSource][i] > maxFlowBetweenNodes[currentFlowSource][i]) {
75+
76+
visitedNode[i] = true;
77+
flowSourceQueue.add(i);
78+
parentNode[i] = currentFlowSource;
79+
}
80+
}
81+
}
82+
if (isFlowSourceChecked == false)
83+
break;
84+
85+
// subtract the maximum flow between the nodes from the edge
86+
// capacity
87+
long holdPartialResults = edgeCapacity[parentNode[flowTarget]][flowTarget]
88+
- maxFlowBetweenNodes[parentNode[flowTarget]][flowTarget];
89+
90+
// do a breadth first search from target to source to find minimum
91+
// needed capacity
92+
for (int i = flowTarget; i != flowSource; i = parentNode[i])
93+
holdPartialResults = Math.min(holdPartialResults,
94+
(edgeCapacity[parentNode[i]][i] - maxFlowBetweenNodes[parentNode[i]][i]));
95+
96+
// add all minimum needed capacities to the maximum flow between the
97+
// source and the target node
98+
for (int i = flowTarget; i != flowSource; i = parentNode[i]) {
99+
maxFlowBetweenNodes[parentNode[i]][i] += holdPartialResults;
100+
maxFlowBetweenNodes[i][parentNode[i]] -= holdPartialResults;
101+
}
102+
}
103+
104+
long result = 0;
105+
106+
// return the resulting maximum flow between the flowSource and the
107+
// flowTarget
108+
for (int i = 0; i < numOfN; ++i)
109+
result += maxFlowBetweenNodes[flowSource][i];
110+
return result;
111+
}
112+
113+
/**
114+
* Adds an Edge to the flow network
115+
*
116+
* @param fromNode
117+
* is the starting node of an edge
118+
* @param toNode
119+
* is the ending node of an edge
120+
* @param edgeCapacity
121+
* represents edge capacity used for the capacity function which
122+
* calculates the flow
123+
*/
124+
public void addEdge(int fromNode, int toNode, long edgeCapacity) {
125+
assert edgeCapacity >= 0;
126+
this.edgeCapacity[fromNode][toNode] += edgeCapacity;
127+
}
128+
129+
/**
130+
* main function to present the output for characters and integers
131+
*
132+
* @param args
133+
*/
134+
public static void main(String[] args) {
135+
136+
// test 1 with integer input
137+
System.out.println("Test:");
138+
EdmondsKarpMaxFlow edmondsKarpTest = new EdmondsKarpMaxFlow(7, 9);
139+
edmondsKarpTest.addEdge(0, 3, 3);
140+
edmondsKarpTest.addEdge(0, 1, 3);
141+
edmondsKarpTest.addEdge(1, 2, 4);
142+
edmondsKarpTest.addEdge(2, 0, 3);
143+
edmondsKarpTest.addEdge(2, 3, 1);
144+
edmondsKarpTest.addEdge(2, 4, 2);
145+
edmondsKarpTest.addEdge(3, 4, 2);
146+
edmondsKarpTest.addEdge(4, 1, 1);
147+
edmondsKarpTest.addEdge(4, 6, 1);
148+
System.out.println("The maximum flow from flowSource to flowTarget is " + (edmondsKarpTest.getMaxFlow(1, 4)) + ".");
149+
}
150+
}

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy