in graphLayout/jetbrains.mps.graphLayout.graph/source_gen/jetbrains/mps/graphLayout/algorithms/MinCostMaxFlowWithPotentials.java [20:89]
public static Map<Edge, Integer> getFlow(Graph graph, Node source, Node target, Map<Edge, Integer> initialCapacity, Map<Edge, Integer> initialCost) {
double time = System.currentTimeMillis();
Map<Edge, Integer> flow = MapSequence.fromMap(new HashMap<Edge, Integer>());
Map<Edge, Edge> opposite = MapSequence.fromMap(new HashMap<Edge, Edge>());
final Map<Edge, Integer> capacity = MapSequence.fromMap(new HashMap<Edge, Integer>());
Map<Edge, Integer> cost = MapSequence.fromMap(new HashMap<Edge, Integer>());
Set<Edge> dummyEdges = SetSequence.fromSet(new HashSet<Edge>());
for (Edge edge : ListSequence.fromList(graph.getEdges())) {
MapSequence.fromMap(capacity).put(edge, MapSequence.fromMap(initialCapacity).get(edge));
MapSequence.fromMap(cost).put(edge, MapSequence.fromMap(initialCost).get(edge));
MapSequence.fromMap(flow).put(edge, 0);
Edge oppositeEdge = graph.connect(edge.getTarget(), edge.getSource());
MapSequence.fromMap(opposite).put(edge, oppositeEdge);
MapSequence.fromMap(opposite).put(oppositeEdge, edge);
MapSequence.fromMap(capacity).put(oppositeEdge, 0);
MapSequence.fromMap(cost).put(oppositeEdge, -MapSequence.fromMap(cost).get(edge));
SetSequence.fromSet(dummyEdges).addElement(oppositeEdge);
}
boolean hasPath = true;
int numIter = 0;
while (hasPath) {
numIter++;
Dijkstra shortestPathFinder = new Dijkstra(graph, source, cost);
shortestPathFinder.doAlgorithm(new _FunctionTypes._return_P1_E0<Boolean, Edge>() {
public Boolean invoke(Edge edge) {
return MapSequence.fromMap(capacity).get(edge) > 0;
}
}, Edge.Direction.FRONT);
List<Edge> path = shortestPathFinder.getShortestPath(target);
if (path == null) {
hasPath = false;
} else {
int minCapacity = Integer.MAX_VALUE;
for (Edge edge : ListSequence.fromList(path)) {
minCapacity = Math.min(minCapacity, MapSequence.fromMap(capacity).get(edge));
}
for (Edge edge : ListSequence.fromList(path)) {
if (SetSequence.fromSet(dummyEdges).contains(edge)) {
Edge realEdge = MapSequence.fromMap(opposite).get(edge);
MapSequence.fromMap(flow).put(realEdge, MapSequence.fromMap(flow).get(realEdge) - minCapacity);
MapSequence.fromMap(capacity).put(realEdge, MapSequence.fromMap(capacity).get(realEdge) + minCapacity);
MapSequence.fromMap(capacity).put(edge, MapSequence.fromMap(flow).get(realEdge));
} else {
MapSequence.fromMap(flow).put(edge, MapSequence.fromMap(flow).get(edge) + minCapacity);
MapSequence.fromMap(capacity).put(edge, MapSequence.fromMap(capacity).get(edge) - minCapacity);
MapSequence.fromMap(capacity).put(MapSequence.fromMap(opposite).get(edge), MapSequence.fromMap(flow).get(edge));
}
}
Map<Node, Integer> distance = shortestPathFinder.getDistance();
for (Edge edge : ListSequence.fromList(graph.getEdges())) {
if ((Integer) MapSequence.fromMap(distance).get(edge.getSource()) == ShortestPath.INF) {
continue;
}
MapSequence.fromMap(cost).put(edge, MapSequence.fromMap(cost).get(edge) + MapSequence.fromMap(distance).get(edge.getSource()) - MapSequence.fromMap(distance).get(edge.getTarget()));
if (MapSequence.fromMap(cost).get(edge) < 0 && MapSequence.fromMap(capacity).get(edge) > 0) {
throw new RuntimeException("wrong ponetials");
}
}
}
}
for (Edge edge : SetSequence.fromSet(dummyEdges)) {
graph.removeEdge(edge);
}
if (MinCostMaxFlowWithPotentials.SHOW_TIME > 0) {
System.out.println("Min cost max flow algorithm on network with " + ListSequence.fromList(graph.getNodes()).count() + " nodes and " + ListSequence.fromList(graph.getEdges()).count() + " edges");
System.out.println("flow found in " + numIter + " iterations");
System.out.println("working time is " + ((System.currentTimeMillis() - time) / 1000) + " seconds");
}
return flow;
}