Skip to content

Commit

Permalink
Public API implementations for MinimumEdgeCutST
Browse files Browse the repository at this point in the history
  • Loading branch information
barakugav committed Mar 25, 2024
1 parent 8b2d306 commit f66e7cf
Show file tree
Hide file tree
Showing 3 changed files with 120 additions and 107 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
/*-
* Copyright 2023 Barak Ugav
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.jgalgo.alg.connect;

import java.util.Collection;
import com.jgalgo.alg.IVertexBiPartition;
import com.jgalgo.alg.VertexBiPartition;
import com.jgalgo.graph.Graph;
import com.jgalgo.graph.IWeightFunction;
import com.jgalgo.graph.IndexGraph;
import com.jgalgo.graph.IndexIdMap;
import com.jgalgo.graph.IndexIdMaps;
import com.jgalgo.graph.WeightFunction;
import com.jgalgo.graph.WeightFunctions;
import com.jgalgo.internal.util.IntAdapters;
import it.unimi.dsi.fastutil.ints.IntCollection;

/**
* Abstract class for computing the minimum edge cut between two vertices in a graph.
*
* <p>
* The class implements the interface by solving the problem on the index graph and then maps the results back to the
* original graph. The implementation for the index graph is abstract and left to the subclasses.
*
* @author Barak Ugav
*/
public abstract class MinimumEdgeCutSTAbstract implements MinimumEdgeCutST {

/**
* Default constructor.
*/
public MinimumEdgeCutSTAbstract() {}

@SuppressWarnings("unchecked")
@Override
public <V, E> VertexBiPartition<V, E> computeMinimumCut(Graph<V, E> g, WeightFunction<E> w, V source, V sink) {
if (g instanceof IndexGraph) {
IWeightFunction w0 = WeightFunctions.asIntGraphWeightFunc((WeightFunction<Integer>) w);
int source0 = ((Integer) source).intValue(), sink0 = ((Integer) sink).intValue();
return (VertexBiPartition<V, E>) computeMinimumCut((IndexGraph) g, w0, source0, sink0);

} else {
IndexGraph iGraph = g.indexGraph();
IndexIdMap<V> viMap = g.indexGraphVerticesMap();
IndexIdMap<E> eiMap = g.indexGraphEdgesMap();
IWeightFunction iw = IndexIdMaps.idToIndexWeightFunc(w, eiMap);
int iSource = viMap.idToIndex(source);
int iSink = viMap.idToIndex(sink);
IVertexBiPartition indexCut = computeMinimumCut(iGraph, iw, iSource, iSink);
return VertexBiPartition.partitionFromIndexPartition(g, indexCut);
}
}

@SuppressWarnings("unchecked")
@Override
public <V, E> VertexBiPartition<V, E> computeMinimumCut(Graph<V, E> g, WeightFunction<E> w, Collection<V> sources,
Collection<V> sinks) {
if (g instanceof IndexGraph) {
IWeightFunction w0 = WeightFunctions.asIntGraphWeightFunc((WeightFunction<Integer>) w);
IntCollection sources0 = IntAdapters.asIntCollection((Collection<Integer>) sources);
IntCollection sinks0 = IntAdapters.asIntCollection((Collection<Integer>) sinks);
return (VertexBiPartition<V, E>) computeMinimumCut((IndexGraph) g, w0, sources0, sinks0);

} else {
IndexGraph iGraph = g.indexGraph();
IndexIdMap<V> viMap = g.indexGraphVerticesMap();
IndexIdMap<E> eiMap = g.indexGraphEdgesMap();
IWeightFunction iw = IndexIdMaps.idToIndexWeightFunc(w, eiMap);
IntCollection iSources = IndexIdMaps.idToIndexCollection(sources, viMap);
IntCollection iSinks = IndexIdMaps.idToIndexCollection(sinks, viMap);
IVertexBiPartition indexCut = computeMinimumCut(iGraph, iw, iSources, iSinks);
return VertexBiPartition.partitionFromIndexPartition(g, indexCut);
}
}

/**
* Compute the minimum edge-cut in a graph between two terminal vertices.
*
* @see #computeMinimumCut(Graph, WeightFunction, Object, Object)
* @param g a graph
* @param w an edge weight function
* @param source a special vertex that will be in \(C\)
* @param sink a special vertex that will be in \(\bar{C}\)
* @return the cut that was computed
*/
protected abstract IVertexBiPartition computeMinimumCut(IndexGraph g, IWeightFunction w, int source, int sink);

/**
* Compute the minimum edge-cut in a graph between two sets of vertices.
*
* @see #computeMinimumCut(Graph, WeightFunction, Collection, Collection)
* @param g a graph
* @param w an edge weight function
* @param sources special vertices that will be in \(C\)
* @param sinks special vertices that will be in \(\bar{C}\)
* @return the minimum cut between the two sets
*/
protected abstract IVertexBiPartition computeMinimumCut(IndexGraph g, IWeightFunction w, IntCollection sources,
IntCollection sinks);

}
Original file line number Diff line number Diff line change
Expand Up @@ -16,22 +16,14 @@
package com.jgalgo.alg.connect;

import static com.jgalgo.internal.util.Range.range;
import java.util.Collection;
import com.jgalgo.alg.IVertexBiPartition;
import com.jgalgo.alg.VertexBiPartition;
import com.jgalgo.alg.flow.IFlow;
import com.jgalgo.alg.flow.MaximumFlow;
import com.jgalgo.graph.Graph;
import com.jgalgo.graph.IEdgeIter;
import com.jgalgo.graph.IWeightFunction;
import com.jgalgo.graph.IndexGraph;
import com.jgalgo.graph.IndexIdMap;
import com.jgalgo.graph.IndexIdMaps;
import com.jgalgo.graph.WeightFunction;
import com.jgalgo.graph.WeightFunctions;
import com.jgalgo.internal.util.Bitmap;
import com.jgalgo.internal.util.FIFOQueueIntNoReduce;
import com.jgalgo.internal.util.IntAdapters;
import it.unimi.dsi.fastutil.ints.IntCollection;
import it.unimi.dsi.fastutil.ints.IntLists;
import it.unimi.dsi.fastutil.ints.IntPriorityQueue;
Expand All @@ -40,57 +32,6 @@ class MinimumEdgeCutUtils {

private MinimumEdgeCutUtils() {}

abstract static class AbstractImplST implements MinimumEdgeCutST {

@SuppressWarnings("unchecked")
@Override
public <V, E> VertexBiPartition<V, E> computeMinimumCut(Graph<V, E> g, WeightFunction<E> w, V source, V sink) {
if (g instanceof IndexGraph) {
IWeightFunction w0 = WeightFunctions.asIntGraphWeightFunc((WeightFunction<Integer>) w);
int source0 = ((Integer) source).intValue(), sink0 = ((Integer) sink).intValue();
return (VertexBiPartition<V, E>) computeMinimumCut((IndexGraph) g, w0, source0, sink0);

} else {
IndexGraph iGraph = g.indexGraph();
IndexIdMap<V> viMap = g.indexGraphVerticesMap();
IndexIdMap<E> eiMap = g.indexGraphEdgesMap();
IWeightFunction iw = IndexIdMaps.idToIndexWeightFunc(w, eiMap);
int iSource = viMap.idToIndex(source);
int iSink = viMap.idToIndex(sink);
IVertexBiPartition indexCut = computeMinimumCut(iGraph, iw, iSource, iSink);
return VertexBiPartition.partitionFromIndexPartition(g, indexCut);
}
}

@SuppressWarnings("unchecked")
@Override
public <V, E> VertexBiPartition<V, E> computeMinimumCut(Graph<V, E> g, WeightFunction<E> w,
Collection<V> sources, Collection<V> sinks) {
if (g instanceof IndexGraph) {
IWeightFunction w0 = WeightFunctions.asIntGraphWeightFunc((WeightFunction<Integer>) w);
IntCollection sources0 = IntAdapters.asIntCollection((Collection<Integer>) sources);
IntCollection sinks0 = IntAdapters.asIntCollection((Collection<Integer>) sinks);
return (VertexBiPartition<V, E>) computeMinimumCut((IndexGraph) g, w0, sources0, sinks0);

} else {
IndexGraph iGraph = g.indexGraph();
IndexIdMap<V> viMap = g.indexGraphVerticesMap();
IndexIdMap<E> eiMap = g.indexGraphEdgesMap();
IWeightFunction iw = IndexIdMaps.idToIndexWeightFunc(w, eiMap);
IntCollection iSources = IndexIdMaps.idToIndexCollection(sources, viMap);
IntCollection iSinks = IndexIdMaps.idToIndexCollection(sinks, viMap);
IVertexBiPartition indexCut = computeMinimumCut(iGraph, iw, iSources, iSinks);
return VertexBiPartition.partitionFromIndexPartition(g, indexCut);
}
}

abstract IVertexBiPartition computeMinimumCut(IndexGraph g, IWeightFunction w, int sources, int sinks);

abstract IVertexBiPartition computeMinimumCut(IndexGraph g, IWeightFunction w, IntCollection sources,
IntCollection sinks);

}

static IVertexBiPartition computeMinimumCutUsingMaxFlow(IndexGraph g, IWeightFunction w, int source, int sink,
MaximumFlow maxFlowAlg) {
IFlow flow = (IFlow) maxFlowAlg.computeMaximumFlow(g, w, Integer.valueOf(source), Integer.valueOf(sink));
Expand Down Expand Up @@ -171,7 +112,7 @@ private static IVertexBiPartition minCutFromMaxFlow(IndexGraph g, IntCollection
}

static MinimumEdgeCutST buildFromMaxFlow(MaximumFlow maxFlowAlg) {
return new AbstractImplST() {
return new MinimumEdgeCutSTAbstract() {

@Override
public IVertexBiPartition computeMinimumCut(IndexGraph g, IWeightFunction w, int source, int sink) {
Expand Down
52 changes: 5 additions & 47 deletions jgalgo-core/src/main/java/com/jgalgo/alg/flow/MaximumFlows.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@
import java.util.Arrays;
import java.util.Collection;
import com.jgalgo.alg.IVertexBiPartition;
import com.jgalgo.alg.VertexBiPartition;
import com.jgalgo.alg.connect.MinimumEdgeCutST;
import com.jgalgo.alg.connect.MinimumEdgeCutSTAbstract;
import com.jgalgo.graph.EdgeSet;
import com.jgalgo.graph.Graph;
import com.jgalgo.graph.IWeightFunction;
Expand All @@ -40,7 +40,7 @@ class MaximumFlows {

private MaximumFlows() {}

abstract static class AbstractImplBase implements MaximumFlow, MinimumEdgeCutST {
abstract static class AbstractImplBase extends MinimumEdgeCutSTAbstract implements MaximumFlow {

@SuppressWarnings("unchecked")
@Override
Expand Down Expand Up @@ -90,57 +90,15 @@ public <V, E> Flow<V, E> computeMaximumFlow(Graph<V, E> g, WeightFunction<E> cap
abstract IFlow computeMaximumFlow(IndexGraph g, IWeightFunction capacity, IntCollection sources,
IntCollection sinks);

/* TODO: extends MinimumEdgeCutUtils.AbstractImplST once its public API */

@SuppressWarnings("unchecked")
@Override
public <V, E> VertexBiPartition<V, E> computeMinimumCut(Graph<V, E> g, WeightFunction<E> w, V source, V sink) {
if (g instanceof IndexGraph) {
IWeightFunction w0 = WeightFunctions.asIntGraphWeightFunc((WeightFunction<Integer>) w);
int source0 = ((Integer) source).intValue(), sink0 = ((Integer) sink).intValue();
return (VertexBiPartition<V, E>) computeMinimumCut((IndexGraph) g, w0, source0, sink0);

} else {
IndexGraph iGraph = g.indexGraph();
IndexIdMap<V> viMap = g.indexGraphVerticesMap();
IndexIdMap<E> eiMap = g.indexGraphEdgesMap();
IWeightFunction iw = IndexIdMaps.idToIndexWeightFunc(w, eiMap);
int iSource = viMap.idToIndex(source);
int iSink = viMap.idToIndex(sink);
IVertexBiPartition indexCut = computeMinimumCut(iGraph, iw, iSource, iSink);
return VertexBiPartition.partitionFromIndexPartition(g, indexCut);
}
}

@SuppressWarnings("unchecked")
@Override
public <V, E> VertexBiPartition<V, E> computeMinimumCut(Graph<V, E> g, WeightFunction<E> w,
Collection<V> sources, Collection<V> sinks) {
if (g instanceof IndexGraph) {
IWeightFunction w0 = WeightFunctions.asIntGraphWeightFunc((WeightFunction<Integer>) w);
IntCollection sources0 = IntAdapters.asIntCollection((Collection<Integer>) sources);
IntCollection sinks0 = IntAdapters.asIntCollection((Collection<Integer>) sinks);
return (VertexBiPartition<V, E>) computeMinimumCut((IndexGraph) g, w0, sources0, sinks0);

} else {
IndexGraph iGraph = g.indexGraph();
IndexIdMap<V> viMap = g.indexGraphVerticesMap();
IndexIdMap<E> eiMap = g.indexGraphEdgesMap();
IWeightFunction iw = IndexIdMaps.idToIndexWeightFunc(w, eiMap);
IntCollection iSources = IndexIdMaps.idToIndexCollection(sources, viMap);
IntCollection iSinks = IndexIdMaps.idToIndexCollection(sinks, viMap);
IVertexBiPartition indexCut = computeMinimumCut(iGraph, iw, iSources, iSinks);
return VertexBiPartition.partitionFromIndexPartition(g, indexCut);
}
}

IVertexBiPartition computeMinimumCut(IndexGraph g, IWeightFunction w, int source, int sink) {
protected IVertexBiPartition computeMinimumCut(IndexGraph g, IWeightFunction w, int source, int sink) {
return (IVertexBiPartition) MinimumEdgeCutST
.newFromMaximumFlow(this)
.computeMinimumCut(g, w, Integer.valueOf(source), Integer.valueOf(sink));
}

IVertexBiPartition computeMinimumCut(IndexGraph g, IWeightFunction w, IntCollection sources,
@Override
protected IVertexBiPartition computeMinimumCut(IndexGraph g, IWeightFunction w, IntCollection sources,
IntCollection sinks) {
return (IVertexBiPartition) MinimumEdgeCutST
.newFromMaximumFlow(this)
Expand Down

0 comments on commit f66e7cf

Please sign in to comment.