View Javadoc
1   /*
2   * Copyright (c) 2003, The JUNG Authors 
3   *
4   * All rights reserved.
5   *
6   * This software is open-source under the BSD license; see either
7   * "license.txt" or
8   * https://github.com/jrtom/jung/blob/master/LICENSE for a description.
9   */
10  package edu.uci.ics.jung.algorithms.flows;
11  
12  import java.util.HashMap;
13  import java.util.Map;
14  import java.util.Set;
15  
16  import junit.framework.Assert;
17  import junit.framework.Test;
18  import junit.framework.TestCase;
19  import junit.framework.TestSuite;
20  
21  import com.google.common.base.Functions;
22  import com.google.common.base.Supplier;
23  
24  import edu.uci.ics.jung.graph.DirectedGraph;
25  import edu.uci.ics.jung.graph.DirectedSparseMultigraph;
26  import edu.uci.ics.jung.graph.util.EdgeType;
27  
28  /**
29   * @author Scott White, Joshua O'Madadhain, Tom Nelson
30   */
31  public class TestEdmondsKarpMaxFlow extends TestCase {
32  
33  	public static Test suite() {
34  		return new TestSuite(TestEdmondsKarpMaxFlow.class);
35  	}
36  
37  	@Override
38    protected void setUp() {
39  
40  	}
41  
42      public void testSanityChecks() 
43      {
44          DirectedGraph<Number,Number> g = new DirectedSparseMultigraph<Number,Number>();
45          Number source = new Integer(1);
46          Number sink = new Integer(2);
47          g.addVertex(source);
48          g.addVertex(sink);
49          
50          Number v = new Integer(3);
51          
52          DirectedGraph<Number,Number> h = new DirectedSparseMultigraph<Number,Number>();
53          Number w = new Integer(4);
54          g.addVertex(w);
55          
56          try
57          {
58              new EdmondsKarpMaxFlow<Number,Number>(g, source, source, null, null, null);
59              fail("source and sink vertices not distinct");
60          }
61          catch (IllegalArgumentException iae) {}
62  
63          try
64          {
65              new EdmondsKarpMaxFlow<Number,Number>(h, source, w, null, null, null);
66              fail("source and sink vertices not both part of specified graph");
67          }
68          catch (IllegalArgumentException iae) {}
69  
70          try
71          {
72              new EdmondsKarpMaxFlow<Number,Number>(g, source, v, null, null, null);
73              fail("source and sink vertices not both part of specified graph");
74          }
75          catch (IllegalArgumentException iae) {}
76      }
77      
78  	public void testSimpleFlow() {
79  		DirectedGraph<Number,Number> graph = new DirectedSparseMultigraph<Number,Number>();
80  		Supplier<Number> edgeFactory = new Supplier<Number>() {
81  			int count = 0;
82  			public Number get() {
83  				return count++;
84  			}
85  		};
86  
87  		Map<Number,Number> edgeCapacityMap = new HashMap<Number,Number>();
88  		for(int i=0; i<6; i++) {
89  			graph.addVertex(i);
90  		}
91  		
92  		Map<Number,Number> edgeFlowMap = new HashMap<Number,Number>();
93  
94  		graph.addEdge(edgeFactory.get(),0,1,EdgeType.DIRECTED);
95  		edgeCapacityMap.put(0, 16);
96  
97  		graph.addEdge(edgeFactory.get(),0,2,EdgeType.DIRECTED);
98  		edgeCapacityMap.put(1,13);
99  
100 		graph.addEdge(edgeFactory.get(),1,2,EdgeType.DIRECTED);
101 		edgeCapacityMap.put(2, 6);
102 
103 		graph.addEdge(edgeFactory.get(),1,3,EdgeType.DIRECTED);
104 		edgeCapacityMap.put(3, 12);
105 
106 		graph.addEdge(edgeFactory.get(),2,4,EdgeType.DIRECTED);
107 		edgeCapacityMap.put(4, 14);
108 
109 		graph.addEdge(edgeFactory.get(),3,2,EdgeType.DIRECTED);
110 		edgeCapacityMap.put(5, 9);
111 
112 		graph.addEdge(edgeFactory.get(),3,5,EdgeType.DIRECTED);
113 		edgeCapacityMap.put(6, 20);
114 
115 		graph.addEdge(edgeFactory.get(),4,3,EdgeType.DIRECTED);
116 		edgeCapacityMap.put(7, 7);
117 
118 		graph.addEdge(edgeFactory.get(),4,5,EdgeType.DIRECTED);
119 		edgeCapacityMap.put(8, 4);
120 
121 		EdmondsKarpMaxFlow<Number,Number> ek =
122 			new EdmondsKarpMaxFlow<Number,Number>(
123 				graph,
124 				0,
125 				5,
126 				Functions.<Number,Number>forMap(edgeCapacityMap, null),
127 				edgeFlowMap,
128 				edgeFactory);
129 		ek.evaluate();
130 
131 		assertTrue(ek.getMaxFlow() == 23);
132         Set<Number> nodesInS = ek.getNodesInSourcePartition();
133         assertEquals(4,nodesInS.size());
134 
135         for (Number v : nodesInS) {
136             Assert.assertTrue(v.intValue() != 3 && v.intValue() != 5);
137         }
138 
139         Set<Number> nodesInT = ek.getNodesInSinkPartition();
140         assertEquals(2,nodesInT.size());
141 
142         for (Number v : nodesInT) {
143             Assert.assertTrue(v.intValue() == 3 || v.intValue() == 5);
144         }
145 
146         Set<Number> minCutEdges = ek.getMinCutEdges();
147         int maxFlow = 0;
148         for (Number e : minCutEdges) {
149             Number flow = edgeFlowMap.get(e);
150             maxFlow += flow.intValue();
151         }
152         Assert.assertEquals(23,maxFlow);
153         Assert.assertEquals(3,minCutEdges.size());
154 	}
155 
156 	public void testAnotherSimpleFlow() {
157 		DirectedGraph<Number,Number> graph = new DirectedSparseMultigraph<Number,Number>();
158 		Supplier<Number> edgeFactory = new Supplier<Number>() {
159 			int count=0;
160 			public Number get() {
161 				return count++;
162 			}
163 		};
164 
165 		Map<Number,Number> edgeCapacityMap = new HashMap<Number,Number>();
166 		for(int i=0; i<6; i++) {
167 			graph.addVertex(i);
168 		}
169 		
170 		Map<Number,Number> edgeFlowMap = new HashMap<Number,Number>();
171 
172 		graph.addEdge(edgeFactory.get(),0,1,EdgeType.DIRECTED);
173 		edgeCapacityMap.put(0,5);
174 		
175 		graph.addEdge(edgeFactory.get(),0,2,EdgeType.DIRECTED);
176 		edgeCapacityMap.put(1,3);
177 		
178 		graph.addEdge(edgeFactory.get(),1,5,EdgeType.DIRECTED);
179 		edgeCapacityMap.put(2,2);
180 		
181 		graph.addEdge(edgeFactory.get(),1,2,EdgeType.DIRECTED);
182 		edgeCapacityMap.put(3,8);
183 		
184 		graph.addEdge(edgeFactory.get(),2,3,EdgeType.DIRECTED);
185 		edgeCapacityMap.put(4,4);
186 		
187 		graph.addEdge(edgeFactory.get(),2,4,EdgeType.DIRECTED);
188 		edgeCapacityMap.put(5,2);
189 		
190 		graph.addEdge(edgeFactory.get(),3,4,EdgeType.DIRECTED);
191 		edgeCapacityMap.put(6,3);
192 		
193 		graph.addEdge(edgeFactory.get(),3,5,EdgeType.DIRECTED);
194 		edgeCapacityMap.put(7,6);
195 		
196 		graph.addEdge(edgeFactory.get(),4,5,EdgeType.DIRECTED);
197 		edgeCapacityMap.put(8,1);
198 
199 		EdmondsKarpMaxFlow<Number,Number> ek =
200 			new EdmondsKarpMaxFlow<Number,Number>(
201 				graph,
202 				0,
203 				5,
204 				Functions.<Number,Number>forMap(edgeCapacityMap, null),
205 				edgeFlowMap,
206 				edgeFactory);
207 		ek.evaluate();
208 
209 		assertTrue(ek.getMaxFlow() == 7);
210 	}
211 }