All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.salesforce.jgrapht.alg.flow.GusfieldEquivalentFlowTree Maven / Gradle / Ivy

Go to download

This project contains the apt processor that implements all the checks enumerated in @Verify. It is a self contained, and shaded jar.

There is a newer version: 2.0.7
Show newest version
/*
 * (C) Copyright 2016-2017, by Joris Kinable and Contributors.
 *
 * JGraphT : a free Java graph-theory library
 *
 * This program and the accompanying materials are dual-licensed under
 * either
 *
 * (a) the terms of the GNU Lesser General Public License version 2.1
 * as published by the Free Software Foundation, or (at your option) any
 * later version.
 *
 * or (per the licensee's choosing)
 *
 * (b) the terms of the Eclipse Public License v1.0 as published by
 * the Eclipse Foundation.
 */
package com.salesforce.jgrapht.alg.flow;

import java.util.*;

import com.salesforce.jgrapht.*;
import com.salesforce.jgrapht.alg.interfaces.*;
import com.salesforce.jgrapht.graph.*;

/**
 * This class computes an Equivalent Flow Tree (EFT) using the algorithm proposed by Dan Gusfield.
 * EFTs can be used to efficiently calculate the maximum flow for all pairs of vertices. The
 * algorithm is described in: Gusfield, D, Very simple methods for all pairs network flow
 * analysis. SIAM Journal on Computing, 19(1), p142-155, 1990
* In an undirected graph, there exist n(n-1)/2 different vertex pairs. This class computes the * maximum flow between each of these pairs efficiently by performing exactly (n-1) minimum s-t cut * computations. If your application requires fewer than (n-1) flow calculations, consider computing * the maximum flows manually through {@link MaximumFlowAlgorithm}. * * *

* The runtime complexity of this class is O((V-1)Q), where Q is the runtime complexity of the * algorithm used to compute s-t cuts in the graph. By default, this class uses the * {@link PushRelabelMFImpl} implementation to calculate minimum s-t cuts. This class has a runtime * complexity of O(V^3), resulting in a O(V^4) runtime complexity for the overal algorithm. * * *

* Note: this class performs calculations in a lazy manner. The EFT is not calculated until the * first invocation of {@link GusfieldEquivalentFlowTree#calculateMaximumFlow(Object, Object)} or * {@link GusfieldEquivalentFlowTree#getEquivalentFlowTree()}. Moreover, this class only * calculates the value of the maximum flow between a source-destination pair; it does not calculate * the corresponding flow per edge. If you need to know the exact flow through an edge, use one of * the alternative {@link MaximumFlowAlgorithm} implementations. * *

* Warning: EFTs do not allow you to calculate minimum cuts for all pairs of vertex! For that, * Gomory-Hu cut trees are required! Use the {@link GusfieldGomoryHuCutTree} implementation instead. * *

* This class does not support changes to the underlying graph. The behavior of this class is * undefined when the graph is modified after instantiating this class. * * @param the graph vertex type * @param the graph edge type * * @author Joris Kinable * @since January 2016 */ public class GusfieldEquivalentFlowTree implements MaximumFlowAlgorithm { /* Number of vertices in the graph */ private final int N; /* Algorithm used to computed the Maximum s-t flows */ private final MinimumSTCutAlgorithm minimumSTCutAlgorithm; /* Data structures for computations */ private List vertexList = new ArrayList<>(); private Map indexMap = new HashMap<>(); private int[] p; // See vector p in the paper description private int[] neighbors; /* Matrix containing the flow values for every s-t pair */ private double[][] flowMatrix = null; private V lastInvokedSource = null; private V lastInvokedTarget = null; /** * Constructs a new GusfieldEquivalentFlowTree instance. * * @param network input graph */ public GusfieldEquivalentFlowTree(Graph network) { this(network, MaximumFlowAlgorithmBase.DEFAULT_EPSILON); } /** * Constructs a new GusfieldEquivalentFlowTree instance. * * @param network input graph * @param epsilon precision */ public GusfieldEquivalentFlowTree(Graph network, double epsilon) { this(network, new PushRelabelMFImpl<>(network, epsilon)); } /** * Constructs a new GusfieldEquivalentFlowTree instance. * * @param network input graph * @param minimumSTCutAlgorithm algorithm used to compute the minimum s-t cuts */ public GusfieldEquivalentFlowTree( Graph network, MinimumSTCutAlgorithm minimumSTCutAlgorithm) { if (!(network instanceof UndirectedGraph)) throw new IllegalArgumentException("Graph must be undirected"); this.N = network.vertexSet().size(); if (N < 2) throw new IllegalArgumentException("Graph must have at least 2 vertices"); this.minimumSTCutAlgorithm = minimumSTCutAlgorithm; vertexList.addAll(network.vertexSet()); for (int i = 0; i < vertexList.size(); i++) indexMap.put(vertexList.get(i), i); } /** * Runs the algorithm */ private void calculateEquivalentFlowTree() { flowMatrix = new double[N][N]; p = new int[N]; neighbors = new int[N]; for (int s = 1; s < N; s++) { int t = p[s]; neighbors[s] = t; double flowValue = minimumSTCutAlgorithm.calculateMinCut(vertexList.get(s), vertexList.get(t)); Set sourcePartition = minimumSTCutAlgorithm.getSourcePartition(); // Set X in the // paper for (int i = s; i < N; i++) if (sourcePartition.contains(vertexList.get(i)) && p[i] == t) p[i] = s; // populate the flow matrix flowMatrix[s][t] = flowMatrix[t][s] = flowValue; for (int i = 0; i < s; i++) if (i != t) flowMatrix[s][i] = flowMatrix[i][s] = Math.min(flowMatrix[s][t], flowMatrix[t][i]); } } /** * Returns the Equivalent Flow Tree as an actual tree (graph). Note that this tree is not * necessarily unique. The edge weights represent the flow values/cut weights. This method runs * in O(n) time * * @return Equivalent Flow Tree */ public SimpleWeightedGraph getEquivalentFlowTree() { if (p == null) // Lazy invocation of the algorithm this.calculateEquivalentFlowTree(); SimpleWeightedGraph equivalentFlowTree = new SimpleWeightedGraph<>(DefaultWeightedEdge.class); Graphs.addAllVertices(equivalentFlowTree, vertexList); for (int i = 1; i < N; i++) { DefaultWeightedEdge e = equivalentFlowTree.addEdge(vertexList.get(i), vertexList.get(neighbors[i])); equivalentFlowTree.setEdgeWeight(e, flowMatrix[i][neighbors[i]]); } return equivalentFlowTree; } /** * Unsupported operation * * @param source source of the flow inside the network * @param sink sink of the flow inside the network * * @return nothing */ @Override public MaximumFlow getMaximumFlow(V source, V sink) { throw new UnsupportedOperationException( "Flows calculated via Equivalent Flow trees only provide a maximum flow value, not the exact flow per edge/arc."); } /** * Returns the Maximum flow between source and sink. The algorithm is only executed once; * successive invocations of this method will return in O(1) time. * * @param source source vertex * @param sink sink vertex * @return the Maximum flow between source and sink. */ @Override public double calculateMaximumFlow(V source, V sink) { assert indexMap.containsKey(source) && indexMap.containsKey(sink); lastInvokedSource = source; lastInvokedTarget = sink; if (p == null) // Lazy invocation of the algorithm this.calculateEquivalentFlowTree(); return flowMatrix[indexMap.get(source)][indexMap.get(sink)]; } /** * Returns maximum flow value, that was calculated during last * calculateMaximumFlow call. * * @return maximum flow value */ @Override public double getMaximumFlowValue() { return calculateMaximumFlow(lastInvokedSource, lastInvokedTarget); } /** * Unsupported operation * * @return nothing */ @Override public Map getFlowMap() { throw new UnsupportedOperationException( "Flows calculated via Equivalent Flow trees only provide a maximum flow value, not the exact flow per edge/arc."); } /** * Unsupported operation * * @param e edge * @return nothing */ @Override public V getFlowDirection(E e) { throw new UnsupportedOperationException( "Flows calculated via Equivalent Flow trees only provide a maximum flow value, not the exact flow per edge/arc."); } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy