com.salesforce.jgrapht.alg.spanning.PrimMinimumSpanningTree Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of AptSpringProcessor Show documentation
Show all versions of AptSpringProcessor Show documentation
This project contains the apt processor that implements all the checks enumerated in @Verify. It is a self contained, and
shaded jar.
The newest version!
/*
* (C) Copyright 2013-2018, by Alexandru Valeanu and Contributors.
*
* JGraphT : a free Java graph-theory library
*
* See the CONTRIBUTORS.md file distributed with this work for additional
* information regarding copyright ownership.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0, or the
* GNU Lesser General Public License v2.1 or later
* which is available at
* http://www.gnu.org/licenses/old-licenses/lgpl-2.1-standalone.html.
*
* SPDX-License-Identifier: EPL-2.0 OR LGPL-2.1-or-later
*/
package com.salesforce.jgrapht.alg.spanning;
import com.salesforce.jgrapht.*;
import com.salesforce.jgrapht.alg.interfaces.*;
import com.salesforce.jgrapht.util.*;
import java.lang.reflect.*;
import java.util.*;
/**
* An implementation of Prim's
* algorithm that finds a minimum spanning tree/forest subject to connectivity of the supplied
* weighted undirected graph. The algorithm was developed by Czech mathematician V. Jarník and later
* independently by computer scientist Robert C. Prim and rediscovered by E. Dijkstra.
*
* This implementation relies on a Fibonacci heap, and runs in $O(|E| + |V|log(|V|))$.
*
*
* @param the graph vertex type
* @param the graph edge type
*
* @author Alexandru Valeanu
* @author Alexey Kudinkin
*/
public class PrimMinimumSpanningTree
implements
SpanningTreeAlgorithm
{
private final Graph g;
/**
* Construct a new instance of the algorithm.
*
* @param graph the input graph
*/
public PrimMinimumSpanningTree(Graph graph)
{
this.g = Objects.requireNonNull(graph, "Graph cannot be null");
}
/**
* {@inheritDoc}
*/
@Override
@SuppressWarnings("unchecked")
public SpanningTree getSpanningTree()
{
Set minimumSpanningTreeEdgeSet = new HashSet<>(g.vertexSet().size());
double spanningTreeWeight = 0d;
final int N = g.vertexSet().size();
/*
* Normalize the graph by mapping each vertex to an integer.
*/
VertexToIntegerMapping vertexToIntegerMapping = Graphs.getVertexToIntegerMapping(g);
Map vertexMap = vertexToIntegerMapping.getVertexMap();
List indexList = vertexToIntegerMapping.getIndexList();
VertexInfo[] vertices = (VertexInfo[]) Array.newInstance(VertexInfo.class, N);
FibonacciHeapNode[] fibNodes =
(FibonacciHeapNode[]) Array.newInstance(FibonacciHeapNode.class, N);
FibonacciHeap fibonacciHeap = new FibonacciHeap<>();
for (int i = 0; i < N; i++) {
vertices[i] = new VertexInfo();
vertices[i].id = i;
vertices[i].distance = Double.MAX_VALUE;
fibNodes[i] = new FibonacciHeapNode<>(vertices[i]);
fibonacciHeap.insert(fibNodes[i], vertices[i].distance);
}
while (!fibonacciHeap.isEmpty()) {
FibonacciHeapNode fibNode = fibonacciHeap.removeMin();
VertexInfo vertexInfo = fibNode.getData();
V p = indexList.get(vertexInfo.id);
vertexInfo.spanned = true;
// Add the edge from its parent to the spanning tree (if it exists)
if (vertexInfo.edgeFromParent != null) {
minimumSpanningTreeEdgeSet.add(vertexInfo.edgeFromParent);
spanningTreeWeight += g.getEdgeWeight(vertexInfo.edgeFromParent);
}
// update all (unspanned) neighbors of p
for (E e : g.edgesOf(p)) {
V q = Graphs.getOppositeVertex(g, e, p);
int id = vertexMap.get(q);
// if the vertex is not explored and we found a better edge, then update the info
if (!vertices[id].spanned) {
double cost = g.getEdgeWeight(e);
if (cost < vertices[id].distance) {
vertices[id].distance = cost;
vertices[id].edgeFromParent = e;
fibonacciHeap.decreaseKey(fibNodes[id], cost);
}
}
}
}
return new SpanningTreeImpl<>(minimumSpanningTreeEdgeSet, spanningTreeWeight);
}
private class VertexInfo
{
public int id;
public boolean spanned;
public double distance;
public E edgeFromParent;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy