Maze solve and shortest path with Java BFS [closed] - java

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 5 years ago.
Improve this question
The goal is to draw a maze after resolving it (using BFS) with the shortest path from start to exit.
OUTPUT must be like this
***************************************************
[20,19]
***************************************************
#####################
..#...........#.....#
#.#.#########.#.###.#
#...#.........#.#...#
###############.#.###
#.....#.......#.#...#
#.#######.###.#.#.#.#
#...#...#...#...#.#.#
###.###.###.###.#.#.#
#.#.#.#...#.#...#.#.#
#.#.#.#.#1#.#.###.#.#
#...#.#.#1#.#...#.#.#
#####.###1#.#####.###
#.#1111111#.#...#...#
#.#1#######.#.#.###.#
#.#1#...#...#.#.#...#
#.#1###.#.#####.#####
#.#11111111111111111#
#.##.####.#########1#
#..................11
#####################
There are many path to go to the exit [20,19] , but we must draw with the shortest path.
My code is below but it doesn't print the shortest path.
CODE
class Maze {
public static void main(String args[]) {
int W = 21;
int H = 21;
int X = 9;
int Y = 10;
String[] mazeString = {
"##########.##########",
"..#...........#.....#",
"#.#.#########.#.###.#",
"#...#.........#.#...#",
"###############.#.###",
"#.....#.......#.#...#",
"#.#######.###.#.#.#.#",
"#...#...#...#...#.#..",
"###.###.###.###.#.#.#",
"#.#.#.#...#.#...#.#.#",
"#.#.#.#.#.#.#.###.#.#",
"#...#.#.#.#.#...#.#.#",
"#####.###.#.#####.###",
"#.#.......#.#...#...#",
"#.#.#######.#.#.###.#",
"#.#.#...#...#.#.#...#",
"#.#.###.#.#####.#####",
"#.#.................#",
"#.##.####.#########.#",
"#.........#..........",
"####.######.#########"
};
Node[][] nodes = new Node[W][H];
Node start = null;
List<Node> result = new ArrayList<>();
Boolean[][] visited = new Boolean[W][H];
Boolean[][] blocked = new Boolean[W][H];
Boolean[][] exits = new Boolean[W][H];
for (int i = 0; i < H; i++) {
String R = mazeString[i];
for (int j = 0; j < W; j++) {
Node node = new Node(j, i);
blocked[j][i] = R.charAt(j) == '#';
node.blocked = R.charAt(j) == '#';
exits[j][i] = (!node.blocked) && (i == (H - 1) || j == (W - 1) || i == 0 || j == 0);
visited[j][i] = false;
node.exit = (!node.blocked) && (i == (H - 1) || j == (W - 1) || i == 0 || j == 0);
nodes[j][i] = node;
if (X == j && Y == i) {
start = nodes[j][i];
}
}
}
List<List<Node>> paths = new ArrayList<>();
findExits(start, nodes, visited, W, H, result, paths);
if (!result.isEmpty()) {
Collections.sort(result, new Comparator<Node>() {
#Override
public int compare(Node o1, Node o2) {
if (Integer.compare(o1.x, o2.x) == 0) {
return Integer.compare(o1.y, o2.y);
} else {
return Integer.compare(o1.x, o2.x);
}
}
});
}
for (List<Node> path : paths) {
System.out.println("***************************************************");
System.out.println("[" + path.get(0).x + "," + path.get(0).y + "]");
System.out.println("***************************************************");
for (int i = 0; i < H; i++) {
for (int j = 0; j < W; j++) {
String s = blocked[j][i] ? "#" : path.contains(new Node(j, i)) ? "1" : ".";
System.out.print(s);
}
System.out.println("");
}
}
}
public static void findExits(Node start, Node[][] nodes, Boolean[][] visited, int W, int H, List<Node> result, List<List<Node>> paths) {
int x = start.x;
int y = start.y;
visited[x][y] = true;
if (start.exit) {
result.add(start);
visited[x][y] = false;
List<Node> path = new ArrayList<Node>();
while (start.parent != null) {
path.add(start);
start = start.parent;
}
path.add(start);
paths.add(path);
}
//TOP
if ((y - 1) >= 0) {
if (!visited[x][y - 1] && (!nodes[x][y - 1].blocked)) {
nodes[x][y - 1].parent = start;
findExits(nodes[x][y - 1], nodes, visited, W, H, result, paths);
}
}
//BOT
if ((y + 1) < H) {
if (!visited[x][y + 1] && (!nodes[x][y + 1].blocked)) {
nodes[x][y + 1].parent = start;
findExits(nodes[x][y + 1], nodes, visited, W, H, result, paths);
}
}
//LEFT
if ((x - 1) >= 0) {
if (!visited[x - 1][y] && (!nodes[x - 1][y].blocked)) {
nodes[x - 1][y].parent = start;
findExits(nodes[x - 1][y], nodes, visited, W, H, result, paths);
}
}
//RIGHT
if ((x + 1) < W) {
if (!visited[x + 1][y] && (!nodes[x + 1][y].blocked)) {
nodes[x + 1][y].parent = start;
findExits(nodes[x + 1][y], nodes, visited, W, H, result, paths);
}
}
}
public static class Node {
public int x, y;
boolean blocked = false;
boolean exit = false;
Node parent = null;
public Node(int x, int y) {
this.x = x;
this.y = y;
}
#Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final Node other = (Node) obj;
if (this.x != other.x) {
return false;
}
if (this.y != other.y) {
return false;
}
return true;
}
}
}
I want to solve a maze and print the shortest path from start to exit usign BFS. I already solve the maze but my code doesnt print the shortest path, this is my problem.
NB (Additional informations, not questions) :
the maze can have many exit
W (width), H (height), [X,Y] (start point)
'#' (blocked cell), '.' (free cell)
the path from start and exit is represented by '11111...' on the output

Please review the following code. It lets you printout all paths found, as well as the shortest one found.
I did not change nor checked the search algorithm. I think it needs more work because I think it does not find the shortest path possible to each exit. I will look into it later.
I did not figure out yet what is the use of List<Node> result. Also I did not see you implement backtracking.
class Maze {
private static char NUMBER_SIGN = '#', DOT = '.', START = 'S';
private static char EXIT = 'E', PATH = '1';
private static Node[][] nodes;
private static Node start;
private static boolean[][] visited; //no need to use Boolean
//exit holds the same information as Node.blocked. No need to duplicate
//private static boolean[][] blocked;
//exit holds the same information as Node.exit. No need to duplicate
//private static boolean[][] exits;
private static int mazeWidth, mazeHeight, startH, startW; //use meaningful names
private static List<List<Node>> paths;
public static void main(String args[]) {
mazeWidth = 21;//use meaningful names
mazeHeight = 21;
startH = 9; startW = 10;
String[] mazeData = getMazeData() ;
makeMaze(mazeData);
drawMaze(); //draw maze as built from input data
List<Node> result = new ArrayList<>();
paths = new ArrayList<>();
findExits(start, nodes, visited, mazeWidth, mazeHeight, result, paths);
if (!result.isEmpty()) {
Collections.sort(result, new Comparator<Node>() {
#Override
public int compare(Node o1, Node o2) {
if (Integer.compare(o1.x, o2.x) == 0) {
return Integer.compare(o1.y, o2.y);
} else {
return Integer.compare(o1.x, o2.x);
}
}
});
}
drawAllPaths(); // see all paths found
List<Node> shortestPath = getShortestPath();
drawShortestPath(shortestPath);
}
private static void drawMaze() {
System.out.println("***************************************************");
System.out.println("Maze as defined by input");
System.out.println("***************************************************");
drawMaze(null);
}
private static void drawAllPaths() {
for (List<Node> path : paths) {
System.out.println("***************************************************");
System.out.println("Path to exit ["
+ path.get(0).x + "," + path.get(0).y + "] length:"+ path.size());
System.out.println("***************************************************");
drawMaze(path);
}
}
private static void drawShortestPath(List<Node> path) {
System.out.println("***************************************************");
System.out.println("Shortest path is to exit ["
+ path.get(0).x + "," + path.get(0).y + "] length:"+ path.size());
System.out.println("***************************************************");
drawMaze(path);
}
private static void drawMaze(List<Node> path) {
for(Node[] row : nodes ) {
for(Node node : row) {
char c = node.getGraphics();
if ((path != null) && path.contains(node)) {c = PATH;}
System.out.print(c);
}
System.out.println("");
}
}
private static void makeMaze(String[] mazeData) {
nodes = new Node[mazeHeight][mazeWidth];
visited = new boolean[mazeHeight][mazeWidth];
for (int height = 0; height < mazeHeight; height++) {
String row = mazeData[height];
for (int width = 0; width < mazeWidth; width++) {
Node node = new Node(height, width);
node.blocked = row.charAt(width) == NUMBER_SIGN;
visited[width][height] = false;
node.exit = (!node.blocked) && ((height == (mazeHeight - 1)) ||
(width == (mazeWidth - 1)) || (height == 0) || (width == 0));
nodes[height][width] = node;
}
}
start = nodes[startH][startW];//no need to set it in the loop
}
//use boolean instead of Boolean
private static void findExits(Node start, Node[][] nodes,
boolean[][] visited, int W, int H, List<Node> result, List<List<Node>> paths) {
int x = start.x;
int y = start.y;
visited[x][y] = true;
if (start.exit) {
result.add(start);
visited[x][y] = false;
List<Node> path = new ArrayList<>();
while (start.parent != null) {
path.add(start);
start = start.parent;
}
path.add(start);
paths.add(path);
}
//TOP
if ((y - 1) >= 0) {
if (!visited[x][y - 1] && (!nodes[x][y - 1].blocked)) {
nodes[x][y - 1].parent = start;
findExits(nodes[x][y - 1], nodes, visited, W, H, result, paths);
}
}
//BOT
if ((y + 1) < H) {
if (!visited[x][y + 1] && (!nodes[x][y + 1].blocked)) {
nodes[x][y + 1].parent = start;
findExits(nodes[x][y + 1], nodes, visited, W, H, result, paths);
}
}
//LEFT
if ((x - 1) >= 0) {
if (!visited[x - 1][y] && (!nodes[x - 1][y].blocked)) {
nodes[x - 1][y].parent = start;
findExits(nodes[x - 1][y], nodes, visited, W, H, result, paths);
}
}
//RIGHT
if ((x + 1) < W) {
if (!visited[x + 1][y] && (!nodes[x + 1][y].blocked)) {
nodes[x + 1][y].parent = start;
findExits(nodes[x + 1][y], nodes, visited, W, H, result, paths);
}
}
}
public static class Node {
public int x, y;
boolean blocked = false;
boolean exit = false;
Node parent = null;
public Node(int x, int y) {
this.x = x;
this.y = y;
}
#Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final Node other = (Node) obj;
if (x != other.x) {
return false;
}
if (y != other.y) {
return false;
}
return true;
}
//it is simpler to have Node return its graphic representation
char getGraphics() {
char c = blocked ? NUMBER_SIGN : DOT;
if(equals(start)) { c=START;}
else if (exit) { c=EXIT;}
return c;
}
}
private static List<Node> getShortestPath() {
//initialize with an arbitrary path
List<Node> shortest = paths.get(0);
for (List<Node> path : paths) {
if(path.size() < shortest.size()) {
shortest = path;
}
}
return shortest;
}
private static String[] getMazeData() {
return new String[] {
"##########.##########",
"..#...........#.....#",
"#.#.#########.#.###.#",
"#...#.........#.#...#",
"###############.#.###",
"#.....#.......#.#...#",
"#.#######.###.#.#.#.#",
"#...#...#...#...#.#..",
"###.###.###.###.#.#.#",
"#.#.#.#...#.#...#.#.#",
"#.#.#.#.#.#.#.###.#.#",
"#...#.#.#.#.#...#.#.#",
"#####.###.#.#####.###",
"#.#.......#.#...#...#",
"#.#.#######.#.#.###.#",
"#.#.#...#...#.#.#...#",
"#.#.###.#.#####.#####",
"#.#.................#",
"#.##.####.#########.#",
"#.........#..........",
"####.######.#########"
};
}
}
EDIT
An improved version. Please test carefully.
class Maze {
private static char NUMBER_SIGN = '#', DOT = '.', START = 'S';
private static char EXIT = 'E', PATH = '1';
private static Node[][] nodes;
private static Node startNode;
private static boolean[][] visited; //no need to use Boolean
//exit holds the same information as Node.blocked. No need to duplicate
//private static boolean[][] blocked;
//exit holds the same information as Node.exit. No need to duplicate
//private static boolean[][] exits;
private static int mazeRows, mazeCols, startRow, startCol; //use meaningful names
private static List<List<Node>> paths;
public static void main(String args[]) {
mazeCols = 21; mazeRows = 21;//use meaningful and consistent names
startRow = 9; startCol = 10; //better keep h,w or height,width all over
String[] mazeData = getMazeData() ;
makeMaze(mazeData);
drawMaze(); //draw maze as built from input data
paths = new ArrayList<>();
findExits(startNode);
drawAllPaths(); // print all paths found
List<Node> shortestPath = getShortestPath();
drawShortestPath(shortestPath);
}
private static void drawMaze() {
System.out.println("*****************************************");
System.out.println("Maze as defined by input");
System.out.println("*****************************************");
drawMaze(null);
}
private static void drawAllPaths() {
for (List<Node> path : paths) {
System.out.println("*****************************************");
System.out.println("Path to exit ["
+ path.get(0).row + "," + path.get(0).col + "] length:"+ path.size());
System.out.println("*****************************************");
drawMaze(path);
}
}
private static void drawShortestPath(List<Node> path) {
System.out.println("*****************************************");
System.out.println("Shortest path is to exit ["
+ path.get(0).row + "," + path.get(0).col + "] length:"+ path.size());
System.out.println("*****************************************");
drawMaze(path);
}
private static void drawMaze(List<Node> path) {
for(Node[] row : nodes ) {
for(Node node : row) {
char c = node.getGraphics();
//overwrite c if node is in path
if ( (c != EXIT) && ( c != START ) &&
(path != null) && path.contains(node)) {c = PATH;}
System.out.print(c);
}
System.out.println("");
}
}
private static void makeMaze(String[] mazeData) {
nodes = new Node[mazeRows][mazeCols];
visited = new boolean[mazeRows][mazeCols];
for (int rowIndex = 0; rowIndex < mazeRows; rowIndex++) {
String row = mazeData[rowIndex];
for (int colIndex = 0; colIndex < mazeCols; colIndex++) {
Node node = new Node(rowIndex, colIndex);
node.blocked = row.charAt(colIndex) == NUMBER_SIGN;
visited[rowIndex][colIndex] = false;
node.exit = (!node.blocked) && ((rowIndex == (mazeRows - 1)) ||
(colIndex == (mazeCols - 1)) || (rowIndex == 0) || (colIndex == 0));
nodes[rowIndex][colIndex] = node;
}
}
startNode = nodes[startRow][startCol];//no need to set it in the loop
}
//use boolean instead of Boolean
private static void findExits(Node node) {
int row = node.row;
int col = node.col;
if(visited[row][col]) { return; }
if (node.exit) {
List<Node> path = new ArrayList<>();
while (node.parent != null) {
path.add(node);
node = node.parent;
}
path.add(node);
paths.add(path);
return; //do not continue to check exit neighbors
}
//LEFT
if ((col - 1) >= 0) {
Node testNode = nodes[row][col - 1];
//the following if statement repeats for all directions
//better put in a method
if ((testNode.parent == null) && ! testNode.blocked) {
testNode.parent = node; //parent ! null indicates that cell is tested
findExits(testNode);
testNode.parent = null; //set back to null: test finished
}
}
//RIGHT
if ((col + 1) < mazeCols) {
Node testNode = nodes[row][col + 1];
if ((testNode.parent == null) && ! testNode.blocked) {
testNode.parent = node;
findExits(testNode);
testNode.parent = null;
}
}
//TOP
if ((row - 1) >= 0) {
Node testNode = nodes[row-1][col];
if ((testNode.parent == null) && ! testNode.blocked) {
testNode.parent = node;
findExits(testNode);
testNode.parent = null;
}
}
//BOTTOM
if ((row + 1) < mazeRows) {
Node testNode = nodes[row+1][col];
if ((testNode.parent == null) && ! testNode.blocked) {
testNode.parent = node;
findExits(testNode);
testNode.parent = null;
}
}
visited[row][col] = true; //mark as visited after all directions explored
node.parent = null;
}
public static class Node {
public int row, col;
boolean blocked = false;
boolean exit = false;
Node parent = null;
public Node(int row, int col) {
this.row = row;
this.col = col;
}
#Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final Node other = (Node) obj;
if (row != other.row) {
return false;
}
if (col != other.col) {
return false;
}
return true;
}
//it is simpler to have Node return its graphic representation
char getGraphics() {
char c = blocked ? NUMBER_SIGN : DOT;
if(equals(startNode)) { c=START;}
else if (exit) { c=EXIT;}
return c;
}
#Override
public String toString() {
return "Node " + row +"-"+ col +" ("+ getGraphics() + ")";
}
}
private static List<Node> getShortestPath() {
//initialize with an arbitrary path
List<Node> shortest = paths.get(0);
for (List<Node> path : paths) {
if(path.size() < shortest.size()) {
shortest = path;
}
}
return shortest;
}
private static String[] getMazeData() {
return new String[] {
"##########.##########",
"..#...........#.....#",
"#.#.#########.#.###.#",
"#...#.........#.#...#",
"###############.#.###",
"#.....#.......#.#...#",
"#.#######.###.#.#.#.#",
"#...#...#...#...#.#..",
"###.###.###.###.#.#.#",
"#.#.#.#...#.#...#.#.#",
"#.#.#.#.#.#.#.###.#.#",
"#...#.#.#.#.#...#.#.#",
"#####.###.#.#####.###",
"#.#.......#.#...#...#",
"#.#.#######.#.#.###.#",
"#.#.#...#...#.#.#...#",
"#.#.###.#.#####.#####",
"#.#.................#",
"#.##.####.#########.#",
"#.........#..........",
"####.######.#########"
};
}
}
Feedback would be appreciated.

You're on the right track where you're building a list of paths.
Try this:
create an empty list of paths
start at the starting point, create one path with one cell
look in the four directions and for each cell that is not blocked and not already included in any of the previous paths clone your current path, add that new cell to the end and add it to the list of paths
now loop through all your paths and repeat this progress, checking the four directions from the cell at the tip
stop building a path when it hits the exit or has no more legitimate moves to make, i.e. dead end
use the path with the shortest length

Related

Find max sum path and trace its path in 2d matrix with obstacles

For example I have 2d matrix like this:
.X..X..
2...2..
..X.1..
2.....X
Starting at (0,0),I can move down 1 cell or right 1 cell at a time, cell 'X' is an obstacle. Find the path with maximum sum. The answer for the above input is: DRRRRRD (D for down, R for right)
I could find the sum using dfs and a DP array but I don't know how can I trace the optimal path with this approach.
public static int dfs(char[][] matrix, int i, int j, int[][] cache) {
if (cache[i][j] != 0) {
return cache[i][j];
}
if (matrix[i][j] != 'X' && matrix[i][j] != 'x' && matrix[i][j] != '.') {
cache[i][j] += Character.getNumericValue(matrix[i][j]);
}
int iDown = i + 1;
int jRight = j + 1;
int dirDown = cache[i][j];
int dirRight = cache[i][j];
if (iDown < matrix.length && matrix[iDown][j] != 'X' && matrix[iDown][j] != 'x') {
dirDown += dfs(matrix, iDown, j, cache);
}
if (jRight < matrix[0].length && matrix[i][jRight] != 'X' && matrix[i][jRight] != 'x') {
dirRight += dfs(matrix, i, jRight, cache);
}
cache[i][j] = Math.max(dirDown, dirRight);
return cache[i][j];
}
You can modify dfs to keep track of the path and have it return a pair of Integer (the sum) and a String representing the path:
import java.util.Map;
import java.util.Map.Entry;
class Main {
public static void main(String[] args) {
char[][] matrix = {
{'.','X','.','.','X','.','.'},
{'2','.','.','.','2','.','.'},
{'.','.','X','.','1','.','.'},
{'2','.','.','.','.','.','X'}
};
Entry<Integer, String> result = dfs(matrix,0,0,new int[matrix.length][matrix[0].length],"");
System.out.println(result.getKey() +" "+ result.getValue());
}
//Entry is used as a container for an int-string pair
public static Entry<Integer, String> dfs(char[][] matrix, int i, int j, int[][] cache, String path) {
cache[i][j]=0;//clear previous sum
if (matrix[i][j] != 'X' && matrix[i][j] != 'x' && matrix[i][j] != '.') {
cache[i][j] += Character.getNumericValue(matrix[i][j]);
}
int iDown = i + 1;
int jRight = j + 1;
Entry<Integer,String> resultDown = null;
Entry<Integer,String> resultRight = null;
if (iDown < matrix.length && matrix[iDown][j] != 'X' && matrix[iDown][j] != 'x') {
resultDown = dfs(matrix, iDown, j, cache, path+"D");
if(resultDown.getKey() <= 0) { //no values found
resultDown = null;
}
}
if (jRight < matrix[0].length && matrix[i][jRight] != 'X' && matrix[i][jRight] != 'x') {
resultRight = dfs(matrix, i, jRight, cache, path+"R");
if(resultRight.getKey() <= 0) { //no values found
resultRight = null;
}
}
//no values found moving right or down
if(resultDown == null && resultRight == null) return Map.entry(cache[i][j], path);
String newPath = path;
if(resultDown != null && resultRight != null){ //values found in both directions
if(resultDown.getKey() > resultRight.getKey()) {
cache[i][j]+= resultDown.getKey();
newPath = resultDown.getValue();
}else {
cache[i][j] += resultRight.getKey();
newPath = resultRight.getValue();
}
}else /*values found only in one direction*/if(resultDown != null ) {
cache[i][j] += resultDown.getKey();
newPath = resultDown.getValue();
}else{
cache[i][j] += resultRight.getKey();
newPath = resultRight.getValue();
}
return Map.entry(cache[i][j] , newPath);
}
}
A better and more Object Oriented approach is to define a Node object, for example:
class Node {
private final char value;
private String direction;
private Node child = null;
private int sum = 0;
public Node(char value) {
this.value = value;
}
public String getDirection() {
return direction;
}
public void setDirection(String direction) {
this.direction = direction;
}
public Node getChild() {
return child;
}
public void setChild(Node parent) {
child = parent;
}
public char getValue() {
return value;
}
public int getSum() {
return sum;
}
public void addToSum(int add) {
sum += add;
}
}
and run dfs on a graph of Nodes (for example Node[][]).

Java assignment to use Dijkstras search method, breath-first and depth first

Hello StackOverflow community, need your help. I have a final for my java class and its asking for:
Generate a graph with 100,000 nodes, where each node randomly has between 1 and 5 connections to other nodes. Each node should contain within it a random value between 1 and 300,000. (So generally about 1 in 3 searches will yield a query match). Allow the user to enter a number to search for, and implement each of the following three types of searching algorithms. Breadth-First. (30 points) Depth-First. (30 points) Dijkstra's Algorithm. (40 points)
Do not allow back-tracking in your searches. (Mark nodes that you already searched as complete, and do not re-visit them in the same search). Each search should return the following: The Success/Failure of your search. The length of the shortest path to the found node. The total number of nodes examined during the search. Optionally you may return the exhaustive display of the shortest path, for testing and verification.
For some reason, my IDE shows that BFS and Dijkstras has "duplicated code fragment 17 lines long" can someone look at tell me how to fix it or maybe a better way to implement it? Also, if i try to do nodesNum > 30k in "Driver Class" i get a memory leak.
Here is the code:
Class Graph:
import java.util.*;
import javax.swing.JOptionPane;
class Graph
{
private Listing[] vertex;
private int[][] edge;
private int max;
private int numberOfVertices;
private int nodeCheck = 0;
private int selectNum = 0;
Graph(int g)
{
vertex = new Listing[g];
edge = new int[g][g];
max = g;
numberOfVertices = 0;
}
private void depthFirstSearch(int firstVertex)
{
int v;
Stack<Integer> nodeStack = new Stack<>();
for(int i = 0; i<numberOfVertices; i++)
{
if (vertex[i] != null) {
vertex[i].setPushed(false);
}
}
nodeStack.push(firstVertex);
vertex[firstVertex].setPushed(true);
while (!nodeStack.empty())
{
v = nodeStack.pop();
vertex[v].visit();
nodeCheck++;
for (int column = 0; column < numberOfVertices; column++)
{
if(edge[v][column] == 1 && vertex[column].getPushed())
{
nodeStack.push(column);
vertex[column].setPushed(true);
}
}
}
}
private void breathFirstSearch(int firstVertex)
{
int V;
Queue<Integer> nodeQueue = new LinkedList<>();
for(int i = 0; i < numberOfVertices; i++)
{
if(vertex[i] != null)
vertex[i].setPushed(false);
}
nodeQueue.add(firstVertex);
vertex[firstVertex].setPushed(true);
while(!nodeQueue.isEmpty())
{
V = nodeQueue.remove();
vertex[V].visit();
nodeCheck++;
for(int column = 0; column < numberOfVertices; column++)
{
if(edge[V][column] == 1 && vertex[column].getPushed())
{
nodeQueue.add(column);
vertex[column].setPushed(true);
}
}
}
}
private void Dijkstra(int firstVertex)
{
int v;
LinkedList<Integer> nodeQueue = new LinkedList<>();
int i = 0;
while (i < numberOfVertices)
{
if(vertex[i] != null)
vertex[i].setPushed(false);
i++;
}
nodeQueue.add(firstVertex);
vertex[firstVertex].setPushed(true);
while(!nodeQueue.isEmpty())
{
v = nodeQueue.remove();
vertex[v].visit();
nodeCheck++;
for(int column = 0; column < numberOfVertices; column++)
{
if(edge[v][column] == 1 && vertex[column].getPushed())
{
nodeQueue.add(column);
vertex[column].setPushed(true);
}
}
}
}
private void insertVertex(int vertexNumber, Listing newListing)
{
if(vertexNumber >= max)
{
return;
}
vertex[vertexNumber] = newListing.deepCopy();
numberOfVertices++;
}
private void insertEdge(int fromVertex, int toVertex)
{
if(vertex[fromVertex] == null || vertex[toVertex] == null)
return;
edge[fromVertex][toVertex] = 1;
}
void showVertex(int vertexNumber)
{
System.out.print(vertex[vertexNumber]);
}
void showEdges(int vertexNumber)
{
for(int column = 0; column < numberOfVertices; column++)
{
if(edge[vertexNumber][column] == 1)
{
System.out.println(vertexNumber + "," + column);
}
}
System.out.println();
}
void InitializeNodes(Graph G, int nodesNum)
{
Random random = new Random();
for (int i = 0; i < nodesNum; i++ )
{
Listing v = new Listing(random.nextInt(300000) + 1);
G.insertVertex(i, v);
}
int vertexListNumber = G.vertex.length;
List<Integer> list = new ArrayList<>();
for (int i = 0; i < nodesNum; i++ )
{
list.add(i);
}
Collections.shuffle(list);
for (int i = 0; i < vertexListNumber; i++ )
{
int randnum = random.nextInt(5);
for (int j = 0; j < randnum; j++ )
{
int rand = random.nextInt(5);
G.insertEdge(i, list.get(rand));
}
}
}
int Search()
{
String search = JOptionPane.showInputDialog("Enter Node to search:");
try
{
if(search != null)
{
selectNum = Integer.parseInt(search);
}
}
catch (NumberFormatException e)
{
selectNum = 0;
}
return selectNum;
}
private int SelectPane()
{
String paneSelect = JOptionPane.showInputDialog("Choose a search method:" +
"\n\t1: Use Depth-First Search" +
"\n\t2: Use Breadth-First Search" +
"\n\t3: Use Dijkstra's Search" +
"\n\t4: Close Program");
int selectNum = 0;
try{
if(paneSelect != null)
{
selectNum = Integer.parseInt(paneSelect);
}
}
catch (NumberFormatException ignored)
{
}
return selectNum;
}
void algorithmChoice(Graph graph, int vertexStart)
{
int paneNum = 0;
while (paneNum != 4)
{
paneNum = SelectPane();
switch (paneNum)
{
case 1:
graph.depthFirstSearch(vertexStart);
System.out.println("Nodes counted were: " + nodeCheck);
System.out.println("------------------------------------");
break;
case 2:
graph.breathFirstSearch(vertexStart);
System.out.println("Nodes counted were: " + nodeCheck);
System.out.println("------------------------------------");
break;
case 3:
graph.Dijkstra(vertexStart);
System.out.println("Nodes counted were: " + nodeCheck);
System.out.println("------------------------------------");
break;
case 4:
break;
default:
JOptionPane.showMessageDialog(null, "Enter 4 to quit.");
break;
}
}
}
}
Class Listing:
public class Listing
{
private int value;
private boolean pushed;
Listing(int v)
{
value = v;
}
public String toString()
{
return ("Vertex: " + value + "\n" );
}
Listing deepCopy()
{
return new Listing(value);
}
boolean getPushed()
{
return !pushed;
}
void setPushed(boolean value)
{
pushed = value;
}
void visit()
{
System.out.println(this);
}
}
Class Driver:
public class Driver
{
public static void main(String[] args)
{
int nodesNum = 30000; //Can go up to 30k nodes, otherwise causes memory leak.
Graph graph = new Graph(nodesNum);
graph.InitializeNodes(graph, nodesNum);
for(int i = 0; i<5; i++)
{
System.out.print("Node " + i + "\'s ");
graph.showVertex(i);
System.out.print("Its routes are:\n");
graph.showEdges(i);
}
int select = graph.Search();
graph.algorithmChoice(graph, select);
}
}
Thanks alot for your help!
The error you get is due to exceeding max heap size when creating a edge = new int[g][g]; where g can be as high as 100,000 in your case.
I would suggest avoiding the use of such huge matrix.
Instead introduce an Edge object :
class Edge{
private final int fromVertex, toVertex;
Edge(int fromVertex, int toVertex){
this.fromVertex = fromVertex;
this.toVertex = toVertex;
}
#Override
public boolean equals(Object obj) {
if( ! (obj instanceof Edge)) return false;
Edge other = (Edge)obj;
return connects(other.fromVertex, other.toVertex);
}
boolean connects(int fromVertex, int toVertex){
return fromVertex == this.fromVertex && toVertex == this.toVertex ||
fromVertex == this.toVertex && toVertex == this.fromVertex;
}
}
and use it in Graph.
Instead of private int[][] edge; use a collection of Edges:
private final Set<Edge> edges = new HashSet<>();
Change insertEdge to:
private void insertEdge(int fromVertex, int toVertex)
{
if(vertex[fromVertex] == null || vertex[toVertex] == null)
return;
edges.add(new Edge(fromVertex, toVertex));
}
and add a method to check if there is an edge between two vertices:
private boolean isEdgeBetween(int fromVertex, int toVertex)
{
for(Edge edge : edges){
if(edge.connects(fromVertex, toVertex)) return true;
}
return false;
}
Usage : if( isEdgeBetween(v,column) && vertex[column].getPushed())
instead of: if(edge[v][column] == 1 && vertex[column].getPushed())

Actual path in maximum path sum in binary tree

I'm trying to store and print the actual path in the problem of finding maximum path sum in a binary tree. I already know how to find the maximum path sum (below), but how can we add a snippet to output the actual path?
private int maxSum;
public int maxPathSum(TreeNode root) {
maxSum = Integer.MIN_VALUE;
findMax(root);
return maxSum;
}
private int findMax(TreeNode p) {
if (p == null) return 0;
int left = findMax(p.left);
int right = findMax(p.right);
maxSum = Math.max(p.val + left + right, maxSum);
int ret = p.val + Math.max(left, right);
return ret > 0 ? ret : 0;
}
May you can try this.
static class Node {
int pathSum;
List<Integer> path;
Node(int pathSum) {
this.pathSum = pathSum;
this.path = new ArrayList<>();
}
}
public List<Integer> maxPathSum(TreeNode root) {
solve(root);
return maxPathTrace;
}
int maxPath = Integer.MIN_VALUE;
List<Integer> maxPathTrace = new ArrayList<>();
public Node solve(TreeNode root) {
if ( root == null) return new Node(0);
Node leftNode = solve(root.left);
Node rightNode = solve(root.right);
int leftGain = Math.max(leftNode.pathSum, 0);
int rightGain = Math.max(rightNode.pathSum, 0);
int resultGain = leftGain + rightGain + root.val;
// calculate max path and note it down
if ( resultGain > maxPath) {
maxPathTrace.clear();
if ( leftNode.pathSum >= 0) {
maxPathTrace.addAll(leftNode.path);
}
maxPathTrace.add(root.val);
if ( rightNode.pathSum >= 0) {
maxPathTrace.addAll(rightNode.path);
}
}
maxPath = Math.max(resultGain, maxPath);
//calculate return path
Node resultNode = new Node(Math.max(leftGain + root.val , rightGain + root.val));
if ( leftGain > rightGain ) {
if ( leftNode.pathSum >= 0) {
resultNode.path.addAll(leftNode.path);
}
resultNode.path.add(root.val);
} else {
resultNode.path.add(root.val);
if ( rightNode.pathSum >= 0) {
resultNode.path.addAll(rightNode.path);
}
}
return resultNode;
}

AVL tree rotation in Java

I want to implement the Java AVL tree and to rotate the tree left and right. I am not getting this.
Can anybody by looking at the code below tell me how can I possibly rotate the tree left and right and then use fix up with those two functions to balance the AVL tree?
I hope someone here can guide me through this.
import java.util.Random;
import java.util.SortedSet;
import java.util.TreeSet;
public class AVLTree<T> extends
BinarySearchTree<AVLTree.Node<T>, T> implements SSet<T> {
Random rand;
public static class Node<T> extends BSTNode<Node<T>,T> {
int h; // the height of the node
}
public AVLTree() {
sampleNode = new Node<T>();
rand = new Random();
c = new DefaultComparator<T>();
}
public int height(Node<T> u) {
return (u == null) ? 0 : u.h;
}
public boolean add(T x) {
Node<T> u = new Node<T>();
u.x = x;
if (super.add(u)) {
for (Node<T> w = u; w != nil; w = w.parent) {
// walk back up to the root adjusting heights
w.h = Math.max(height(w.left), height(w.right)) + 1;
}
fixup(u);
return true;
}
return false;
}
public void splice(Node<T> u) {
Node<T> w = u.parent;
super.splice(u);
for (Node<T> z = u; z != nil; z = z.parent)
z.h = Math.max(height(z.left), height(z.right)) + 1;
fixup(w);
}
public void checkHeights(Node<T> u) {
if (u == nil) return;
checkHeights(u.left);
checkHeights(u.right);
if (height(u) != 1 + Math.max(height(u.left), height(u.right)))
throw new RuntimeException("Check heights shows incorrect heights");
int dif = height(u.left) - height(u.right);
if (dif < -1 || dif > 1)
throw new RuntimeException("Check heights found height difference of " + dif);
}
/**
* TODO: finish writing this method
* #param u
*/
public void fixup(Node<T> u) {
while (u != nil) {
int dif = height(u.left) - height(u.right);
if (dif > 1) {
// TODO: add code here to fix AVL condition
// on the path from u to the root, if necessary
} else if (dif < -1) {
// TODO: add code here to fix AVL condition
// on the path from u to the root, if necessary
}
u = u.parent;
}
}
public Node rotateLeft() {
return rotateLeft(u.parent);
}
public void rotateLeft(Node<T> u) {
// TODO: Recompute height values at u and u.parent
}
public void rotateRight(Node<T> u) {
// TODO: Recompute height values at u and u.parent
}
public static <T> T find(SortedSet<T> ss, T x) {
SortedSet<T> ts = ss.tailSet(x);
if (!ts.isEmpty()) {
return ts.first();
}
return null;
}
/**
* This just does some very basic correctness testing
* #param args
*/
public static void main(String[] args) {
AVLTree<Integer> t = new AVLTree<Integer>();
Random r = new Random(0);
System.out.print("Running AVL tests...");
int n = 1000;
for (int i = 0; i < n; i++) {
t.add(r.nextInt(2*n));
t.checkHeights(t.r);
}
for (int i = 0; i < n; i++) {
t.remove(r.nextInt(2*n));
t.checkHeights(t.r);
}
System.out.println("done");
t.clear();
System.out.print("Running correctness tests...");
n = 100000;
SortedSet<Integer> ss = new TreeSet<Integer>();
Random rand = new Random();
for (int i = 0; i < n; i++) {
Integer x = rand.nextInt(2*n);
boolean b1 = t.add(x);
boolean b2 = ss.add(x);
if (b1 != b2) {
throw new RuntimeException("Adding " + x + " gives " + b2
+ " in SortedSet and " + b1 + " in AVL Tree");
}
}
for (int i = 0; i < n; i++) {
Integer x = rand.nextInt(2*n);
Integer x1 = t.find(x);
Integer x2 = find(ss, x);
if (x1 != x2) {
throw new RuntimeException("Searching " + x + " gives " + x2
+ " in SortedSet and " + x1 + " in AVL Tree");
}
ss.headSet(x);
}
for (int i = 0; i < n; i++) {
Integer x = rand.nextInt(2*n);
boolean b1 = t.remove(x);
boolean b2 = ss.remove(x);
if (b1 != b2) {
throw new RuntimeException("Error (2): Removing " + x + " gives " + b2
+ " in SortedSet and " + b1 + " in AVL Tree");
}
}
for (int i = 0; i < n; i++) {
Integer x = rand.nextInt(2*n);
Integer x1 = t.find(x);
Integer x2 = find(ss, x);
if (x1 != x2) {
throw new RuntimeException("Error (3): Searching " + x + " gives " + x2
+ " in SortedSet and " + x1 + " in AVL Tree");
}
ss.headSet(x);
}
System.out.println("done");
}
}
Full AVL tree implementation:
public class AVLTree<T> {
private AVLNode<T> root;
private static class AVLNode<T> {
private T t;
private int height;
private AVLNode<T> left;
private AVLNode<T> right;
private AVLNode(T t) {
this.t = t;
height = 1;
}
}
public void insert(T value) {
root = insert(root, value);
}
private AVLNode<T> insert(AVLNode<T> n, T v) {
if (n == null) {
n = new AVLNode<T>(v);
return n;
} else {
int k = ((Comparable) n.t).compareTo(v);
if (k > 0) {
n.left = insert(n.left, v);
} else {
n.right = insert(n.right, v);
}
n.height = Math.max(height(n.left), height(n.right)) + 1;
int heightDiff = heightDiff(n);
if (heightDiff < -1) {
if (heightDiff(n.right) > 0) {
n.right = rightRotate(n.right);
return leftRotate(n);
} else {
return leftRotate(n);
}
} else if (heightDiff > 1) {
if (heightDiff(n.left) < 0) {
n.left = leftRotate(n.left);
return rightRotate(n);
} else {
return rightRotate(n);
}
} else;
}
return n;
}
private AVLNode<T> leftRotate(AVLNode<T> n) {
AVLNode<T> r = n.right;
n.right = r.left;
r.left = n;
n.height = Math.max(height(n.left), height(n.right)) + 1;
r.height = Math.max(height(r.left), height(r.right)) + 1;
return r;
}
private AVLNode<T> rightRotate(AVLNode<T> n) {
AVLNode<T> r = n.left;
n.left = r.right;
r.right = n;
n.height = Math.max(height(n.left), height(n.right)) + 1;
r.height = Math.max(height(r.left), height(r.right)) + 1;
return r;
}
private int heightDiff(AVLNode<T> a) {
if (a == null) {
return 0;
}
return height(a.left) - height(a.right);
}
private int height(AVLNode<T> a) {
if (a == null) {
return 0;
}
return a.height;
}
}
Here's a full implementation of AVL tree in Java
class Node {
int key;
Node left;
Node right;
int height;
Node(int value) {
key = value;
left = null;
right = null;
height = 1;
}
}
class AVLTree {
Node root;
int height(Node root) {
if (root == null)
return 0;
return root.height;
}
int findHeight() {
return height(root);
}
int findHeightFrom(int value) {
Node node = search(root, value);
if (node == null)
return -1;
return node.height;
}
Node search(Node root, int value) {
if (root == null)
return null;
else {
if (value == root.key)
return root;
else if (value < root.key)
return search(root.left, value);
else
return search(root.right, value);
}
}
boolean find(int value) {
Node node = search(root,value);
if (node == null)
return false;
return true;
}
int max(int one, int two) {
return (one > two) ? one : two;
}
Node rightRotate(Node root) {
Node rootLeftChild = root.left;
root.left = rootLeftChild.right;
rootLeftChild.right = root;
root.height = max(height(root.left), height(root.right)) + 1;
rootLeftChild.height = max(height(rootLeftChild.left), height(rootLeftChild.right)) + 1;
return rootLeftChild;
}
Node leftRotate(Node root) {
Node rootRightChild = root.right;
root.right = rootRightChild.left;
rootRightChild.left = root;
root.height = max(height(root.left), height(root.right)) + 1;
rootRightChild.height = max(height(rootRightChild.left), height(rootRightChild.right)) + 1;
return rootRightChild;
}
Node insertNode(Node root, int value) {
if (root == null)
root = new Node(value);
else {
if (value < root.key)
root.left = insertNode(root.left, value);
else
root.right = insertNode(root.right, value);
}
root.height = max(height(root.left), height(root.right)) + 1;
int balanceFactor = height(root.left) - height(root.right);
if (balanceFactor > 1) {
// either left-left case or left-right case
if (value < root.left.key) {
// left-left case
root = rightRotate(root);
} else {
// left-right case
root.left = leftRotate(root.left);
root = rightRotate(root);
}
} else if (balanceFactor < -1) {
// either right-right case or right-left case
if (value > root.right.key) {
// right-right case
root = leftRotate(root);
} else {
// right-left case
root.right = rightRotate(root.right);
root = leftRotate(root);
}
}
return root;
}
void insert(int value) {
root = insertNode(root, value);
}
void inorder(Node root) {
if (root != null) {
inorder(root.left);
System.out.print(root.key + " ");
inorder(root.right);
}
}
void inorderTraversal() {
inorder(root);
System.out.println();
}
void preorder(Node root) {
if (root != null) {
System.out.print(root.key + " ");
preorder(root.left);
preorder(root.right);
}
}
void preorderTraversal() {
preorder(root);
System.out.println();
}
}
public class AVLTreeExample {
public static void main(String[] args) {
AVLTree avl = new AVLTree();
avl.insert(10);
avl.insert(20);
avl.insert(30);
avl.insert(40);
avl.insert(50);
avl.insert(25);
System.out.print("Inorder Traversal : "); avl.inorderTraversal();
System.out.print("Preorder Traversal : "); avl.preorderTraversal();
System.out.println("Searching for 10 : " + avl.find(10));
System.out.println("Searching for 11 : " + avl.find(11));
System.out.println("Searching for 20 : " + avl.find(20));
System.out.println("Height of the tree : " + avl.findHeight());
System.out.println("Finding height from 10 : " + avl.findHeightFrom(10));
System.out.println("Finding height from 20 : " + avl.findHeightFrom(20));
System.out.println("Finding height from 25 : " + avl.findHeightFrom(25));
}
}
in order to rotate it right
you need to first check if the parent is not root
then if the parent is the right of the grand parent
if so, set the right of the grand parent to the child
else, set the left of the gran parent to the child
otherwise,
root is child

Unable to implement A Star in java

I've been trying all day to get this algorithm up and running, but I cant for the life of me. I've read many tutorials on the net, and source code in AS3, javascript, and C++; but I cannot adapt what I am seeing to my own code.
I have created an AStar class that has a nested class named Node. The map is a 2D array named MAP.
The biggest problem that I am having is pulling the F value in the pathfind function.
I have implemented the F = G + H, my problem is the actual AStar algorithm. Can someone please help, this is how far I've got as of yet:
import java.util.ArrayList;
public class AStar
{
int MAP[][];
Node startNode, endNode;
public AStar(int MAP[][], int startXNode, int startYNode,
int endXNode, int endYNode)
{
this.MAP = MAP;
startNode = new Node(startXNode, startYNode);
endNode = new Node(endXNode, endYNode);
}
public void pathfinder()
{
ArrayList openList = new ArrayList();
ArrayList closedList = new ArrayList();
}
public int F(Node startNode, Node endNode)
{
return (H(startNode, endNode) + G(startNode));
}
//H or Heuristic part of A* algorithm
public int H(Node startNode, Node endNode)
{
int WEIGHT = 10;
int distance = (Math.abs(startNode.getX() - endNode.getX()) + Math.abs(startNode.getY() - endNode.getY()));
return (distance * WEIGHT);
}
public int G(Node startNode)
{
if(MAP[startNode.getX() - 1][startNode.getY()] != 1)
{
return 10;
}
if(MAP[startNode.getX() + 1][startNode.getY()] != 1)
{
return 10;
}
if(MAP[startNode.getX()][startNode.getY() -1] != 1)
{
return 10;
}
if(MAP[startNode.getX()][startNode.getY() + 1] != 1)
{
return 0;
}
return 0;
}
public class Node
{
private int NodeX;
private int NodeY;
private int gScore;
private int hScore;
private int fScore;
public Node(int NodeX, int NodeY)
{
this.NodeX = NodeX;
this.NodeY = NodeY;
}
public int getX()
{
return NodeX;
}
public int getY()
{
return NodeY;
}
public int getG()
{
return gScore;
}
public void setG(int gScore)
{
this.gScore = gScore;
}
public int getH()
{
return hScore;
}
public void setH(int hScore)
{
this.hScore = hScore;
}
public int getF()
{
return fScore;
}
public void setF(int fScore)
{
this.fScore = fScore;
}
}
}
This is the furthest I can ever get with the pathfinder function:
public void pathfinder()
{
LinkedList<Node> openList = new LinkedList();
LinkedList<Node> closedList = new LinkedList();
Node currentNode;
openList.add(startNode);
while(openList.size() > 0)
{
currentNode = (Node) openList.get(0);
closedList.add(currentNode);
for(int i = 0; i < openList.size(); i++)
{
int cost = F(currentNode, endNode);
}
}
}
I recently threw this A* code together to solve a Project Euler problem. You'll have to fill in the details for a matrix of Node objects. Use it at your own risk, however I can say it solved the problem :)
public class Node {
List<Node> neighbors = new ArrayList<Node>();
Node parent;
int f;
int g;
int h;
int x;
int y;
int cost;
}
public List<Node> aStar(Node start, Node goal) {
Set<Node> open = new HashSet<Node>();
Set<Node> closed = new HashSet<Node>();
start.g = 0;
start.h = estimateDistance(start, goal);
start.f = start.h;
open.add(start);
while (true) {
Node current = null;
if (open.size() == 0) {
throw new RuntimeException("no route");
}
for (Node node : open) {
if (current == null || node.f < current.f) {
current = node;
}
}
if (current == goal) {
break;
}
open.remove(current);
closed.add(current);
for (Node neighbor : current.neighbors) {
if (neighbor == null) {
continue;
}
int nextG = current.g + neighbor.cost;
if (nextG < neighbor.g) {
open.remove(neighbor);
closed.remove(neighbor);
}
if (!open.contains(neighbor) && !closed.contains(neighbor)) {
neighbor.g = nextG;
neighbor.h = estimateDistance(neighbor, goal);
neighbor.f = neighbor.g + neighbor.h;
neighbor.parent = current;
open.add(neighbor);
}
}
}
List<Node> nodes = new ArrayList<Node>();
Node current = goal;
while (current.parent != null) {
nodes.add(current);
current = current.parent;
}
nodes.add(start);
return nodes;
}
public int estimateDistance(Node node1, Node node2) {
return Math.abs(node1.x - node2.x) + Math.abs(node1.y - node2.y);
}
I dont know if you are trying only to use simple types, or if you just didn't think about it, but you need to have a PriorityQueue to get your A* working.
A good way to think is that you put your startpoint into a priority queue with distance 0, and then start a loop that only stops when the prioriy queue is empty.
In the loop you take the min-node out, and check to see if it hasnt been open before, or if it has, if you have now found a shorter way to it.
If either these are true, you add the distance to the new node, add the edge/from-square to a map, and then add the distance + heuristic to the priority queue.
I have written this to work on a grid of booleans, and a constant conversion between 1D and 2D arrays, but I hope it is readable:
public void AStarRoute()
{
gridDist = new double[rows][cols];
System.out.println("Start of AStarRoute");
MinPriorityQueue pq = new MinPriorityQueue(rows * cols);
edgeTo = new HashMap<Integer, Integer>();
gridDist[x1Dto2D(start)][y1Dto2D(start)] = 0;
pq.insert(start, 0);
int from;
while (!pq.isEmpty()) {
from = pq.delMin();
int x = x1Dto2D(from);
int y = y1Dto2D(from);
for (int i = -1; i <= 1; i++) {
for (int j = -1; j <= 1; j++) {
int newX = x + i;
int newY = y + j;
if (newX >= 0 && newY >= 0 && newX < cols && newY < rows && !(i == 0 && j == 0)) {
if (grid[newX][newY]) {
//System.out.println("NewDist: " + gridDist[newX][newY] + " - OldDist+dist: " + (gridDist[x][y] + ((Math.abs(i) == Math.abs(j)) ? 1.4 : 1.0)) + ":" + (int)(gridDist[x][y] + ((Math.abs(i) == Math.abs(j)) ? 1.4 : 1.0)));
if (!edgeTo.containsKey(convert2Dto1D(newX, newY)) || gridDist[newX][newY] > (gridDist[x][y] + ((Math.abs(i) == Math.abs(j)) ? 14 : 10))) {
gridDist[newX][newY] = (int)(gridDist[x][y] + ((Math.abs(i) == Math.abs(j)) ? 14 : 10));
maxDistToEnd = (int)Math.max(maxDistToEnd, gridDist[newX][newY]);
edgeTo.put(convert2Dto1D(newX, newY), convert2Dto1D(x, y));
pq.insert(convert2Dto1D(newX, newY), gridDist[newX][newY] + (int)Math.sqrt(Math.pow((newX - x1Dto2D(end))*10, 2) + Math.pow((newY - y1Dto2D(end))*10, 2)));
if(convert2Dto1D(newX, newY) == end){
System.out.println("End found at (" + newX + ", " + newY + ")");
paintGridDist = true;
route = new ArrayList<Integer>();
int n = convert2Dto1D(newX, newY);
route.add(n);
do{
n = edgeTo.get(n);
route.add(n);
}while(start != n);
repaint();
return;
}
}
}
}
}
}
}
paintGridDist = true;
repaint();
}

Categories