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
Related
I have an assignment to implementthe matrix class and a method that checks if the matrix is symmetric.
The method has to be recursive and then I have to calculate its complexity. After I have to transform the recursive function to its iterative version.
For now this is how my matrix class looks like:
public class Matrix<T> {
private int m, n;
private T[][] data;
public Matrix(int m, int n) {
this.m = m;
this.n = n;
}
public Matrix(T[][] data) {
this.data = data;
}
public boolean isSymmetric() {
if (m != n) {
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
if (data[i][j] != data[j][i]) {
return false;
}
}
}
return true;
}
return false;
}
public boolean isSymmetric(int i, int j) {
if (i < 0 && j < 0) return true;
else {
return isSymmetric(i - 1, j - 1);
}
}
public T get(int i, int j) {
return data[i][j];
}
public void set(int i, int j, T value) {
data[i][j] = value;
}
public int[] getSize() {
return new int[]{m, n};
}
#Override
public String toString() {
String rep = "";
for (int i = 0; i < m; i++) {
rep += "( ";
for (int j = 0; j < n; j++) {
rep += data[i][j].toString() + "\t";
}
rep += ")\n";
}
return rep;
}
}
I have a iterative version of the isSymmetric() function, but I cannot get the recursive one.
You can start check from maximum row and col each recursion will be decrese it by 1 until 0;
public class Matrix<T> {
private final int height;
private final int width;
private final T[][] data;
public Matrix(T[][] data) {
height = data.length;
width = data[0].length;
this.data = data; // it brakes OOP: encapsulation
}
public boolean isSymmetricIterative() {
if (height != width)
return false;
for (int row = 0; row < height; row++)
for (int col = 0; col < width; col++)
if (data[row][col] != data[col][row])
return false;
return true;
}
public boolean isSymmetricRecursive() {
return isSymmetricRecursive(height - 1, width - 1);
}
private boolean isSymmetricRecursive(int row, int col) {
return row < 0 && col < 0 || data[row][col] == data[col][row] && isSymmetricRecursive(row - 1, col - 1);
}
}
In the recursive version, you forgot to add a check to see if the two elements are equal. Without it, there is no case where the method would return false.
public boolean isSymmetric() {
return m == n && isSymmetric(m - 1, n - 1);
}
public boolean isSymmetric(int i, int j) {
if (i < 0 && j < 0) return true;
else if (data[i][j] != data[j][i]) return false;
else {
return isSymmetric(i - 1, j - 1);
}
}
Symmetric matrix is a square matrix that is equal to its transpose. Let's assume that we have a square matrix.
To avoid unnecessary iterations and to reduce the time complexity, you can iterate over the indices only in the lower left corner of the matrix and compare the corresponding elements with those in the upper right corner m[i][j]==m[j][i], excluding the main diagonal, until the first mismatch.
Try it online!
// let's assume that we have a square matrix
public static void main(String[] args) {
int[][] matrix = {
{1, 2, 3, 4, 5},
{2, 3, 4, 5, 6},
{3, 4, 5, 6, 7},
{4, 5, 6, 7, 8},
{5, 6, 7, 8, 9}};
System.out.println(isSymmetric(matrix)); // true
System.out.println(isSymmetricR(matrix, 1, 0)); // true
}
// iterative version
static boolean isSymmetric(int[][] matrix) {
return IntStream.range(1, matrix.length)
.allMatch(i -> IntStream.range(0, i)
//intermediate output
.peek(j -> System.out.println("i=" + i + ",j=" + j))
.allMatch(j -> matrix[i][j] == matrix[j][i]));
}
// recursive version
static boolean isSymmetricR(int[][] matrix, int i, int j) {
if (i < matrix.length && j < i) {
//intermediate output
System.out.println("i=" + i + ",j=" + j);
if (matrix[i][j] == matrix[j][i]) {
if (j == i - 1) {
return isSymmetricR(matrix, i + 1, 0);
} else {
return isSymmetricR(matrix, i, j + 1);
}
} else {
// the first mismatch, the
// matrix is not symmetric
return false;
}
} else {
// if reached this point,
// the matrix is symmetric
return true;
}
}
The intermediate output is the same in both cases:
i=1,j=0
i=2,j=0
i=2,j=1
i=3,j=0
i=3,j=1
i=3,j=2
i=4,j=0
i=4,j=1
i=4,j=2
i=4,j=3
See also: How to remove rows and columns containing only zeros from a 2d matrix?
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.
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?
My solution for npuzzle works with 2x2 but stack over flow error with 3x3. I am not able to figure out whats wrong. I am using DFS to check if any of the path has the solution.
Algorithm,
- Move piece left, right, up & down.
- For each check if state is already visited .
- if not visited mark visited and check if it matches the goal state.
I believed that the stack should be able to hold all the states, it should be only 181400 states right?
Any help please!
public class PuzzleSolvable {
public static final int N = 3;
public static int[][] s2 = new int[][]{{8, 2, 1},
{-1, 4, 3},
{7, 6, 5}};
public static void main(String[] args) {
int[][] stage1 = new int[][]{ //needs 5 swaps
{1, 2, 3},
{4, 5, 6},
{7, 8, -1}
};
/*int[][] stage1 = new int[][]{{1, 2},
{4, -1}};
int[][] stage2 = new int[][]{{-1, 1},
{4, 2}};*/
Map<String, Boolean> map = new HashMap<>();
boolean solution = false;
for (int i = 0; i <= 181440; i = i + 3000) {
if (isSolvable(stage1, map, i)) {
solution = true;
break;
}
}
if (solution) {
System.out.println("Solution exists");
}else{
System.out.println("Solution does not exist");
}
}
static boolean isSolvable(int[][] s1, Map<String, Boolean> map, int depth) {
if (depth > 3000) {
return false;
}
depth++;
System.out.println(serializeArray(s1));
System.out.println(map.size());
if (map.get(serializeArray(s1)) != null) {
return false;
}
if (equals(s1, s2)) {
return true;
}
map.put(serializeArray(s1), true);
return isSolvable(move(s1, 0), map, depth) ||
isSolvable(move(s1, 1), map, depth) ||
isSolvable(move(s1, 2), map, depth) ||
isSolvable(move(s1, 3), map, depth);
}
static String serializeArray(int[][] arr) {
String s = "";
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
s = s + arr[i][j];
}
}
return s;
}
static boolean equals(int[][] s1, int[][] s2) {
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
if (s1[i][j] != s2[i][j]) {
return false;
}
}
}
return true;
}
static int[][] move(int[][] arr, int direction) {
int[][] array = new int[N][N];
int posx = 0, posy = 0;
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
array[i][j] = arr[i][j];
if (arr[i][j] == -1) {
posx = i;
posy = j;
}
}
}
switch (direction) {
case 0://right
if (posy < N - 1) {
System.out.println("Swap right");
swap(array, posx, posy, posx, posy + 1);
}
break;
case 1://left
if (posy > 0) {
System.out.println("Swap left");
swap(array, posx, posy, posx, posy - 1);
}
break;
case 2://up
if (posx > 0) {
System.out.println("Swap up");
swap(array, posx, posy, posx - 1, posy);
}
break;
case 3://down
if (posx < N - 1) {
System.out.println("Swap down");
swap(array, posx, posy, posx + 1, posy);
}
break;
}
return array;
}
static void swap(int[][] arr, int posx, int posy, int x, int y) {
int temp = arr[posx][posy];
arr[posx][posy] = arr[x][y];
arr[x][y] = temp;
}}
Edited:
Code updated with working version implemented using recursion depth limiter.
I think stack overflow does make sense.
If you test it with a target represented by
static int[][] s2 = new int[][]{
{ 1, 2, 3},
{ 4, -1, 5},
{ 6, 7, 8}
};
and set initial state to
int[][] stage5 = new int[][]{ //needs 5 swaps
{ 2, 3, 5},
{ 1, 4, -1},
{ 6, 7, 8}
};
which requires 5 swaps to get the target, isSolvable is invoked 54 times with no exception.
If you set initial state to
int[][] stage6 = new int[][]{ //needs 6 swaps
{ 2, 3, 5},
{ 1, 4, 8},
{ 6, 7, -1}
};
which requires 6 swaps to get the target, isSolvable is invoked about 12000 times, and throws StackOverflowError.
Even a simple rest like
recusiveTest(stage6, new Random());
//overflows after less than 5k invokes
private static boolean recusiveTest(int[][] array, Random rand){
System.out.println("counter " +isSolvedCounter++);
array[rand.nextInt(2)][rand.nextInt(2)] = 0;
return recusiveTest(array, rand);
}
throws StackOverflowError after less than 5000 runs.
A non recursive dfs solution would be more solid.
Here is a version with limited recursion depth. It needs profiling (it is slow) but it works (tested with a range of test cases. Not fully debugged though):
import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
public class LimitedDfs {
private static final int DEPTH_LIMIT = 3000;
private static final int BLANK = 9;
private static int[][] directions = {
{-1, 0}, //up
{ 0,-1}, //left
{ 0, 1}, //right
{ 1, 0} //down
};
private static int[][] target = new int[][]{
{ 1, 2, 3},
{ 4, 5, 6},
{ 7, 8, 9}
};
private static State targetState = new State(target);
public static void main(String[] args) {
int[][] swap31 = new int[][] {
{3,5,1},
{6,2,4},
{8,7,9}
};
isSolvable(swap31);
}
static boolean isSolvable(int[][] stateData) {
State state = new State(stateData);
List<State> tested = new ArrayList<>();
LinkedList<State> toBeTested = new LinkedList<>();
toBeTested.add(state);
boolean solution = false;
System.out.print("working ");
while (! toBeTested.isEmpty()) {
if ( isSolvable(toBeTested, tested, 0)){
solution = true;
break;
}
System.out.print(".");
}
System.out.print(" Tested "+ tested.size() + " states. ");
if (solution) {
System.out.println("\n -> Solution exists ");
}else{
System.err.println("\n -> Solution does not exist ");
}
return solution;
}
static boolean isSolvable(LinkedList<State> toBeTested, List<State> tested, int depth) {
if((depth ++ > DEPTH_LIMIT) || toBeTested.isEmpty()) {
return false;
}
//else get last element in stack
State state = toBeTested.peek();
if (state.equals(targetState)) {
return true;
}
int added = 0;
for(int[] dir : directions) {
State newState = move(state, dir);
if((newState != null) && ! tested.contains(newState)) {
toBeTested.add(newState);
tested.add(newState);
added++;
break;
}
}
if(added == 0) { // means state was fully explored, remove it
toBeTested.remove(state);
}
return isSolvable(toBeTested, tested, depth);
}
private static State move(State state, int[] dir) {
int[][] stateData = state.getState();
int size = stateData.length;
int[][] newArray = new int[size][size];
int posY = 0, posX = 0;
for (int y = 0; y < size; y++) {
for (int x = 0; x < size; x++) {
newArray[y][x] = stateData[y][x];
if (stateData[y][x] == BLANK) {
posY = y;
posX = x;
}
}
}
if( isValidAddress(posY + dir[0], posX + dir[1], size, size)) {
swap(newArray, posY, posX,posY+ dir[0], posX+ dir[1]);
return new State(newArray);
}
return null;
}
private static void swap(int[][] arr, int y1, int x1, int y2, int x2) {
int temp = arr[y1][x1];
arr[y1][x1] = arr[y2][x2];
arr[y2][x2] = temp;
}
private static boolean isValidAddress(int rowIndex,int colIndex,
int numberOfRows, int numberOfCols) {
if((rowIndex <0) || (rowIndex >= numberOfRows)||
(colIndex <0) || (colIndex >= numberOfCols)) {
return false;
}
return true;
}
}
class State {
private final int[][] state;
private final int hash;
State(int[][] state) {
this.state = state;
hash = serializeArray(state).hashCode();
}
#Override
public boolean equals(Object obj) {
if (this == obj) { return true; }
if (obj == null) { return false; }
if (getClass() != obj.getClass()) {
return false;
}
return hash == obj.hashCode();
}
#Override
public int hashCode() {
return hash;
}
int[][] getState() {
return state;
}
#Override
public String toString() {
StringBuilder sb = new StringBuilder();
for(int[] array : state) {
sb.append(Arrays.toString(array))
.append("\n");
}
return sb.toString();
}
private static String serializeArray(int[][] array) {
StringBuilder sb = new StringBuilder();
for (int[] elements : array) {
for (int element : elements) {
sb.append(element);
}
}
return sb.toString();
}
}
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;
}
}
}