Directed Graph Shortest path source to destination Dijkstra - java

Here is my code to get the shortest path
static void shortestPath(int[][] adjacencyMatrix, int src, int dest) {
int n = adjacencyMatrix[0].length;
int[] shortest = new int[n];
boolean[] added = new boolean[n];
for (int v = 0; v < n;v++) {
shortest[v] = Integer.MAX_VALUE;
added[v] = false;
}
shortest[src] = 0;
int[] parents = new int[n];
parents[src] = NO_PARENT;
for (int i = 1; i < n; i++) {
int v1 = -1; //store temp data
int min = Integer.MAX_VALUE;
for (int v = 0; v < n; v++) {
if (!added[v] && shortest[v] < min) {
v1 = v;
min = shortest[v];
}
}
added[v1] = true; // ERROR HAPPENS HERE
for (int v = 0; v < n; v++) {
int dist = adjacencyMatrix[v1][v];
if (dist > 0 && ((min + dist) <shortest[v])){
parents[v] = v1;
shortest[v] = min + dist;
}
}
}
dists.add(shortest[dest]);
visitUtil(dest, parents);
}
static void visitUtil(int i,int[] parents) {
if (i == NO_PARENT)
return;
visitUtil(parents[i], parents);
edges.add(i);
}
My matrix is this
{ 0,10, 0, 0, 3 },
{0, 0, 5, 0, 1 },
{ 0, 0, 0, 7, 8 },
{ 0, 0, 0, 0, 2 },
{ 0, 0, 0, 0, 0 }
Here is my graph so you can see it.
I get a ArrayIndexOutOfBoundsException. For example, lets say I want to go from 2-4, in the graph below, you can see that the weight is 8, and they are directly attached.
How can I fix this?

Related

Number of Circuits in Directed graph

There are various questions on how to find the number of cycles/circuits in a directed graph.I have mostly visited them, and i did come out with a code which does it.
I am struck at a point where my code doesn't give a cycle/circuit below of length 3.
Code:
public class CyclesInGraph {
// Graph modeled as list of edges
static int[][] graph =
{
{1, 2}, {2, 3}, {3, 4}, {4, 3},
{3, 1}
};
static List<int[]> cycles = new ArrayList<int[]>();
/**
* #param args
*/
public static void main(String[] args) {
for (int i = 0; i < graph.length; i++)
for (int j = 0; j < graph[i].length; j++)
{
findNewCycles(new int[] {graph[i][j]});
}
for (int[] cy : cycles)
{
String s = "" + cy[0];
for (int i = 1; i < cy.length; i++)
{
s += "," + cy[i];
}
o(s);
}
}
static void findNewCycles(int[] path)
{
int n = path[0];
int x;
int[] sub = new int[path.length + 1];
for (int i = 0; i < graph.length; i++)
for (int y = 0; y <= 1; y++)
if (graph[i][y] == n)
// edge refers to our current node
{
x = graph[i][(y + 1) % 2];
if (!visited(x, path))
// neighbor node not on path yet
{
sub[0] = x;
System.arraycopy(path, 0, sub, 1, path.length);
// explore extended path
findNewCycles(sub);
}
else if ((path.length > 2) && (x == path[path.length - 1]))
// cycle found
{
int[] p = normalize(path);
int[] inv = invert(p);
if (isNew(p) && isNew(inv))
{
cycles.add(p);
}
}
}
}
// check of both arrays have same lengths and contents
static Boolean equals(int[] a, int[] b)
{
Boolean ret = (a[0] == b[0]) && (a.length == b.length);
for (int i = 1; ret && (i < a.length); i++)
{
if (a[i] != b[i])
{
ret = false;
}
}
return ret;
}
// create a path array with reversed order
static int[] invert(int[] path)
{
int[] p = new int[path.length];
for (int i = 0; i < path.length; i++)
{
p[i] = path[path.length - 1 - i];
}
return normalize(p);
}
// rotate cycle path such that it begins with the smallest node
static int[] normalize(int[] path)
{
int[] p = new int[path.length];
int x = smallest(path);
int n;
System.arraycopy(path, 0, p, 0, path.length);
while (p[0] != x)
{
n = p[0];
System.arraycopy(p, 1, p, 0, p.length - 1);
p[p.length - 1] = n;
}
return p;
}
// compare path against known cycles
// return true, iff path is not a known cycle
static Boolean isNew(int[] path)
{
Boolean ret = true;
for(int[] p : cycles)
{
if (equals(p, path))
{
ret = false;
break;
}
}
return ret;
}
static void o(String s)
{
System.out.println(s);
}
// return the int of the array which is the smallest
static int smallest(int[] path)
{
int min = path[0];
for (int p : path)
{
if (p < min)
{
min = p;
}
}
return min;
}
// check if vertex n is contained in path
static Boolean visited(int n, int[] path)
{
Boolean ret = false;
for (int p : path)
{
if (p == n)
{
ret = true;
break;
}
}
return ret;
}
}
Output that I am getting:
1,3,2
But i should get 3,4 also as 3-4-3 also make a cycle in graph.

Changing Scanner type to arrays of number

I have the following codes and instead of typing the numbers using scanner function. I want to use an array instead . How do I do this? I need help. Thanks in advance
public class salomon {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int n = in.nextInt();
int[] a = new int[n];
int[] minHeap = new int[n];
int[] maxHeap = new int[n];
int minHeapSize = 0;
int maxHeapSize = 0;
float currentMedian = 0;
for (int a_i = 0; a_i < n; a_i++) {
a[a_i] = in.nextInt();
if (a[a_i] < currentMedian) {
maxHeap[maxHeapSize++] = a[a_i];
// making sure the max heap has maximum value at the top
if (maxHeap[maxHeapSize - 1] > maxHeap[0]) {
swap(maxHeap, maxHeapSize - 1, 0);
}
} else {
minHeap[minHeapSize++] = a[a_i];
// making sure the min heap has minimum value at the top
if (minHeap[minHeapSize - 1] < minHeap[0]) {
swap(minHeap, minHeapSize - 1, 0);
}
}
// if the difference is more than one
if (Math.abs(maxHeapSize - minHeapSize) > 1) {
if (maxHeapSize > minHeapSize) {
swap(maxHeap, maxHeapSize - 1, 0);
minHeap[minHeapSize++] = maxHeap[--maxHeapSize];
swap(minHeap, 0, minHeapSize - 1);
buildMaxHeap(maxHeap, maxHeapSize);
} else {
swap(minHeap, minHeapSize - 1, 0);
maxHeap[maxHeapSize++] = minHeap[--minHeapSize];
swap(maxHeap, 0, maxHeapSize - 1);
buildMinHeap(minHeap, minHeapSize);
}
}
// calculate the median
if (maxHeapSize == minHeapSize) {
currentMedian = (minHeap[0] + maxHeap[0]);
currentMedian = currentMedian / 2;
} else if (maxHeapSize > minHeapSize) {
currentMedian = maxHeap[0];
} else {
currentMedian = minHeap[0];
}
System.out.println(currentMedian);
}
}
static void buildMaxHeap(int[] input, int heapSize) {
int depth = (heapSize - 1) / 2;
for (int i = depth; i >= 0; i--) {
maxHeapify(input, i, heapSize);
}
}
static void maxHeapify(int[] input, int i, int heapSize) {
int left = 2 * i + 1;
int right = 2 * i + 2;
// find the largest
int largest = i;
if (left < heapSize && input[left] > input[largest]) {
largest = left;
}
if (right < heapSize && input[right] > input[largest]) {
largest = right;
}
if (largest != i) {
//swap
swap(input, i, largest);
//recursive call
maxHeapify(input, largest, heapSize);
}
}
static void buildMinHeap(int[] input, int heapSize) {
int depth = (heapSize - 1) / 2;
for (int i = depth; i >= 0; i--) {
minHeapify(input, i, heapSize);
}
}
static void minHeapify(int[] input, int i, int heapSize) {
int left = 2 * i + 1;
int right = 2 * i + 2;
// find the smallest
int smallest = i;
if (left < heapSize && input[left] < input[smallest]) {
smallest = left;
}
if (right < heapSize && input[right] < input[smallest]) {
smallest = right;
}
if (smallest != i) {
//swap
swap(input, i, smallest);
//recursive call
minHeapify(input, smallest, heapSize);
}
}
static void swap(int[] input, int i, int j) {
if (i == j)
return;
int temp = input[i];
input[i] = input[j];
input[j] = temp;
}
}
When I typed 6, 12, 4, 5, 3, 8, 7 and enter - I get the Moving median
12.0
8.0
5.0
4.5
5.0
6.0
I want to replace the scanner with an array {6, 12, 4, 5, 3, 8, 7}`
instead and how do I adjust the code. Thanks
The first value 6 is the array length. Assuming you intend for that to remain, you would remove everything that "isn't an elephant" (namely all of the median calculations), and rename int[] a to int[] f. Like,
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int n = in.nextInt();
int[] f = new int[n];
for (int i = 0; i < n; i++) {
f[i] = in.nextInt();
}
System.out.println(Arrays.toString(f));
}
When executed with your example input, this outputs
[12, 4, 5, 3, 8, 7]
If you really did want the six as well, then you would need to add it. Like,
int[] f = new int[n + 1];
f[0] = n;
for (int i = 1; i <= n; i++) {
f[i] = in.nextInt();
}
System.out.println(Arrays.toString(f));
which outputs (as requested)
[6, 12, 4, 5, 3, 8, 7]

Shortest path for the knight (BFS)

Please help me understand what I am doing wrong with my code. I am trying to get the shortest path using BFS to solve the problem but it's either giving me -1 or 2. It should give me 6 as the answer. What am I doing wrong? This is the problem:
Given a chess board, find the shortest distance(minimum number of steps) taken by a knight to reach given destination from given source.
For example, N = 8 (8 x 8 board), Source = (7, 0) Destination = (0, 7)
Minimum number of steps required is 6
My code is below:
class Point {
int x, y;
public Point(int x, int y){
this.x = x;
this.y = y;
}
}
class knightShortestPath {
int N = 8;
public static boolean visited[][];
public boolean isPositionValid(int x, int y){
if( x < 0 || y < 0 || x > this.N || y > this.N){
return false;
}
return true;
}
public void createChessBoard(int N) {
this.N = N;
visited = new boolean[this.N][this.N];
for (int i = 0; i < this.N; i++) {
for (int j = 0; j < this.N; j++) {
visited[i][j] = false;
}
}
}
public int BFS(Point source, Point destination) {
int row[] = {2, 2, -2, -2, 1, 1, -1, -1};
int col[] = {1, -1, 1, -1, 2, -2, 2, -2};
Queue<Point> queue = new LinkedList<>();
queue.offer(source);
visited[source.x][source.y] = true;
int minimumNumSteps = 0;
while (!queue.isEmpty()) {
int size = queue.size();
for (int i = 0; i < size; i++) {
Point pt = queue.poll();
if (pt.x == destination.x && pt.y == destination.y) {
return minimumNumSteps;
}
for (int j = 0; j < size; j++) {
Point next = new Point(pt.x + row[i], pt.y + col[j]);
if (isPositionValid(pt.x + row[i], pt.y + col[j]) && !visited[i][j]) {
visited[i][j] = true;
queue.offer(next);
}
}
}
minimumNumSteps++;
}
return minimumNumSteps;
}
public static void main(String[] args) {
knightShortestPath position = new knightShortestPath();
position.createChessBoard(8);
Point src = new Point(0,7);
Point dest = new Point(7,0);
System.out.println("The minimum number of steps are: " + position.BFS(src, dest)); //answer is 6
}
}
First thing: I have no idea how you can end up with a negative value. You never decrease minimumNumSteps after initializing it with 0. An overflow possibly? Seems weird to me ..
Besides that, I see two issues:
The two for loops are incorrect. You currently iterate over the queue.size(). What you want to do instead is iterating over all children of the current node.
Poll the current point outside of the for loops.
So:
while(!queue.isEmpty()) {
Point pt = queue.poll();
// check if it's target
// ...
for (int i = 0; i < row.length; i++) {
// ...
for (int j = 0; j < col.length; j++) {
// ...
}
}
}
Another note: When the queue is empty and you have not reached the goal, there is no solution. Currently, you are returning some value that may be interpreted falsely.

java.lang.IllegalArgumentException

I have the implementation of Branch and Bound I'am getting error in this function there is priority queue which will used further its getting IllegalArgumentException
//here is that line on which I'am getting this error
PriorityQueue<Node> pq = new PriorityQueue<>(0, comp);
import java.util.Comparator;
import java.util.PriorityQueue;
public class Node {
private int N = 3;
Node parent;
int[][] mat = new int[N][N];
int x, y;
int cost;
int level;
public void printMatrix(int[][] mat) {
for (int i = 0; i < mat.length; i++) {
for (int j = 0; j < mat[i].length; j++) {
System.out.print(mat[i][j]);
}
System.out.println();
}
}
public void newNode(int[][] mat, int x, int y, int newX, int newY, int level, Node parent) {
Node node = new Node();
node.parent = parent;
node.mat = mat;
node.mat[x][y] = node.mat[newX][newY];
node.cost = Integer.MAX_VALUE;
node.level = level;
node.x = newX;
node.y = newY;
}
int[] row = {1, 0, -1, 0};
int[] col = {0, -1, 0, 1};
public int calculateCost(int[][] initial, int[][] fin) {
int count = 0;
for (int i = 0; i < fin.length; i++) {
for (int j = 0; j < fin.length; j++) {
if(initial[i][j] != fin[i][j])
count++;
}
}
return count;
}
public int isSafe(int x, int y) {
if ((x >= 0 && x < N) && (y >= 0 && y < N))
return 1;
return 0;
}
public void printPath(Node root) {
if(root == null)
return;
printPath(root.parent);
printMatrix(root.mat);
System.out.println();
}
**// here I'am getting error in this function there is priority queue which will used further its getting IllegalArgumentException **
public void solve(int[][] initial, int x, int y, int[][] fin) {
Comparator<Node> comp = new Comparator<Node>() {
#Override
public int compare(Node lhs, Node rhs) {
if((lhs.cost + lhs.level) > (rhs.cost + rhs.level))
return 1;
return 0;
}
};
//here is that line on which im getting this error
PriorityQueue<Node> pq = new PriorityQueue<>(0, comp);
Node root = new Node();
root.newNode(initial, x, y, x, y, 0, null);
root.cost = calculateCost(initial, fin);
pq.add(root);
while(!pq.isEmpty()) {
Node min = pq.peek();
pq.remove();
if(min.cost == 0) {
printPath(min);
return;
}
for (int i = 0; i < 4; i++) {
if(isSafe(min.x + row[i], min.y + col[i]) == 1) {
Node child = new Node();
child.newNode(min.mat, min.x, min.y, min.x + row[i], min.y + col[i], min.level + 1, min);
child.cost = calculateCost(child.mat, fin);
pq.add(child);
}
}
}
}
public static void main(String[] args) {
int[][] initial =
{
{1, 2, 3},
{5, 6, 0},
{7, 8, 4}
};
int[][] fin =
{
{1, 2, 3},
{5, 0, 6},
{8, 7, 4}
};
int x = 1, y = 2;
Node newNode = new Node();
newNode.solve(initial, x, y, fin);
}
}
From the javadoc (emphasis is mine):
public PriorityQueue(int initialCapacity, Comparator<? super E> comparator)
Creates a PriorityQueue with the specified initial capacity that orders its elements according to the specified comparator.
[...]
Throws:
IllegalArgumentException - if initialCapacity is less than 1

Breadth First Traversal using adj Matrix

I'm writing breadth first, depth first, and depth first recursive traversal for the following graph:
From what I understand, the traversal should be 0 1 3 6 4 5 2...but i'm only getting that for the depth first traversal, and for the dfs(recursive) and BFS, I'm getting 0 1 3 6 2 4 5. I don't know which one is right and what I need to do to fix the problem.
Class
public void depthFirst(int vFirst,int n, int[] isvisited)
{ //vFirst = 0, n = 6
int v,i;
// st is a stack
st.push(vFirst);
while(!st.isEmpty())
{
v = st.pop();
if(isvisited[v]==0)
{
System.out.print(v);
isvisited[v]=1;
}
for ( i = 0; i <= n; i++)
{
if((adjMatrix[v][i] == 1) && (isvisited[i] == 0))
{
st.push(v);
isvisited[i]=1;
System.out.print(" " + i);
v = i;
}
}
}
}
public void depthFirstRecursive(int w) {
int j; //w = 0;
visited[w] = 1;
if (w == 0) {
System.out.print(w + " ");
}
for (j = 0; j <= 6; j++) {
if ((adjMatrix[w][j] == 1) && (visited[j] == 0)) {
System.out.print(j + " ");
depthFirstRecursive(j);
}
}
}
public void breadthFirst(int first, int p) {
int e; // first = 0; p = 6
int[] nodeVisited = new int[7];
que.add(first);
while (!que.isEmpty()) {
e = que.remove();
if(nodeVisited[e]==0)
{
System.out.print(e);
nodeVisited[e]=1;
}
for (int i = 0; i <= p; i++)
{
if((adjMatrix[e][i] == 1) && (nodeVisited[i] == 0))
{
que.add(e);
nodeVisited[i]=1;
System.out.print(" " + i);
e = i;
}
}
}
}
public static void main(String[] args) {
// 1 2 3 4 5 6 7
int[][] adjMatrix = { {0, 1, 1, 0, 0, 0, 0},
{1, 0, 0, 1, 1, 1, 0},
{1, 0, 0, 0, 0, 0, 1},
{0, 1, 0, 0, 0, 0, 1},
{0, 1, 0, 0, 0, 0, 1},
{0, 1, 0, 0, 0, 0 ,0},
{0, 0, 1, 1, 1, 0, 0} };
new myGraphs(adjMatrix);
}
About following snippet in BFS:
que.add(e);
nodeVisited[i]=1;
System.out.print(" " + i);
e = i;
They why do you change e and add e to queue? It seems incorrect to me.
Non Recursive BFS using Queue:
public int[] breadthFirstSearch(int[][] adjacencyMatrix, int start) {
int totalNumberOfvertices = adjacencyMatrix.length;
boolean[] visited = new boolean[totalNumberOfvertices];
Queue<Integer> queue = new LinkedList<>();
queue.add(start);
visited[start] = true;
List<Integer> list = new ArrayList<>();
while (!queue.isEmpty()) {
list.add(queue.peek());
int currentFirstElementInQueue = queue.poll();
for (int i = 0; i < adjacencyMatrix.length; i++) {
if ((adjacencyMatrix[currentFirstElementInQueue][i] == 1) && (!visited[i])) {
queue.add(i);
visited[i] = true;
}
}
}
int[] result = new int[list.size()];
int i = 0;
Iterator<Integer> itr = list.iterator();
while (itr.hasNext()) {
result[i++] = itr.next();
}
return result;
}
public void BFS(int start)
{
int v=a.length;//a[][] is adj matrix declared globally
boolean visited[]=new boolean[v];//indexing done from 1 to n
LinkedList<Integer> queue=new LinkedList<Integer>();
visited[start]=true;
queue.add(start);
while(queue.size()!=0)
{
int x=queue.remove();
System.out.print(x+" ");
for (int i=1; i < v; i++)
if((a[x][i] == 1) && (!visited[i]))
{
queue.add(i);
visited[i]=true;
}
}
}

Categories