Commit a9eddb21 authored by gsavin's avatar gsavin

Add new flow algorithm Edmonds-Karp.

parent 7a5e4b67
/*
* Copyright 2006 - 2012
* Stefan Balev <stefan.balev@graphstream-project.org>
* Julien Baudry <julien.baudry@graphstream-project.org>
* Antoine Dutot <antoine.dutot@graphstream-project.org>
* Yoann Pigné <yoann.pigne@graphstream-project.org>
* Guilhelm Savin <guilhelm.savin@graphstream-project.org>
*
* This file is part of GraphStream <http://graphstream-project.org>.
*
* GraphStream is a library whose purpose is to handle static or dynamic
* graph, create them from scratch, file or any source and display them.
*
* This program is free software distributed under the terms of two licenses, the
* CeCILL-C license that fits European law, and the GNU Lesser General Public
* License. You can use, modify and/ or redistribute the software under the terms
* of the CeCILL-C license as circulated by CEA, CNRS and INRIA at the following
* URL <http://www.cecill.info> or under the terms of the GNU LGPL as published by
* the Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* The fact that you are presently reading this means that you have had
* knowledge of the CeCILL-C and LGPL licenses and that you accept their terms.
*/
package org.graphstream.algorithm.flow.test;
import java.io.IOException;
import java.io.InputStream;
import org.graphstream.algorithm.flow.EdmondsKarpAlgorithm;
import org.graphstream.algorithm.flow.FlowAlgorithm;
public class TestEdmondsKarpAlgorithm extends TestFlowAlgorithm {
/*
* (non-Javadoc)
*
* @see
* org.graphstream.algorithm.flow.test.TestFlowAlgorithm#getGraphStream()
*/
public InputStream getGraphStream() throws IOException {
return getClass().getResourceAsStream(
"data/TestFordFulkersonAlgorithm.dgs");
}
/*
* (non-Javadoc)
*
* @see
* org.graphstream.algorithm.flow.test.TestFlowAlgorithm#getFlowAlgorithm()
*/
public FlowAlgorithm getFlowAlgorithm() {
return new EdmondsKarpAlgorithm();
}
}
/*
* Copyright 2006 - 2012
* Stefan Balev <stefan.balev@graphstream-project.org>
* Julien Baudry <julien.baudry@graphstream-project.org>
* Antoine Dutot <antoine.dutot@graphstream-project.org>
* Yoann Pigné <yoann.pigne@graphstream-project.org>
* Guilhelm Savin <guilhelm.savin@graphstream-project.org>
*
* This file is part of GraphStream <http://graphstream-project.org>.
*
* GraphStream is a library whose purpose is to handle static or dynamic
* graph, create them from scratch, file or any source and display them.
*
* This program is free software distributed under the terms of two licenses, the
* CeCILL-C license that fits European law, and the GNU Lesser General Public
* License. You can use, modify and/ or redistribute the software under the terms
* of the CeCILL-C license as circulated by CEA, CNRS and INRIA at the following
* URL <http://www.cecill.info> or under the terms of the GNU LGPL as published by
* the Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* The fact that you are presently reading this means that you have had
* knowledge of the CeCILL-C and LGPL licenses and that you accept their terms.
*/
package org.graphstream.algorithm.flow.test;
import static org.junit.Assert.assertTrue;
import java.io.IOException;
import java.io.InputStream;
import org.graphstream.algorithm.flow.FlowAlgorithm;
import org.graphstream.graph.Graph;
import org.graphstream.graph.implementations.AdjacencyListGraph;
import org.graphstream.stream.file.FileSourceDGS;
import org.junit.Before;
import org.junit.Test;
public abstract class TestFlowAlgorithm {
Graph g;
FileSourceDGS dgs;
public abstract InputStream getGraphStream() throws IOException;
public abstract FlowAlgorithm getFlowAlgorithm();
@Before
public void load() throws IOException {
dgs = new FileSourceDGS();
g = new AdjacencyListGraph("flow-test");
dgs.addSink(g);
dgs.begin(getGraphStream());
}
@Test
public void testFlowAlgorithm() throws IOException {
FlowAlgorithm flowAlgo = getFlowAlgorithm();
double maximumFlow;
flowAlgo.setCapacityAttribute("cap");
while (dgs.nextStep()) {
flowAlgo.init(g, "s", "t");
flowAlgo.compute();
maximumFlow = flowAlgo.getMaximumFlow();
assertTrue(maximumFlow == g.getNumber("expected maximum flow"));
}
}
}
......@@ -31,44 +31,31 @@
*/
package org.graphstream.algorithm.flow.test;
import static org.junit.Assert.assertTrue;
import java.io.IOException;
import java.io.InputStream;
import org.graphstream.algorithm.flow.FlowAlgorithm;
import org.graphstream.algorithm.flow.FordFulkersonAlgorithm;
import org.graphstream.graph.Graph;
import org.graphstream.graph.implementations.AdjacencyListGraph;
import org.graphstream.stream.file.FileSourceDGS;
import org.junit.Before;
import org.junit.Test;
public class TestFordFulkersonAlgorithm {
Graph g;
FileSourceDGS dgs;
@Before
public void load() throws IOException {
dgs = new FileSourceDGS();
g = new AdjacencyListGraph("test");
dgs.addSink(g);
dgs.begin(getClass().getResourceAsStream(
"data/TestFordFulkersonAlgorithm.dgs"));
public class TestFordFulkersonAlgorithm extends TestFlowAlgorithm {
/*
* (non-Javadoc)
*
* @see
* org.graphstream.algorithm.flow.test.TestFlowAlgorithm#getGraphStream()
*/
public InputStream getGraphStream() throws IOException {
return getClass().getResourceAsStream(
"data/TestFordFulkersonAlgorithm.dgs");
}
@Test
public void testFordFulkerson() throws IOException {
FordFulkersonAlgorithm flowAlgo = new FordFulkersonAlgorithm();
double maximumFlow;
flowAlgo.setCapacityAttribute("cap");
while (dgs.nextStep()) {
flowAlgo.init(g, "s", "t");
flowAlgo.compute();
maximumFlow = flowAlgo.getMaximumFlow();
assertTrue(maximumFlow == g.getNumber("expected maximum flow"));
}
/*
* (non-Javadoc)
*
* @see
* org.graphstream.algorithm.flow.test.TestFlowAlgorithm#getFlowAlgorithm()
*/
public FlowAlgorithm getFlowAlgorithm() {
return new FordFulkersonAlgorithm();
}
}
/*
* Copyright 2006 - 2012
* Stefan Balev <stefan.balev@graphstream-project.org>
* Julien Baudry <julien.baudry@graphstream-project.org>
* Antoine Dutot <antoine.dutot@graphstream-project.org>
* Yoann Pigné <yoann.pigne@graphstream-project.org>
* Guilhelm Savin <guilhelm.savin@graphstream-project.org>
*
* This file is part of GraphStream <http://graphstream-project.org>.
*
* GraphStream is a library whose purpose is to handle static or dynamic
* graph, create them from scratch, file or any source and display them.
*
* This program is free software distributed under the terms of two licenses, the
* CeCILL-C license that fits European law, and the GNU Lesser General Public
* License. You can use, modify and/ or redistribute the software under the terms
* of the CeCILL-C license as circulated by CEA, CNRS and INRIA at the following
* URL <http://www.cecill.info> or under the terms of the GNU LGPL as published by
* the Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* The fact that you are presently reading this means that you have had
* knowledge of the CeCILL-C and LGPL licenses and that you accept their terms.
*/
package org.graphstream.algorithm.flow;
import java.util.Arrays;
import java.util.LinkedList;
import org.graphstream.graph.Edge;
import org.graphstream.graph.Node;
public class EdmondsKarpAlgorithm extends FordFulkersonAlgorithm {
/*
* (non-Javadoc)
*
* @see
* org.graphstream.algorithm.flow.FordFulkersonAlgorithm#findPath(java.util
* .LinkedList, org.graphstream.graph.Node, org.graphstream.graph.Node)
*/
protected double findPath(LinkedList<Node> path, Node source, Node target) {
LinkedList<Node> Q = new LinkedList<Node>();
Node u;
int[] P = new int[source.getGraph().getNodeCount()];
double[] M = new double[source.getGraph().getNodeCount()];
double r;
Arrays.fill(P, -1);
P[source.getIndex()] = -2;
M[source.getIndex()] = Double.MAX_VALUE;
Q.add(source);
while (Q.size() > 0) {
u = Q.pop();
for (int i = 0; i < u.getDegree(); i++) {
Edge e = u.getEdge(i);
Node v = e.getOpposite(u);
r = getCapacity(u, v) - getFlow(u, v);
if (r > 0 && P[v.getIndex()] == -1) {
P[v.getIndex()] = u.getIndex();
M[v.getIndex()] = Math.min(M[u.getIndex()], r);
if (v != target)
Q.push(v);
else {
u = target;
do {
path.addFirst(u);
u = flowGraph.getNode(P[u.getIndex()]);
} while (u != source);
path.addFirst(u);
return M[target.getIndex()];
}
}
}
}
return 0;
}
}
......@@ -72,19 +72,10 @@ public class FordFulkersonAlgorithm extends FlowAlgorithmBase {
setFlow(e.getNode1(), e.getNode0(), 0);
}
double minCf;
LinkedList<Node> path = new LinkedList<Node>();
path.add(source);
while (findPath(path, source, sink)) {
double minCf = Double.MAX_VALUE;
for (int i = 1; i < path.size(); i++) {
Node u = path.get(i - 1);
Node v = path.get(i);
minCf = Math.min(minCf, getCapacity(u, v) - getFlow(u, v));
}
while ((minCf = findPath(path, source, sink)) > 0) {
for (int i = 1; i < path.size(); i++) {
Node u = path.get(i - 1);
Node v = path.get(i);
......@@ -94,7 +85,6 @@ public class FordFulkersonAlgorithm extends FlowAlgorithmBase {
}
path.clear();
path.add(source);
}
double flow = 0;
......@@ -105,9 +95,13 @@ public class FordFulkersonAlgorithm extends FlowAlgorithmBase {
maximumFlow = flow;
}
protected boolean findPath(LinkedList<Node> path, Node source, Node target) {
protected double findPath(LinkedList<Node> path, Node source, Node target) {
path.addLast(source);
if (source == target)
return true;
return Double.MAX_VALUE;
double minCf;
for (int i = 0; i < source.getDegree(); i++) {
Edge e = source.getEdge(i);
......@@ -115,15 +109,13 @@ public class FordFulkersonAlgorithm extends FlowAlgorithmBase {
if (getCapacity(source, o) - getFlow(source, o) > 0
&& !path.contains(o)) {
path.addLast(o);
if (findPath(path, o, target))
return true;
path.removeLast();
if ((minCf = findPath(path, o, target)) > 0)
return Math.min(minCf,
getCapacity(source, o) - getFlow(source, o));
}
}
return false;
path.removeLast();
return 0;
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment