Depth First Traversal and Adj Matrix - java

I'm trying to do a depth first traversal. I have no idea if I'm even close. Right now it's printing 1 3 4 5. It should be printing 1 2 4 7 3 5 6. Any help or advice is appreciated. Thanks. :)
Class:
public class myGraphs {
Stack<Integer> st;
int vFirst;
int[][] adjMatrix;
int[] isVisited = new int[7];
public myGraphs(int[][] Matrix) {
this.adjMatrix = Matrix;
st = new Stack<Integer>();
int i;
int[] node = {1, 2, 3, 4, 5, 6, 7};
int firstNode = node[0];
for (i = 1; i < node.length - 1; i++) {
depthFirst(firstNode, node[i]);
}
}
public void depthFirst(int vFirst, int n) {
int v, i;
st.push(vFirst);
while (!st.isEmpty()) {
v = st.pop();
if (isVisited[v]==0) {
System.out.print("\n"+v);
isVisited[v]=1;
}
for ( i=1;i<=n;i++) {
if ((adjMatrix[v][i] == 1) && (isVisited[i] == 0)) {
st.push(v);
isVisited[i]=1;
System.out.print(" " + i);
v = 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);
}
}

If you are looking at Depth First Traversal then following is the code changes you should make
1) First declare your node array as int[] node = {0, 1, 2, 3, 4, 5, 6}. This should be done to avoid array index start (which is 0 ) and your node start number (which is 1). SO here now we assume that new names of your node 1 is 0, node 2 is 1......and node 7 is 6.
2) Instead of doing
for (i = 1; i < node.length-1; i++){
depthFirst(firstNode, node[i]);
}
in myGraphs do :
depthFirst(firstNode, 7);
3)In depthFirst instead of for ( i=1;i<=n;i++) use for ( i=0;i<n;i++) While doing System.out.println in function depthFirst add one to the number as 0 represents node 1, 1 represents node 2 and so on.
Below is your fully functional code I modified :
import java.util.Stack;
public class DFS {
Stack<Integer> st;
int vFirst;
int[][] adjMatrix;
int[] isVisited = new int[7];
/**
* #param args
*/
public static void main(String[] args) {
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 DFS(adjMatrix);
}
public DFS(int[][] Matrix) {
this.adjMatrix = Matrix;
st = new Stack<Integer>();
int i;
int[] node = {0, 1, 2, 3, 4, 5, 6};
int firstNode = node[0];
depthFirst(firstNode, 7);
}
public void depthFirst(int vFirst,int n)
{
int v,i;
st.push(vFirst);
while(!st.isEmpty())
{
v = st.pop();
if(isVisited[v]==0)
{
System.out.print("\n"+(v+1));
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+1));
v = i;
}
}
}
}}

A working/tested solution in C#, if someone looking for it.
using System;
using System.Collections.Generic;
namespace GraphAdjMatrixDemo
{
public class Program
{
public static void Main(string[] args)
{
// 0 1 2 3 4 5 6
int[,] matrix = { {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} };
bool[] visitMatrix = new bool[matrix.GetLength(0)];
Program ghDemo = new Program();
for (int lpRCnt = 0; lpRCnt < matrix.GetLength(0); lpRCnt++)
{
for (int lpCCnt = 0; lpCCnt < matrix.GetLength(1); lpCCnt++)
{
Console.Write(string.Format(" {0} ", matrix[lpRCnt, lpCCnt]));
}
Console.WriteLine();
}
Console.Write("\nDFS Recursive : ");
ghDemo.DftRecursive(matrix, visitMatrix, 0);
Console.Write("\nDFS Iterative : ");
ghDemo.DftIterative(matrix, 0);
Console.Read();
}
//====================================================================================================================================
public void DftRecursive(int[,] srcMatrix, bool[] visitMatrix, int vertex)
{
visitMatrix[vertex] = true;
Console.Write(vertex + 1 + " ");
for (int neighbour = 0; neighbour < srcMatrix.GetLength(0); neighbour++)
{
if (visitMatrix[neighbour] == false && srcMatrix[vertex, neighbour] == 1)
{
DftRecursive(srcMatrix, visitMatrix, neighbour);
}
}
}
public void DftIterative(int[,] srcMatrix, int srcVertex)
{
bool[] visited = new bool[srcMatrix.GetLength(0)];
Stack<int> vertexStack = new Stack<int>();
vertexStack.Push(srcVertex);
while (vertexStack.Count > 0)
{
int vertex = vertexStack.Pop();
if (visited[vertex] == true)
continue;
Console.Write(vertex + 1 + " ");
visited[vertex] = true;
for (int neighbour = 0; neighbour < srcMatrix.GetLength(0); neighbour++)
//for (int neighbour = srcMatrix.GetLength(0) - 1; neighbour >= 0; neighbour--)// To make same as recursive
{
if (srcMatrix[vertex, neighbour] == 1 && visited[neighbour] == false)
{
vertexStack.Push(neighbour);
}
}
}
}
}
}
To make display order of iterative same as recursion, we need to push neighbors in reverse order to stack. Took this logic from Amit answer here

Related

Breadth First Search from scratch in Java

I wrote a java-code to find the path in an 2d array. The array is filled with 0=valid node and 1=obstacle. The code runs perfetcly with small 2d arrays for example with the size of int [][] obstacleMap=new int[10][11];
When I increase the size of the array (e.g. int[][] obstacleMap =[600][300];) now the code doesn't work anymore, I get not an Error. I have tested a lot of times my code, I think the problem is the while loop within the findpath function (code below)
My code has following functions:
main: to test the other functions
2.findPath: find path with given map from start position to target position
3.addNeighbour: add neighbour
Following classes:
Node : x and y coordinates and distance to start
pathCoordinates: x and y values for path
The Code is here:
package strategyRobot;
//import java.awt.datatransfer.SystemFlavorMap;
import java.util.ArrayDeque;
import java.util.HashSet;
import java.util.Queue;
import java.util.Set;
import java.util.LinkedList;
import java.util.List;
public class strategyRobotClass {
static Set<String> visitedNodes = new HashSet<>();
public static void main(String[] args) {
int[][] randomMap={
{ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
{ 0, 0, 1, 1, 1, 1, 1, 1, 1, 1 },
{ 1, 0, 1, 1, 1, 1, 0, 1, 1, 1 },
{ 1, 0, 0, 0, 1, 1, 0 ,1, 1, 1 },
{ 1, 1, 1, 0, 1, 1, 0, 1, 1, 1 },
{ 1, 1, 1, 0, 1, 1, 0, 1, 1, 1 },
{ 1, 1, 1, 0, 0, 0, 0, 1, 1, 1 },
{ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
};
int value = randomMap[2][6];
System.out.printf("value = %d", value);
System.out.println(" ");
LinkedList<pathCoordinates> pathMap= findPath(randomMap,0,0,3,6);
for(int i = 0; i<pathMap.size();i++) {
System.out.printf("(%d,%d) %n",pathMap.get(i).x,pathMap.get(i).y);
}
}
static public LinkedList<pathCoordinates> findPath(int map[][], int xStartPos, int yStartPos, int xTargetPos, int yTargetPos) {
LinkedList<pathCoordinates> pathMap = new LinkedList<pathCoordinates>();
Node source = new Node(xStartPos, yStartPos,0);
Queue<Node> queue= new LinkedList<Node>();
queue.add(source);
while(!queue.isEmpty()) { // IS THE BUG HERE ????
Node poped = queue.poll();
if(poped.x == xTargetPos && poped.y ==yTargetPos) {
return pathMap;
}
else {
map[poped.x][poped.y] = 1 ;
pathCoordinates coordinates = new pathCoordinates(poped.x,poped.y);
pathMap.add(coordinates);
List<Node> neighbourList = addNeighbours(poped,map);
queue.addAll(neighbourList);
}
}
return null;
}
static public List addNeighbours(Node poped, int[][] map) {
List<Node> list=new LinkedList<Node>();
if((poped.x-1 >0 && poped.x-1<map.length) && (map[poped.x-1][poped.y]== 0)) {
list.add(new Node(poped.x-1, poped.y, poped.distanceFromStart+1));
}
if((poped.x+1 >0 && poped.x+1<map.length) && (map[poped.x+1][poped.y]== 0)) {
list.add(new Node(poped.x+1, poped.y, poped.distanceFromStart+1));
}
if((poped.y-1 >0 && poped.y-1<map.length) && (map[poped.x][poped.y-1]== 0)) {
list.add(new Node(poped.x-1, poped.y, poped.distanceFromStart+1));
}
if((poped.y+1 >0 && poped.y+1<map.length) && (map[poped.x][poped.y+1]== 0)) {
list.add(new Node(poped.x, poped.y+1, poped.distanceFromStart+1));
}
return list;
}
static public class Node{
int x, y; //coordinates in a cell
int distanceFromStart;
Node parent;
Node(int x, int y, int distanceFromStart){
this.x=x;
this.y=y;
this.distanceFromStart=distanceFromStart;
}
}
static public class pathCoordinates {
int x,y;
pathCoordinates(int x, int y){
this.x=x;
this.y=y;
}
}

Setting a specific element in a 2d array to a random value

I am looking to set a random value to a certain element in a 2d array.
In my assignment I have to assign a random number 1-5 for the first element in the 2d array and then go the the next row and do the same thing. This is what I have so far but it does not look right.
double CURRENT_BOARD [5][5] = {{0, 0, 0, 0, 0},
{0, 0, 0, 0, 0},
{0, 0, 0, 0, 0},
{0, 0, 0, 0, 0},
{0, 0, 0, 0, 0}};
public double shuffleBoard (double currentBoard) {
Random rand = new Random();
shuffledBoard [][] = new double [5][5];
for (i=0 ;i<5 ;i++) {
j = rand.nextInt(5) + 1;
shuffledBoard = shuffledBoard [j][0];
}
return shuffleBoard;
}//shuffleBoard
My end goal is that the elements of the array will look something like
{5, 0, 0, 0, 0}
{3, 0, 0, 0, 0}
{4, 0, 0, 0, 0} and so on as long as the first element of the array is selected at random. Can anyone offer any help to make this happen?
Your declaration of a 2D double array is not correct.
Take a look at this StackOverflow answer
Declaration should be like
double[][] CURRENT_BOARD = new double[][]{{0, 0, 0, 0, 0},
{0, 0, 0, 0, 0},
{0, 0, 0, 0, 0},
{0, 0, 0, 0, 0},
{0, 0, 0, 0, 0}};
For random number part, you can try this
public double[][] shuffleBoard(double[][] currentBoard) {
double[][] shuffledBoard = currentBoard;
Random rand = new Random();
double rangeMin = 1, rangeMax = 5;
for (int i = 0; i < 5; i++) {
double j = rangeMin + (rangeMax - rangeMin) * rand.nextDouble();
shuffledBoard[i][0] = j;
}
return shuffledBoard;
}

Java Array change value for half of half etc

So I have a method that takes in a size of an array. My method makes half the array 0's.
int [] arrary2 = new int[arraySize];
for(int i = 0; i < arraySize/2; i++){
arr2[i] = 0;
}
//do rest of code?
return array2;
How do I make the half of the last half my array into 1's and so on.
For example an array of size 14, but the array size could be any size?
[0,0,0,0,0,0,0,1,1,1,1,2,2,3]
Rough algorithm:
Calculate half what's left to do (be careful with odd / even)
Fill that with the current value
Repeat
Sample code:
public static int[] createArray(int size)
{
int[] array = new int[size];
int half = (size / 2) + (size % 2);
int index = half;
int value = 0;
for (int i = 0; i < size; i++) {
if (i == index) {
half = (half / 2) + (half % 2);
index += half;
value++;
}
array[i] = value;
}
return array;
}
Sample output:
15 => 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 3
14 => 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 3
Here's one way:
import java.util.Arrays;
public class Main {
static int[] createArray(int size) {
int[] result = new int[size];
int limit = (size + 1) / 2;
int start = 0, value = 0, idx = 0;
do {
for (int i = start; i < start + limit && idx < size; ++i)
result[idx++] = value;
start += limit;
limit = (limit + 1) / 2;
++value;
} while (idx < size);
return result;
}
public static void main(String[] args) {
int[] result = createArray(70);
System.out.println(Arrays.toString(result));
}
}
A couple of tests:
14 => [0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 3]
70 => [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 4, 4, 4]
To do this keep track of where you want the input value to change, the input value and also how many inserts you want to perform until the next change.
int[] arrary2 = new int[arraySize];
int currentEndPoint = (arraySize / 2) + (arraySize % 2);
int endPointIncrement = currentEndPoint;
int currentInputValue = 0;
for (int i = 0; i < arraySize; i++)
{
if (i == currentEndPoint - 1)
{
currentInputValue++;
endPointIncrement = (endPointIncrement / 2) + (endPointIncrement % 2);
currentEndPoint = currentEndPoint + endPointIncrement;
}
arrary2[i] = currentInputValue;
}
return arrary2;
Hope this helps

Checking for number repetition in a line or column in a grid

I have to make a Sudoku board and have the grid but am confused as how to check for any repetitions across a line or column. The code for my grid is.
for (int i = 0; i < 9; i++) {
for (int j = 0; j < 9; j++) {
grid[i][j] = new JTextField();
BoardPanel.add(grid[i][j]);
So basically i want to check for repetition across i and then down j
Here is the code with an example to show it.
This program will tell if there are two equal numbers in vertical and horizontal bars.
public static void main(String args[]) {
// store your puzzle in puzzle variable.
int puzzle[][] = {
{0, 9, 0, 0, 0, 0, 0, 0, 8},
{0, 0, 3, 2, 0, 7, 0, 9, 0},
{0, 6, 0, 0, 0, 0, 7, 0, 0},
{0, 0, 0, 0, 0, 1, 0, 0, 6},
{0, 0, 5, 4, 3, 2, 1, 0, 0},
{4, 0, 0, 7, 0, 0, 0, 0, 0},
{0, 0, 7, 0, 0, 0, 0, 3, 0},
{0, 2, 0, 9, 0, 8, 6, 0, 0},
{1, 0, 0, 0, 0, 0, 0, 4, 0}
};
testHorizontal(puzzle);
testVertical(puzzle);
}
public static void testHorizontal(int[][] puzzle) {
for (int[] arr : puzzle) {
test(arr);
}
}
public static void testVertical(int[][] puzzle) {
int[] cols = new int[puzzle.length];
for (int i = 0; i < puzzle.length; i++) {
for (int j = 0; j < puzzle.length; j++) {
cols[j] = puzzle[i][j];
test(cols);
}
}
}
public static boolean test(int arr[]) {
boolean flag = false;
for (int a : arr) {
for (int b : arr) {
if (a == b) {
flag = true;
System.out.println("equal numbers found.");
break;
}
}
}
return flag;
}

A* infinite loop

I'm trying to implement an A* algorithm for a pathfinding problem.
It works, like 9 out of 10 times, but at some points I get a (possibly) infinite loop, and the program doesn't find the optimal path. Can you see why it happens?
A*:
import java.util.*;
public abstract class AStar<T>
{
private class Path implements Comparable{
public T point;
public Double f;
public Double g;
public Path parent;
public Path(){
parent = null;
point = null;
g = f = 0.0;
}
public Path(Path p){
this();
parent = p;
g = p.g;
f = p.f;
}
public int compareTo(Object o){
Path p = (Path)o;
return (int)(f - p.f);
}
public T getPoint(){
return point;
}
public void setPoint(T p){
point = p;
}
}
protected abstract boolean isGoal(T node);
protected abstract Double g(T from, T to);
protected abstract Double h(T from, T to);
protected abstract List<T> generateSuccessors(T node);
private PriorityQueue<Path> paths;
private HashMap<T, Double> mindists;
private Double lastCost;
private int expandedCounter;
public int getExpandedCounter(){
return expandedCounter;
}
public AStar(){
paths = new PriorityQueue<Path>();
mindists = new HashMap<T, Double>();
expandedCounter = 0;
lastCost = 0.0;
}
protected Double f(Path p, T from, T to){
Double g = g(from, to) + ((p.parent != null) ? p.parent.g : 0.0);
Double h = h(from, to);
p.g = g;
p.f = g + h;
return p.f;
}
private void expand(Path path){
T p = path.getPoint();
Double min = mindists.get(path.getPoint());
if(min == null || min.doubleValue() > path.f.doubleValue())
mindists.put(path.getPoint(), path.f);
else
return;
List<T> successors = generateSuccessors(p);
for(T t : successors){
Path newPath = new Path(path);
newPath.setPoint(t);
f(newPath, path.getPoint(), t);
paths.offer(newPath);
}
expandedCounter++;
}
public Double getCost(){
return lastCost;
}
public List<T> compute(T start){
try{
Path root = new Path();
root.setPoint(start);
/* Needed if the initial point has a cost. */
f(root, start, start);
expand(root);
for(;;){
Path p = paths.poll();
if(p == null){
lastCost = Double.MAX_VALUE;
return null;
}
T last = p.getPoint();
lastCost = p.g;
if(isGoal(last)){
LinkedList<T> retPath = new LinkedList<T>();
for(Path i = p; i != null; i = i.parent){
retPath.addFirst(i.getPoint());
}
return retPath;
}
expand(p);
}
}
catch(Exception e){
e.printStackTrace();
}
return null;
}
}
And the pathfinding class with the main:
import java.util.*;
public class PathFinder extends AStar<PathFinder.Node>
{
private int[][] map;
private int endx;
private int endy;
public static class Node{
public int x;
public int y;
Node(int x, int y){
this.x = x;
this.y = y;
}
public String toString(){
return "(" + x + ", " + y + ") ";
}
public int getX(){
return x;
}
public int getY(){
return y;
}
} public PathFinder(int[][] map, int endx, int endy){
this.map = map;
this.endx=endx;
this.endy=endy;
}
protected boolean isGoal(Node node){
return (node.x == endx) && (node.y == endy);
}
protected Double g(Node from, Node to){
if(from.x == to.x && from.y == to.y){
// System.out.println("To x1 " + to.x);
// System.out.println("To y1 " + to.y);
return 0.0;}
if(map[to.y][to.x] == 1){
//System.out.println("To x2 " + to.x);
// System.out.println("To y2 " + to.y);
return 1.0;}
return Double.MAX_VALUE;
}
protected Double h(Node from, Node to){
return new Double(Math.abs(endx - to.x) + Math.abs(endy - to.y));
}
protected List<Node> generateSuccessors(Node node){
List<Node> ret = new LinkedList<Node>();
int x = node.x;
int y = node.y;
if(y < map[0].length-1 && map[y+1][x] == 1)
ret.add(new Node(x, y+1));
if(x <map.length-1 && map[y][x+1] == 1)
ret.add(new Node(x+1, y));
if(y !=0 && map[y-1][x] == 1)
ret.add(new Node(x, y-1));
if(x !=0 && map[y][x-1] == 1)
ret.add(new Node(x-1, y));
return ret;
}
public static void main(String [] args){
WorldGenerator gen = new WorldGenerator();
int ammountOfBlocks =200;
int width = 25;
int length = 25;
int startX = 1;
int startY = 1;
int endX = 24;
int endY = 24;
int[][] map = gen.createWorld(ammountOfBlocks,width,length,startX,startY,endX,endY);
int a=map.length;
int b=map[0].length;
int[][] map2=new int[b][a];
for(int i=0; i<map.length; i++){
for(int j=0; j<map[0].length;j++)
{map2[j][i]=map[i][j];
}
}
PathFinder pf = new PathFinder(map,endX,endY);
/* for(int i = 0; i < map.length; i++){
for(int j = 0; j < map[0].length; j++)
System.out.print(map[i][j] + " ");
System.out.println();
}*/
long begin = System.currentTimeMillis();
List<Node> nodes = pf.compute(new PathFinder.Node(startX,startY));
long end = System.currentTimeMillis();
System.out.println("Time = " + (end - begin) + " ms" );
//System.out.println("Expanded = " + pf.getExpandedCounter());
System.out.println("Cost = " + pf.getCost());
if(nodes == null)
System.out.println("No path");
else{
for(int i=0; i<nodes.size();i++){
Node n=nodes.get(i);
int x= n.getX();
int y= n.getY();
map[x][y]=4;
}
/* for(int i = 0; i < map.length; i++){
for(int j = 0; j < map[0].length; j++)
System.out.print(map[i][j] + " ");
System.out.println();
}*/
}
}
}
the WorldGenerator class only generates a 2 dimensional array of 1s and 0s.
Thanks in advance!
Shooting from my hip here, but if you want to use a 'direct line distance' as your heuristic you have a bug in your code.
The current heuristic is: The node with the smallest sum of delta x and y is closest.
Let's say we have a five x five grid and the target is in 2,2 then using this heuristic 2,0 would be equally optimal as 1,1 which of course is wrong.
Try using Pythagoras for a new heuristic: The node with the shortest distance to the end is the closest.
protected Double h(Node from, Node to) {
int dx = Math.abs(endx - to.x);
int dy = Math.abs(endy - to.y);
return new Double(Math.sqrt(dx*dx) + (dy*dy));
}
This would make your algorithm use an http://en.wikipedia.org/wiki/Admissible_heuristic which is a criteria for A*: http://en.wikipedia.org/wiki/A_star#Admissibility_and_optimality
Hope this helps.
A solution that works for me:
AStar.java
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.PriorityQueue;
public abstract class AStar<T> {
private class Path<T> implements Comparable {
public T point;
public Double f;
public Double g;
public Path<T> parent;
public Path() {
parent = null;
point = null;
g = f = 0.0;
}
public Path(Path<T> p) {
this();
parent = p;
g = p.g;
f = p.f;
}
#Override
public int compareTo(Object o) {
AStar.Path p = (AStar.Path) o;
return (int) (f - p.f);
}
public T getPoint() {
return point;
}
public void setPoint(T p) {
point = p;
}
}
protected abstract boolean isGoal(T node);
protected abstract Double g(T from, T to);
protected abstract Double h(T from, T to);
protected abstract List<T> generateSuccessors(T node, T parent);
private PriorityQueue<AStar.Path> paths;
private HashMap<T, Double> mindists;
private Double lastCost;
private int expandedCounter;
public int getExpandedCounter() {
return expandedCounter;
}
public AStar() {
paths = new PriorityQueue<>();
mindists = new HashMap<>();
expandedCounter = 0;
lastCost = 0.0;
}
protected Double f(AStar.Path p, T from, T to) {
Double g = g(from, to) + ((p.parent != null) ? p.parent.g : 0.0);
Double h = h(from, to);
p.g = g;
p.f = g + h;
return p.f;
}
private void expand(Path<T> path) {
if (expandedCounter > 1000000) {
return;
}
T p = path.getPoint();
Double min = mindists.get(path.getPoint());
if (min == null || min.doubleValue() > path.f.doubleValue()) {
mindists.put(path.getPoint(), path.f);
} else {
return;
}
List<T> successors = generateSuccessors(p, path.parent != null ? path.parent.getPoint() : null);
for (T t : successors) {
AStar.Path newPath = new AStar.Path(path);
newPath.setPoint(t);
f(newPath, path.getPoint(), t);
paths.offer(newPath);
}
expandedCounter++;
}
public Double getCost() {
return lastCost;
}
public List<T> compute(T start) {
try {
AStar.Path root = new AStar.Path();
root.setPoint(start);
/*
* Needed if the initial point has a cost.
*/
f(root, start, start);
expand(root);
for (;;) {
Path<T> p = paths.poll();
if (p == null) {
lastCost = Double.MAX_VALUE;
return null;
}
T last = p.getPoint();
lastCost = p.g;
if (isGoal(last)) {
LinkedList<T> retPath = new LinkedList<T>();
for (Path<T> i = p; i != null; i = i.parent) {
retPath.addFirst(i.getPoint());
}
return retPath;
}
expand(p);
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
PathFinder.java
package playground;
import java.util.*;
public class PathFinder extends AStar<PathFinder.Node> {
private int[][] map;
private int endx;
private int endy;
public static class Node {
public int x;
public int y;
Node(int x, int y) {
this.x = x;
this.y = y;
}
public String toString() {
return "(" + x + ", " + y + ") ";
}
public int getX() {
return x;
}
public int getY() {
return y;
}
}
public PathFinder(int[][] map, int endx, int endy) {
this.map = map;
this.endx = endx;
this.endy = endy;
}
protected boolean isGoal(Node node) {
return (node.x == endx) && (node.y == endy);
}
protected Double g(Node from, Node to) {
if (from.x == to.x && from.y == to.y) {
// System.out.println("To x1 " + to.x);
// System.out.println("To y1 " + to.y);
return 0.0;
}
if (map[to.y][to.x] == 1) {
//System.out.println("To x2 " + to.x);
// System.out.println("To y2 " + to.y);
return 1.0;
}
return Double.MAX_VALUE;
}
protected Double h(Node from, Node to) {
int dx = Math.abs(endx - to.x);
int dy = Math.abs(endy - to.y);
return new Double(Math.sqrt(dx * dx) + (dy * dy));
//return new Double(Math.abs(endx - to.x) + Math.abs(endy - to.y));
}
#Override
protected List<Node> generateSuccessors(Node node, Node parent) {
List<Node> ret = new LinkedList<Node>();
int x = node.x;
int y = node.y;
if (y < map[0].length - 1 && map[y + 1][x] == 1 && (parent == null || (parent != null && !(parent.x == x && parent.y == y + 1)))) {
ret.add(new Node(x, y + 1));
}
if (x < map.length - 1 && map[y][x + 1] == 1 && (parent == null || (parent != null && !(parent.x == x + 1 && parent.y == y)))) {
ret.add(new Node(x + 1, y));
}
if (y != 0 && map[y - 1][x] == 1 && (parent == null || (parent != null && !(parent.x == x && parent.y == y - 1)))) {
ret.add(new Node(x, y - 1));
}
if (x != 0 && map[y][x - 1] == 1 && (parent == null || (parent != null && !(parent.x == x - 1 && parent.y == y)))) {
ret.add(new Node(x - 1, y));
}
return ret;
}
public static void main(String[] args) {
int ammountOfBlocks = 200;
int width = 25;
int length = 25;
int startX = 1;
int startY = 1;
int endX = 24;
int endY = 24;
int[][] map = {
{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1},
{1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
{1, 0, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1},
{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1},
{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1},
{1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
{1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1},
{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1},
{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1},
{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1},
{1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1},
{1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1},
{1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1},
{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1},
{0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1},
{1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
{1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1},
{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0},
{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1}
};
int a = map.length;
int b = map[0].length;
int[][] map2 = new int[b][a];
for (int i = 0; i < map.length; i++) {
for (int j = 0; j < map[0].length; j++) {
map2[j][i] = map[i][j];
}
}
PathFinder pf = new PathFinder(map, endX, endY);
/*
* for(int i = 0; i < map.length; i++){ for(int j = 0; j <
* map[0].length; j++) System.out.print(map[i][j] + " ");
* System.out.println(); }
*/
long begin = System.currentTimeMillis();
List<Node> nodes = pf.compute(new PathFinder.Node(startX, startY));
long end = System.currentTimeMillis();
System.out.println("Time = " + (end - begin) + " ms");
//System.out.println("Expanded = " + pf.getExpandedCounter());
System.out.println("Cost = " + pf.getCost());
if (nodes == null) {
System.out.println("No path");
} else {
for (int i = 0; i < nodes.size(); i++) {
Node n = nodes.get(i);
int x = n.getX();
int y = n.getY();
map[x][y] = 4;
}
for(int i = 0; i < map.length; i++){
for(int j = 0; j < map[0].length; j++)
System.out.print(map[i][j] + " ");
System.out.println();
}
}
}
}

Categories