Shortest Path LinkedList - java

I want to find the shortest path on a list of linked list, which represents a directed graph with cost per edge/path.
The output would look something like this, It tells me the cost it would take me to get from vertex 0 to the other vertices:
d[0 to 0] = 0
d[0 to 1] = 20
d[0 to 2] = 10
This is how I populate my list for testing.
LinkedList<GraphData> g = new LinkedList[3];
for (int i = 0; i < 3; i++)
weight[i] = new LinkedList<GraphData>();
g[0].add(new GraphData(1, 20);
g[0].add(new GraphData(2, 10);
The GraphData class looks something like this:
int vertex, int edgeCost;
Now for my problem:
I want to find the shortest path from vertex v to all the others.
public static int[] shortestPaths(int v, LinkedList<GraphData>[] cost)
{
// get the set of vertices
int n = cost.length;
// dist[i] is the distance from v to i
int[] dist = new int[n];
// s[i] is true if there is a path from v to i
boolean[] s = new boolean[n];
// initialize dist
for(int i = 0; i < n; i++)
dist[i] = cost[v].get(i).getCost();
s[v] = true;
// determine n-1 paths from v
for ( int j = 2 ; j < n ; j++ )
{
// choose u such that dist[u] is minimal for all w with s[w] = false
// and dist[u] < INFINITY
int u = -1;
for (int k = 0; k < n; k++)
if ( !s[k] && dist[k] < INFINITY)
// check if u needs updating
if ( u < 0 || dist[k] < dist[u])
u = k;
if (u < 0)
break;
// set s[u] to true and update the distances
s[u]=true;
for (int k = 0; k < n; k++)
if ( !s[k] && cost[u].get(k).getCost() < INFINITY )
if( dist[k] > dist[u] + cost[u].get(k).getCost())
dist[k] = dist[u] + cost[u].get(k).getCost();
// at this point dist[k] is the smallest cost path from
// v to k of length j.
}
return dist;
}
This line dist[i] = cost[v].get(i).getCost(); throws "IndexOutOfBoundsException"
Any idea what I am doing wrong? Any help will be appreciated.

There are two common ways to represent graphs: adjacency lists and adjacency matrices.
Adjacency List: Array of lists. The element at index i is a small list containing the outgoing edges of vertex i. This is what you are creating when you populate the list.
Adjacency Matrix: Array of arrays, with cost[i][j] containing the cost of the edge from vertex i to vertex j. You are using the cost parameter as if it is an adjacency matrix.
You have two options:
Change the graph construction to create an adjacency matrix and use an array of arrays
Change the algorithm to treat cost as an adjacency list instead of an adjacency matrix
Here is the second option. I renamed a few things and simplified the initialization so that the first iteration calculates the distance to the immediate neighbours of v (as opposed to doing it as a special case at the start).
import java.util.*;
public class Main
{
public static int[] shortestPaths(int v, LinkedList<Edge>[] edges)
{
// get the set of vertices
int n = edges.length;
// dist[i] is the distance from v to i
int[] dist = new int[n];
for (int i = 0; i < n; i++) {
dist[i] = Integer.MAX_VALUE;
}
// seen[i] is true if there is a path from v to i
boolean[] seen = new boolean[n];
dist[v] = 0;
// determine n-1 paths from v
for (int j = 0; j < n; j++) {
// choose closest unseen vertex
int u = -1;
for (int k = 0; k < n; k++) {
if (!seen[k]) {
// check if u needs updating
if (u < 0 || dist[k] < dist[u]) {
u = k;
}
}
}
if (u < 0 || dist[u] == Integer.MAX_VALUE) {
break;
}
// at this point dist[u] is the cost of the
// shortest path from v to u
// set seen[u] to true and update the distances
seen[u] = true;
for (Edge e : edges[u]) {
int nbr = e.getTarget();
int altDist = dist[u] + e.getCost();
dist[nbr] = Math.min(dist[nbr], altDist);
}
}
return dist;
}
public static void main(String[] args)
{
int n = 5;
int start = 0;
LinkedList<Edge>[] cost = new LinkedList[n];
for (int i = 0; i < n; i++) {
cost[i] = new LinkedList<Edge>();
}
cost[0].add(new Edge(1, 20));
cost[0].add(new Edge(2, 10));
cost[1].add(new Edge(3, 5));
cost[2].add(new Edge(1, 6));
int[] d = shortestPaths(start, cost);
for (int i = 0; i < n; i++) {
System.out.print("d[" + start + " to " + i + "] = ");
System.out.println(d[i]);
}
}
}
class Edge
{
int target, cost;
public Edge(int target, int cost) {
this.target = target;
this.cost = cost;
}
public int getTarget() {
return target;
}
public int getCost() {
return cost;
}
}

Probably element cost[v].get(i) does not exist (no element with index i in this LinkedList which is cost[v]).
http://docs.oracle.com/javase/6/docs/api/java/util/LinkedList.html#get(int)

The problem is that your indices do not correspond. If you only put one distance, for instance
cost[0].add(new GraphData(5, 20));
then
cost[0].get(5).getCost();
will throw an IndexOutOfBoundsException, because you should do
cost[0].get(0).getCost();
in order to get 20 (which is very confusing).
I would advise using a Map, rather than a List to encode the edge costs.
You populate that Map like
List<Map<Integer, Integer>> g = new ArrayList<>();
for (int i = 0; i < 3; i++)
g.add(new HashMap<Integer, Integer>());
g.get(0).put(1, 20);
g.get(0).put(2, 10);
With this, you could initialize your dist array like
// initialize dist
for(int i = 0; i < n; i++)
dist[i] = cost.get(v).containsKey(i) ? cost.get(v).get(i) : INFINITY;

Related

Maximum items to retain after removing k items from array

I have an array of numbers, I want to delete k items such that they are next to each other such that the number of distinct elements in the array after deletion is maximum.
Example:
Input:
arr = [2,3,1,1,2]
k = 2
Ans: 3
Explanation:
Remove elements at index 3 & 4 which are 1 and 2 in array. Then array becomes [2,3,1] so it has 3 different elements.
This is my code:
int delete(int[] arr, int k) {
int n = arr.length;
int max = -1;
for (int i = 0; i < n - k + 1; i++) {
Set<Integer> set = new HashSet<>();
for (int j = 0; j < n; j++) {
if (i == j) {
j = j + k - 1;
} else {
set.add(arr[j]);
}
}
max = Math.max(set.size(), max);
}
return max;
}
How to reduce the time complexity for this problem. Because the size of array can be upto 1000000 and also the size of k is upto the array size. Each arraycelement can be upto 1000000
Here's a solution in O(N): It uses a map containing the number of occurrences of each number:
You start by filling the map with the elements from k to n-1 (in other words, the array without the first k elements), then you iterate and the first element and remove the last.
static int delete2(int[] arr, int k) {
int n = arr.length;
Map<Integer,Integer> map = new HashMap<>();
for (int i = k; i < n; i++) {
Integer value = arr[i];
if (!map.containsKey(value)) {
map.put(value, 1);
} else {
map.put(value, map.get(value)+1);
}
}
int max = map.size();
for (int i = 0; i < n-k; ++i) {
Integer value = arr[i];
if (!map.containsKey(value)) {
map.put(value, 1);
} else {
map.put(value, map.get(value)+1);
}
value = arr[i+k];
Integer count = map.get(value);
if (count == 1) {
map.remove(value);
} else {
map.put(value, count-1);
}
max = Math.max(map.size(), max);
}
return max;
}
If I understand correctly, you want to delete k adjacent elements such that the resulting set of set of arr - k elements is as large as possible.
Just test each candidate set (there are n sets to try).
So something like this should work
int delete(int[] arr, int k) {
int n = arr.length;
int max = -1;
Set<Integer> rem = new HashSet<>();
for (int i= 0; i<n; i++) {
rem.add(arr[i]);
}
for (int i = 0; i < n - k + 1; i++) {
Set<Integer> candidate = new HashSet<>();
for (int j = i; j < i + k; j++) {
candidate.add(arr[j]);
}
rem.removeAll(candidate);
if (rem.size() > max){
max = rem.size();
} else {
candidate.forEach((e) -> {
rem.add(e);
});
}
}
// you could also return the actual candidate set that produces the maximum
return max;
}
The set operation in the loop are all order k. So resulting time is order n*k.
int delete(int[] arr, int k) {
// step 1: traverse the array exactly once and make a hashtable
// with counts of each unique element
Map<Integer, Integer> elemCounts = new HashMap<>();
for (int e : arr) {
int ct = elemCounts.getOrDefault(e, 0);
elemCounts.put(e, ct + 1);
}
// step 2: traverse through the array exactly once more, and
// keep track of the adjacent elements which produce the least
// disturbance.
// step 2a: for the first k elements, see what removing them would
// do to the overall uniqueness of the array
int numPermanentRemovals = 0;
for (int i = 0; i < k; i++) {
int ct = elemCounts.get(arr[i]);
elemCounts.put(arr[i], ct - 1);
if (ct - 1 == 0) {
numPermanentRemovals += 1;
}
}
// step 2b: for the remainder of the array, track the rolling
// numPermanentRemovals for k adjacent elements
int minDisruption = numPermanentRemovals;
int minDisruptionIndex = 0;
for (int i = k; i < arr.length; i++) {
// put back the element at the start of the current window
int stct = elemCounts.get(arr[i - k]);
elemCounts.put(arr[i - k], stct + 1);
if (stct == 0) {
numPermanentRemovals -= 1;
}
// take out the element being added to the new window
int edct = elemCounts.get(arr[i]);
elemCounts.put(arr[i], edct - 1);
if (edct - 1 == 0) {
numPermanentRemovals += 1;
}
// if this minimum disruption index is a new floor, then
// replace the original
if (numPermanentRemovals < minDisruption) {
minDisruption = numPermanentRemovals;
minDisruptionIndex = i - k + 1;
}
// short-circuit if we find a perfect solution
if (minDisruption == 0) {
break;
}
}
return minDisruptionIndex;
}

Keep original index of 2D Arraylist using comparable class

I have an arraylist of arraylists which stores distances between points. I need to keep the original indexes of the distances after sorting the arraylist, because I need to find the K-nearest neighbours at a later stage of the code. The class I have implemented does not output the correct index of the distances instead an index of the arraylists only is the output
I have tried implementing a 2D comparable class but I was given a few errors.
public staticArrayList<ArrayList<Double>>distance(ArrayList<sample_points> points) {
ArrayList<ArrayList<Double>> distArray = new ArrayList<ArrayList<Double>>(points.size());
double dist = 0;
List<Element> elements = new ArrayList<Element>();
for(int i = 0; i<points.size()-1; i++) {
ArrayList<Double> distances = new ArrayList<Double>();
for(int j=i+1; j<points.size(); j++){
// do your calculations here
dist = Math.sqrt(Math.pow(points.get(i).getX() - points.get(j).getX(), 2)
+ Math.pow(points.get(i).getY() - points.get(j).getY(), 2));
distances.add(dist);// add the distance to the current distances list
}
distArray.add(distances);//
}
System.out.print("Distances: "distArray);
System.out.println();
for(int i = 0; i < distArray.size(); i++) {
for (int j = 0; j < distArray.get(i).size(); j++) {
elements.add(new Element(i, distArray.get(i).get(j)));
}
}
Collections.sort(elements);
for(int i = 0; i < elements.size(); i++) {
System.out.println("Dist "+ elements.get(i).distance + " "
+ "Index " + elements.get(i).index+" ");
}
}
Here is my comparable class:
class Element implements Comparable<Element>{
public final int index;
public final double distance;
public Element(int index, double distance){
this.index = index;
this.distance = distance;
}
#Override
public int compareTo(Element e){
return Double.valueOf(this.distance).compareTo(Double.valueOf(e.distance));
}
}
Expected results:
Distances: [[2.8284271247461903, 5.830951894845301, 7.280109889280518],
[3.1622776601683795, 5.0], [2.23606797749979]]
Dist 2.23606797749979 Index 0
Dist 2.8284271247461903 Index 0
Dist 3.1622776601683795 Index 0
Dist 5.0 Index 1
Dist 5.830951894845301 Index 1
Dist 7.280109889280518 Index 2
Actual results:
Distances: [[2.8284271247461903, 5.830951894845301, 7.280109889280518],
[3.1622776601683795, 5.0], [2.23606797749979]]
Dist 2.23606797749979 Index 2
Dist 2.8284271247461903 Index 0
Dist 3.1622776601683795 Index 1
Dist 5.0 Index 1
Dist 5.830951894845301 Index 0
Dist 7.280109889280518 Index 0
On review of your code, I think that the error is in your assumptions and that the output itself is in fact correct. The index that you're seeing is in fact the index of the outer Lists within your list of list nested array lists that you create here:
for (int i=0; i<points.size()-1; i++) {
ArrayList<Double> distances = new ArrayList<Double>();
for (int j=i+1; j < points.size(); j++) {
// do your calculations here
dist = Math.sqrt(Math.pow(points.get(i).getX() - points.get(j).getX(), 2)
+ Math.pow(points.get(i).getY() - points.get(j).getY(), 2));
distances.add(dist); // add the distance to the current distances list
}
distArray.add(distances); // ***** the index of items added here *****
}
If you add these debugging lines:
for (int i=0; i < points.size()-1; i++) {
ArrayList<Double> distances = new ArrayList<Double>();
for (int j=i+1; j<points.size(); j++) {
// do your calculations here
dist = Math.sqrt(Math.pow(points.get(i).getX() - points.get(j).getX(), 2)
+ Math.pow(points.get(i).getY() - points.get(j).getY(), 2));
distances.add(dist);// add the distance to the current distances list
}
distArray.add(distances); // ***** the index of items added here *****
// ******* add this ********
System.out.println(distArray.indexOf(distances));
System.out.println(distances);
System.out.println();
}
You'll see that this is correct. You need to either change how you create your index values or change your assumptions.
Also, your Element index fields are immutable and are being created before any items in the distance ArrayList are sorted, and so this field cannot represent the sort order of distances.
You state in comment:
If I have a 2D Arraylist of distances i.e [ [d1,d2,d3], [d4,d5], [d6] ]. The indices will be as follows d1=0, d2 =1, d3 = 2, d4 =0, d5 =1 and d6 =0. So I need to get the original indices as mentioned after I sort each arraylist.
Then use j to create the index, not i
for(int i = 0; i < distArray.size(); i++) {
for (int j = 0; j < distArray.get(i).size(); j++) {
// elements.add(new Element(i, distArray.get(i).get(j)));
elements.add(new Element(j, distArray.get(i).get(j))); // ***** note change *****
}
}
Side note: in the future, create a minimal runnable program that demonstrates the problem, that we can compile and run easily. For this question I had to create one myself:
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class Foo01 {
public static void main(String[] args) {
List<SamplePoints> points = new ArrayList<>();
int maxXY = 100;
int max = 4;
for (int i = 0; i < max; i++) {
int x = (int) (maxXY * Math.random());
int y = (int) (maxXY * Math.random());
points.add(new SamplePoints(x, y));
}
distance(points);
}
private static class SamplePoints {
private int x;
private int y;
public SamplePoints(int x, int y) {
this.x = x;
this.y = y;
}
public int getX() {
return x;
}
public int getY() {
return y;
}
}
private static class Element implements Comparable<Element> {
public final int index;
public final double distance;
public Element(int index, double distance) {
this.index = index;
this.distance = distance;
}
#Override
public int compareTo(Element e) {
return Double.valueOf(this.distance).compareTo(Double.valueOf(e.distance));
}
}
public static void distance(List<SamplePoints> points) {
ArrayList<ArrayList<Double>> distArray = new ArrayList<ArrayList<Double>>(points.size());
double dist = 0;
List<Element> elements = new ArrayList<Element>();
for (int i = 0; i < points.size() - 1; i++) {
ArrayList<Double> distances = new ArrayList<Double>();
for (int j = i + 1; j < points.size(); j++) {
// do your calculations here
dist = Math.sqrt(Math.pow(points.get(i).getX() - points.get(j).getX(), 2)
+ Math.pow(points.get(i).getY() - points.get(j).getY(), 2));
distances.add(dist);// add the distance to the current distances
// list
}
distArray.add(distances);//
System.out.println(distArray.indexOf(distances));
System.out.println(distances);
System.out.println();
}
System.out.print("Distances: " + distArray);
System.out.println();
for (int i = 0; i < distArray.size(); i++) {
for (int j = 0; j < distArray.get(i).size(); j++) {
elements.add(new Element(i, distArray.get(i).get(j)));
}
}
Collections.sort(elements);
for (int i = 0; i < elements.size(); i++) {
System.out.println("Dist " + elements.get(i).distance + " " + "Index "
+ elements.get(i).index + " ");
}
}
}
But in the future, you'll want to do this to help make your question easier to answer.

Saving the shortest paths in a graph using the Floyd Warshall algorithm in java

I am trying to write a Betweeness Centrality method for a undirected, unweighted (weight = 1) Graph in Java. The way I have gone about it is by finding all of the shortest paths in the graph, and then iterating through those paths and counting how often a vertex is a step in that path. I have used the Floyd Warshall algorithm to find the shortest paths, and used another array to reconstruct the paths, similar to the pseudo code on the Wikipedia.
However, my results are not correct, and I have tried figuring out where the problem lies but I can't. I will just post the whole code in here for completeness sake, however it is messy so I apologize. I will comment the bits where I think the problems would occur.
public void calculateBetweenessCentrality() {
// Floyd warshall algorithm, storing paths with R
int noPath = Integer.MAX_VALUE / 4;
int[][] adjMatrix = getAdjacencyMatrix();
int distances[][] = new int[numVertices][numVertices];
int[][] R = new int[numVertices][numVertices];
// Initialize the arrays, setting "-5000" as null instead. Possible error here?
for (int i = 0; i < numVertices; i++) {
for (int j = 0; j < numVertices; j++) {
if (adjMatrix[i][j] == 0) {
distances[i][j] = noPath;
R[i][j] = -5000; // null
}
else {
distances[i][j] = adjMatrix[i][j];
R[i][j] = j;
}
}
}
// Do the algorithm, and save in R, possible error here?
for (int k = 0; k < numVertices; k++) {
for (int i = 0; i < numVertices; i++) {
for (int j = 0; j < numVertices; j++) {
if (distances[i][j] > distances[i][k] + distances[k][j]) {
distances[i][j] = distances[i][k] + distances[k][j];
R[i][j] = R[i][k];
}
}
}
}
// Go through R and construct the shortest paths, record the frequency for each node (indexs). Possible error here?
HashMap<Integer, Integer> frequencies = new HashMap<>(); // Key = index, Value = frequency
for (int i = 0; i < numVertices; i++) {
for (int j = 0; j < numVertices; j++) {
ArrayList<Integer> path = findShortestPath(R, i, j);
for (int p : path) {
int freq = frequencies.containsKey(p) ? frequencies.get(p) : 0;
frequencies.put(p, freq + 1);
}
}
}
HashMap<Integer, Integer> temp = new HashMap<Integer, Integer>(); // Instead of printing the vertex's adjacency matrix index value, get the actual value for displaying purposes.
for (Entry<Integer, Integer> freq : frequencies.entrySet()) {
temp.put(verticesIndexValue.get(freq.getKey()), freq.getValue());
}
System.out.println("Top 5 nodes: \nNode - Count");
frequencies.entrySet().stream().sorted(Map.Entry.comparingByValue(Collections.reverseOrder())).limit(5)
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (e1, e2) -> e1, LinkedHashMap::new))
.forEach((node, frequency) -> System.out.println(node + " - " + frequency));
}
private ArrayList<Integer> findShortestPath(int[][] R, int u, int v) {
ArrayList<Integer> paths = new ArrayList<>();
if(R[u][v] == -5000)
return paths;
paths.add(u);
while(u != v) {
u = R[u][v];
paths.add(u);
}
return paths;
}
The graph that I am testing this on is from this input here, where each line is an edge. The graph in that pastebin creates two connected components. The output I get for the first component is as follows:
Top 5 nodes:
Node - Count
11336782 - 11393
50393960 - 9047
627363 - 4079
849131 - 3799
5676102 - 3351
The answer is actually that 50393960 is the top node. If anybody could please guide me to where I am going wrong, I'd appreciate it massively. Thanks =)
Your code contains mistake in the place where it calculates frequencies - according to definition of Betweenness centrality when calculating it for particular vertex V you should exclude shortest paths which start or end with vertex V. Basically it means that when iterating over shortest paths you shoud not add start and end vertexes to frequencies. Try this instead:
HashMap<Integer, Integer> frequencies = new HashMap<>(); // Key = index, Value = frequency
for (int i = 0; i < numVertices; i++) {
for (int j = 0; j < numVertices; j++) {
ArrayList<Integer> path = findShortestPath(R, i, j);
for (int p : path) {
if (p == i || p == j) {
continue;
}
int freq = frequencies.containsKey(p) ? frequencies.get(p) : 0;
frequencies.put(p, freq + 1);
}
}
}

How do i find the shortest distance of specified points between multiple points?

I've input the points and found distances between them. Now I want to find which distance of m points is shortest.
import java.awt.Point;
import java.io.*;
import java.util.*;
import java.text.*;
import java.math.*;
public class Solution
{
public static void main(String[] args)
{
Scanner in = new Scanner(System.in);
int n = in.nextInt();
int m = in.nextInt();
int k = in.nextInt();
Point[] coordinates=new Point[10];
double dist;
for(int i = 0; i < m; i++)
{
coordinates[i]=new Point(in.nextInt(),in.nextInt());
}
for(int i=0;i<m-1;i++)
{
dist=Math.sqrt(((coordinates[i+1].getX()-coordinates[i].getX())*(coordinates[i+1].getX()-coordinates[i].getX()))+((coordinates[i+1].getY()-coordinates[i].getY())*(coordinates[1].getY()-coordinates[0].getY())));
System.out.println("dist between "+coordinates[i+1].getX()+","+coordinates[i+1].getY()+"and "+coordinates[i].getX()+","+coordinates[i].getY() +" is "+dist);
}
in.close();
}
}
The way your for loop is designed, it is only checking one point with the point that was read just after it. You need 2 for loops to compare each of the points with all the others
for(int i = 0; i < m - 1; i++)
{
for (int j = 0; j < m; j++)
{
// compare point i with point j and store the smallest here
// you probably want to discard points where i == j
}
}
You have to make a for-loop inside another one to go through all points per point. The first for-loop will go through every point. The second loop will also go through all points, so inside the second loop, you will have any possible combination of two loops. Then you need to calculate the distance and check if the distance calculated is smaller than the smallest distance calculated before.
In the end you'll have the smallest distance:
0.0f for points[] being size 0 or 1
smallest distance for points[] being size 2 or greater
Here's some example code:
float smallesDistance = 0.0f;
Point[] points = ...;
for(int i = 0; i < points.length; i++) {
for (int j = 0; j < points.length; j++) {
if(i != j) { //cant compare on point with itself
Point a = points[i];
Point b = points[j];
float distance = ...; //calculate distance with pythagorean theorem
if(distance < smallesDistance)
smallesDistance = distance;
}
}
}
If you need the greatest distance, just replace if(distance < smallesDistance) by if(distance > smallesDistance).
Here are the helper functions:
distance: calculate the distance between two points
shortest_pair: return the pair with the shortest distance
Codes are as follows:
import java.awt.Point;
double distance(Point p1, Point p2)
{
return Math.sqrt((p1.x - p2.x)*(p1.x - p2.x) + (p1.y - p2.y)*(p1.y - p2.y));
}
int[] shortest_pair(Point[] coordinates)
{
int m = coordinates.length;
double shortest_distance = Double.MAX_VALUE;
int[] shortest_pair = new int[2];
for (int i = 0; i < m-1; i++)
{
for (int j = i+1; j < m; j++)
{
double d = distance(coordinates[i], coordinates[j]);
if (d < shortest_distance)
{
shortest_distance = d;
shortest_pair[0] = i;
shortest_pair[1] = j;
}
}
}
return shortest_pair;
}
Example is as follows:
Random rand = new Random();
rand.setSeed(0);
int m = coordinates.length;
assert m == 10;
for(int i = 0; i < m; i++)
coordinates[i] = new Point(rand.nextInt(10), rand.nextInt(10));
assert Arrays.equals(shortest_pair(coordinates), new int[] { 2, 7 });

Dijkstra's Algorithm Assistance

Given an adjacency matrix, I need to compute the shortest path between the first vertex and the last vertex (generally, vertex i and j, but we can ignore that for the time being). I've written an algorithm that really only correctly computes the distance between the first and second node (a step in the right direction, I guess).
static int dijkstra(int[][] G, int i, int j) {
//Get the number of vertices in G
int n = G.length;
int[] bestpath = new int[n];
int max = Integer.MAX_VALUE;
boolean[] visited = new boolean[n];
for (int x = 0; x < n; x++) {
visited[x] = false;
bestpath[x] = max;
}
bestpath[i] = 0;
for (int x = 0; x < n; x++) {
int min = max;
int currentNode = i;
for (int y = 0; y < n; y++) {
if (!visited[y] && bestpath[y] < min) {
System.out.println(G[y][x]);
currentNode = y;
min = bestpath[y];
}
}
visited[currentNode] = true;
for (int y = 0; y < n; y++) {
if (G[currentNode][y] < max && bestpath[currentNode] + G[currentNode][y] < bestpath[y]) {
bestpath[y] = bestpath[currentNode] + G[currentNode][y];
}
}
}
return bestpath[j];
}
If I were to guess, I'd say my logic is flawed in this section:
for (int y = 0; y < n; y++) {
if (!visited[y] && bestpath[y] < min) {
System.out.println(G[y][x]);
currentNode = y;
min = bestpath[y];
}
}
An example would be the matrix
0 1 0
1 0 1
0 1 0
which would return 2 (one path between vertex one and two of weight 1 and another between 2 and 3 with weight 1).
If the matrix is not just storing 1s and 0s, but the distance from i to j, then you really need to keep track of the best distance from any node i to j. In other words, your working array should be a working matrix instead. Even if you are just doing a non - weighted graph, I think this approach is better.
There are different versions of the SPF algorithm. Post pseudocode for what you are trying to translate into java.

Categories

Resources