A* nosolution issue - java

I have a question according to A*-Algorithm, which I have implemented in Java.
So, I have a grid of nodes with randomly generated obstacles and a Player, who can walk over the grid.
But I got a Problem. If I click on an obstacle no path is generated, but this is exactly what I want to. So I want to generate the best path the Point I click on to especially to an obstacle.
My idea is to take a boolean flag, but I never get my Problem solved. Maybe some of u guys see the Problem.
Heres the A*-Method:
public List<Node> findPath(int startx,int starty,int endx,int endy){
for(int i = 0;i<cols;i++){
for(int j = 0;j<rows;j++){
grid[i][j] = new Node(i,j,obstacles[i][j]);
}
}
for(int i = 0;i<cols;i++){
for(int j = 0;j<rows;j++){
grid[i][j].addNeighbours(grid);
}
}
List<Node> openList = new ArrayList<Node>();
List<Node> closedList = new ArrayList<Node>();
Node start = grid[startx][starty];
Node end = grid[endx][endy];
openList.add(start);
while(openList.size() > 0){
int winner = 0;
for(int i = 0;i <openList.size();i++){
if(openList.get(i).f < openList.get(winner).f){
winner = i;
}
}
Node current = openList.get(winner);
openList.remove(current);
closedList.add(current);
if(nosolution==false){
if(current == end){
List<Node> path = new ArrayList<Node>();
Node tmp = current;
path.add(tmp);
while(tmp.previous!=null){
path.add(tmp);
tmp = tmp.previous;
}
openList.clear();
closedList.clear();
Collections.reverse(path);
return path;
}
}else{
nosolution=true;
}
List<Node> neighbours = current.neighbours;
for(int i = 0;i<neighbours.size();i++){
Node neighbour = neighbours.get(i);
if(!closedList.contains(neighbour) && !neighbour.obstacle){
int tempG = current.g + 1;
boolean newPath = false;
if(openList.contains(neighbour)){
if(tempG < neighbour.g){
neighbour.g = tempG;
newPath = true;
}
}
else{
neighbour.g = tempG;
newPath = true;
openList.add(neighbour);
}
if(newPath){
neighbour.h = heuristic(neighbour,end);
neighbour.f = neighbour.g + neighbour.h;
neighbour.previous = current;
}
}
}
}
return null;
}

Here the Node class:
public class Node{
public int x;
public int y;
public int g;
public int h;
public int f;
public List<Node> neighbours;
public Node previous;
public boolean obstacle;
public Node(int x,int y,boolean obstacle) {
this.x = x;
this.y = y;
this.g = 0;
this.h = 0;
this.f = 0;
this.previous = null;
this.obstacle = obstacle;
this.neighbours = new ArrayList<Node>();
}
public List<Node> addNeighbours(Node[][] grid){
int x = this.x;
int y = this.y;
if(x < 25 - 1){
neighbours.add(grid[x+1][y]);
}
if(x > 0){
neighbours.add(grid[x-1][y]);
}
if(y < 20 - 1){
neighbours.add(grid[x][y+1]);
}
if(y > 0){
neighbours.add(grid[x][y-1]);
}
return neighbours;
}

When no solution is found, and you still want to know the best solution that got closest to your destination, then look at the closedList and pick the Node with the smallest distance to the destination.
For a better answer, provide the code to Node as well if you need more help.
Update
Node has the x and y. Look through all the closed nodes, find the one closest to the target. Then construct a path using the previous field.
Since there might be many closed nodes, you may want to adjust the algorithm a bit to keep track of the closest node instead, and return that path when no solution exists.

public ArrayList findPath(int startx,int starty,int endx,int endy){
List<Node> openList = new ArrayList<Node>();
List<Node> closedList = new ArrayList<Node>();
Node start = grid[startx][starty];
Node end = grid[endx][endy];
Node closest = start;
openList.add(start);
while(!openList.isEmpty()){
int winner = 0;
for(int i = 0;i <openList.size();i++){
if(openList.get(i).f < openList.get(winner).f){
winner = i;
}
}
Node current = openList.get(winner);
openList.remove(current);
closedList.add(current);
if(current == end){
path = new ArrayList<Node>();
Node tmp = current;
path.add(tmp);
while(tmp.previous!=null){
path.add(tmp);
tmp = tmp.previous;
}
return path;
}
List<Node> neighbours = current.neighbours;
for(int i = 0;i<neighbours.size();i++){
Node neighbour = neighbours.get(i);
int cost = current.g + heuristic(current,neighbour);
if(openList.contains(neighbour) && cost < neighbour.g){
openList.remove(neighbour);
}
if(closedList.contains(neighbour) && cost < neighbour.g){
closedList.remove(neighbour);
}
if(openList.contains(neighbour) == false && closedList.contains(neighbour) == false && neighbour.obstacle == false){
neighbour.g = cost;
int newcost = heuristic(closest,end);
closest.h = newcost;
if(neighbour.h < closest.h){
closest = neighbour;
}
openList.add(neighbour);
neighbour.f = neighbour.g + neighbour.h;
neighbour.previous = current;
}
}
}
if(closest!=end){
path = new ArrayList<Node>();
Node tmp = closest;
path.add(tmp);
while(tmp.previous!=null){
path.add(tmp);
tmp = tmp.previous;
}
}
return path;
}

Related

Dijkstras algorithm shortest path in directed graph, find the last node taken to destination vertex

The code below was taken from https://algorithms.tutorialhorizon.com/dijkstras-shortest-path-algorithm-spt-adjacency-list-and-min-heap-java-implementation/
it finds the shortest distance to each vertex from a given source vertex but does not as of yet offer a way to track the path taken. Is there an easy fix to this? if not how should i approach this?
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.LinkedList;
import java.util.StringTokenizer;
public class DijkstraMinHeap {
static class Edge {
int source;
int destination;
int weight;
public Edge(int source, int destination, int weight) {
this.source = source;
this.destination = destination;
this.weight = weight;
}
}
static class HeapNode{
int vertex;
int distance;
}
static class Graph {
int vertices;
LinkedList<Edge>[] adjacencylist;
Graph(int vertices) {
this.vertices = vertices;
adjacencylist = new LinkedList[vertices];
for (int i = 0; i <vertices ; i++) {
adjacencylist[i] = new LinkedList<>();
}
}
public void addEdge(int source, int destination, int weight) {
Edge edge = new Edge(source, destination, weight);
adjacencylist[source].addFirst(edge);
/**edge = new Edge(destination, source, weight);
adjacencylist[destination].addFirst(edge); //for undirected graph*/
}
public void dijkstra_GetMinDistances(int sourceVertex){
int INFINITY = Integer.MAX_VALUE;
boolean[] SPT = new boolean[vertices];
// //create heapNode for all the vertices
HeapNode [] heapNodes = new HeapNode[vertices];
for (int i = 0; i <vertices ; i++) {
heapNodes[i] = new HeapNode();
heapNodes[i].vertex = i;
heapNodes[i].distance = INFINITY;
}
//decrease the distance for the first index
heapNodes[sourceVertex].distance = 0;
//add all the vertices to the DijkstraMinHeap.MinHeap
MinHeap minHeap = new MinHeap(vertices);
for (int i = 0; i <vertices ; i++) {
minHeap.insert(heapNodes[i]);
}
//while minHeap is not empty
while(!minHeap.isEmpty()){
//extract the min
HeapNode extractedNode = minHeap.extractMin();
//extracted vertex
int extractedVertex = extractedNode.vertex;
SPT[extractedVertex] = true;
//iterate through all the adjacent vertices
LinkedList<Edge> list = adjacencylist[extractedVertex];
for (int i = 0; i <list.size() ; i++) {
Edge edge = list.get(i);
int destination = edge.destination;
//only if destination vertex is not present in SPT
if(SPT[destination]==false ) {
///check if distance needs an update or not
//means check total weight from source to vertex_V is less than
//the current distance value, if yes then update the distance
int newKey = heapNodes[extractedVertex].distance + edge.weight ;
int currentKey = heapNodes[destination].distance;
if(currentKey>newKey){
decreaseKey(minHeap, newKey, destination);
heapNodes[destination].distance = newKey;
}
}
}
}
//print SPT
printDijkstra(heapNodes, sourceVertex);
}
public void decreaseKey(MinHeap minHeap, int newKey, int vertex){
//get the index which distance's needs a decrease;
int index = minHeap.indexes[vertex];
//get the node and update its value
HeapNode node = minHeap.mH[index];
node.distance = newKey;
minHeap.bubbleUp(index);
}
public void printDijkstra(HeapNode[] resultSet, int sourceVertex){
System.out.println("Dijkstra's Algorithm: (using Adjacency List and Min Heap)");
for (int i = 0; i <vertices ; i++) {
String x = String.valueOf(resultSet[i].distance);
if(resultSet[i].distance == Integer.MAX_VALUE){
x = "unreachable";
}
System.out.println("Node: " + i + " | predecessor " + resultSet[i].vertex+
" | distance: " + x);
}
}
}
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new FileReader("./vg1.txt"));
printResult(br);
}
public static void printResult(BufferedReader br) throws IOException {
StringTokenizer st = new StringTokenizer((br.readLine()));
int vertices = Integer.parseInt(st.nextToken());
Graph graph = new Graph(vertices);
int K = Integer.parseInt((st.nextToken()));
for (int i = 0; i < K; i++) {
st = new StringTokenizer(br.readLine());
int from = Integer.parseInt(st.nextToken());
int to = Integer.parseInt(st.nextToken());
int weight = Integer.parseInt(st.nextToken());
graph.addEdge(from, to, weight);
}
int source_vertex = 1;
graph.dijkstra_GetMinDistances(source_vertex);
}
static class MinHeap {
int capacity;
int currentSize;
HeapNode[] mH;
int[] indexes; //will be used to decrease the distance
public MinHeap(int capacity) {
this.capacity = capacity;
mH = new HeapNode[capacity + 1];
indexes = new int[capacity];
mH[0] = new HeapNode();
mH[0].distance = Integer.MIN_VALUE;
mH[0].vertex = -1;
currentSize = 0;
}
public void display() {
for (int i = 0; i <= currentSize; i++) {
System.out.println(" " + mH[i].vertex + " distance " + mH[i].distance);
}
System.out.println("________________________");
}
public void insert(HeapNode x) {
currentSize++;
int idx = currentSize;
mH[idx] = x;
indexes[x.vertex] = idx;
bubbleUp(idx);
}
public void bubbleUp(int pos) {
int parentIdx = pos / 2;
int currentIdx = pos;
while (currentIdx > 0 && mH[parentIdx].distance > mH[currentIdx].distance) {
HeapNode currentNode = mH[currentIdx];
HeapNode parentNode = mH[parentIdx];
//swap the positions
indexes[currentNode.vertex] = parentIdx;
indexes[parentNode.vertex] = currentIdx;
swap(currentIdx, parentIdx);
currentIdx = parentIdx;
parentIdx = parentIdx / 2;
}
}
public HeapNode extractMin() {
HeapNode min = mH[1];
HeapNode lastNode = mH[currentSize];
// update the indexes[] and move the last node to the top
indexes[lastNode.vertex] = 1;
mH[1] = lastNode;
mH[currentSize] = null;
sinkDown(1);
currentSize--;
return min;
}
public void sinkDown(int k) {
int smallest = k;
int leftChildIdx = 2 * k;
int rightChildIdx = 2 * k + 1;
if (leftChildIdx < heapSize() && mH[smallest].distance > mH[leftChildIdx].distance) {
smallest = leftChildIdx;
}
if (rightChildIdx < heapSize() && mH[smallest].distance > mH[rightChildIdx].distance) {
smallest = rightChildIdx;
}
if (smallest != k) {
HeapNode smallestNode = mH[smallest];
HeapNode kNode = mH[k];
//swap the positions
indexes[smallestNode.vertex] = k;
indexes[kNode.vertex] = smallest;
swap(k, smallest);
sinkDown(smallest);
}
}
public void swap(int a, int b) {
HeapNode temp = mH[a];
mH[a] = mH[b];
mH[b] = temp;
}
public boolean isEmpty() {
return currentSize == 0;
}
public int heapSize() {
return currentSize;
}
}
}
Try to add the Edge[] edgeTo array that will track the the edge that you used to reach specific vertex.
For example
edgeTo[0] = null
edgeTo[1] = Edge( 0 -> 1 )
edgeto[2] = Edge( 1 -> 2 )
There is the path 0 -> 1 -> 2 and you can find it by traversing backwards.
You can create such an array structure by changing the lines:
public void dijkstra_GetMinDistances(int sourceVertex){
int INFINITY = Integer.MAX_VALUE;
boolean[] SPT = new boolean[vertices];
Edge[] edgeTo = new Edge[vertices];
...
and you will update this edgeTo array in if statement where you find the shorter distance:
if(currentKey>newKey){
edgeTo[destination] = edge;
decreaseKey(minHeap, newKey, destination);
heapNodes[destination].distance = newKey;
}
Finally the method that return the shortest part from source_vertex to any_other_vertex is:
public List<Edge> pathTo(int vertex) {
List<Edge> path = new LinkedList<>();
for (Edge e = edgeTo[vertex]; e != null; e = edgeTo[e.source]) {
path.addFirst(e);
}
return path;
}
All credits goes to great book and online course https://algs4.cs.princeton.edu/home/

Couldn't implement binary search on linked list

i am a cse student who takes data structures course. Trying to implement binary search algorithm to my SinglyLinkedList class, somehow i've failed. Could you check it what's wrong please ?
The related method;
I've debugged and it just enters the loops this side: else if(temp.getElement() > target)
public int binarySearchLinkedList(SinglyLinkedList<E> list, E target) {
int left = 0;
int right = list.getSize();
while (left <= right) {
int mid = (left + right) / 2;
Node<E> temp = head;
for (int i = 0; i < mid - 1; i++) {
temp = temp.next;
}
if (temp.getElement() instanceof Number && target instanceof Number) {
if (Integer.parseInt(temp.getElement().toString()) == Integer.parseInt(target.toString())) {
return mid;
} else if (Integer.parseInt(temp.getElement().toString()) > Integer.parseInt(target.toString())) {
left = mid + 1;
} else {
right = mid - 1;
}
}
}
All class for better understanding;
public class SinglyLinkedList<E> {
private static class Node<E> {
private E element;
private Node<E> next;
public Node(E e, Node<E> n) {
element = e;
next = n;
}
private E getElement() {
return element;
}
private Node<E> getNext() {
return next;
}
private void setNext(Node<E> n) {
next = n;
}
}
private Node<E> head;
private Node<E> tail;
private int size;
public SinglyLinkedList() {
};
public int getSize() {
return size;
}
public void append(E e) {
if (head == null) {
head = new Node<E>(e, null);
tail = head;
size++;
return;
}
Node<E> temp = head;
while (temp != tail) {
temp = temp.next;
}
temp.setNext(tail = new Node<E>(e, null));
size++;
return;
}
public int binarySearchLinkedList(SinglyLinkedList<E> list, E target) {
int left = 0;
int right = list.getSize();
while (left <= right) {
int mid = (left + right) / 2;
Node<E> temp = head;
for (int i = 0; i < mid - 1; i++) {
temp = temp.next;
}
if (temp.getElement() instanceof Number && target instanceof Number) {
if (Integer.parseInt(temp.getElement().toString()) == Integer.parseInt(target.toString())) {
return mid;
} else if (Integer.parseInt(temp.getElement().toString()) > Integer.parseInt(target.toString())) {
left = mid + 1;
} else {
right = mid - 1;
}
}
}
return -1;
}
public String toString() {
StringBuilder sb = new StringBuilder();
Node<E> temp = head;
while (temp != tail) {
sb.append(temp.getElement()).append(", ");
temp = temp.next;
if (temp == tail) {
sb.append(temp.getElement());
}
}
return sb.toString();
}
}
And the main method;
public static void main(String[] args) {
SinglyLinkedList<Integer> list = new SinglyLinkedList<>();
list.append(10);
list.append(20);
list.append(30);
list.append(40);
list.append(50);
list.append(60);
list.append(70);
list.append(80);
list.append(90);
list.append(100);
System.out.println(list);
System.out.println(list.binarySearchLinkedList(list, 30));
}
It returns;
10, 20, 30, 40, 50, 60, 70, 80, 90, 100
-1
I'm guessing this line is the biggest issue:
for (int i = 0; i < mid - 1; i++) {
Consider what happens if mid is 1. The loop won't execute, because it is not the case that 0 < 1-1. So the inspected node won't be the one you think it is. The actual node at index mid will never be inspected. So the outer loop will eventually exit, never having found the target. Presumably your method ends with return -1;.
Other issues include:
You're initializing right to an exclusive value, but treat it as inclusive elsewhere. Consider using int right = list.getSize() - 1;
You've declared a generic method, but implemented it only for Integer. One way around this would be to limit the generic type to one that supports Comparable - e.g., E extends Comparable<E>.
You're implementing a binary search in a linked list. In a linked list, linear search would be simpler and no less efficient. Or you could use a data structure that supports constant-time access by index, such as an array or ArrayList.

Swapping nodes in a singly linked list java

I have been trying to come up with an algorithm to swap 2 nodes (not necesarily right next to each other) in a singly linked list for 2 days but for some reason I cannot do it.
Here is what I have, I am really new to coding and have been really stressed:
I have managed to place a temp node in but can't actually swap the nodes.
public void swap(int i, int j) {
current = head;
current2 = head;
sllNode temp = new sllNode(" ");
sllNode temp2 = new sllNode(" ");
for(int z = 0; i>z; z++)
current=current.next;
for(int q = 0; j>q; q++)
current2 = current2.next;
temp.next = current2.next.next;
current.next = temp;
current.next = current2.next.next;
current2.next = current;
Why exchange nodes, when you can exchange the data?
public void swap(int i, int j) {
sllNode ithNode = head;
for (int z = 0; z < i; z++) {
ithNode = ithNode.next;
}
sllNode jthNode = head;
for (int q = 0; q < j; q++) {
jthNode = jthNode.next;
}
// Swap the data
String data = ithNode.data;
ithNode.data = jthNode.data;
jthNode.data = data;
}
It would make sense to use a method:
public sllNode get(int i) {
sllNode current = head;
while (i > 0) {
current = current.next;
}
return current;
}
By the way:
The convention for class names is a beginning capital: SllNode.
Do not use fields for things like current and current2 where they can be local variables.
Exchanging nodes, the hard way
Here one has to think, so it is best to deal with special cases first, and then only treat i < j.
public void swap(int i, int j) {
if (i >= size() || j >= size()) {
throw new IndexOutOfBoundsException();
}
if (i == j) {
return;
}
if (j < i) {
swap(j, i);
return;
}
// i < j
sllNode ithPredecessor = null;
sllNode ithNode = head;
for (int z = 0; z < i; z++) {
ithPredecessor = ithNode;
ithNode = ithNode.next;
}
sllNode jthPredecessor = ithNode;
sllNode jthNode = ithNode.next;
for (int q = i + 1; q < j; q++) {
jthPredecessor = jthNode;
jthNode = jthNode.next;
}
// Relink both nodes in the list:
// - The jthNode:
if (ithPredecessor == null) {
head = jthNode;
} else {
ithPredecessor.next = jthNode;
}
sllNode jNext = jthNode.next;
//if (ithNode.next == jthNode) {
if (jthPredecessor == ithNode) {
jthNode.next = ithNode;
} else {
jthNode.next = ithNode.next;
}
// - The ithNode:
if (jthPredecessor == ithNode) {
} else {
jthPredecessor.next = ithNode;
}
ithNode.next = jNext;
}
No guarantee that the logic is okay. There are tricks:
//if (ithNode.next == jthNode) {
if (jthPredecessor == ithNode) {
Both conditions test whether i + 1 == j, but testing on a .next and then assigning makes the condition a momentary state. As you see it would have been easier to have one single if (i + 1 == j) { ... } else { ... } and handle both the ithNode and jthNode.
To do this, you need to swap 2 things: the node as next from the previous node, and the next node.
Once you found current and current2 which are the previous nodes of the nodes you want to swap, do this:
Swap the nodes:
sllNode tmp = current.next;
current.next = current2.next;
current2.next = tmp;
Then swap the next:
tmp = current.next.next;
current.next.next = current2.next.next;
current2.next.next = tmp;
// Swapping two elements in a Linked List using Java
import java.util.*;
class SwappingTwoElements {
public static void main(String[] args)
{
LinkedList<Integer> ll = new LinkedList<>();
// Adding elements to Linked List
ll.add(10);
ll.add(11);
ll.add(12);
ll.add(13);
ll.add(14);
ll.add(15);
// Elements to swap
int element1 = 11;
int element2 = 14;
System.out.println("Linked List Before Swapping :-");
for (int i : ll) {
System.out.print(i + " ");
}
// Swapping the elements
swap(ll, element1, element2);
System.out.println();
System.out.println();
System.out.println("Linked List After Swapping :-");
for (int i : ll) {
System.out.print(i + " ");
}
}
// Swap Function
public static void swap(LinkedList<Integer> list,
int ele1, int ele2)
{
// Getting the positions of the elements
int index1 = list.indexOf(ele1);
int index2 = list.indexOf(ele2);
// Returning if the element is not present in the
// LinkedList
if (index1 == -1 || index2 == -1) {
return;
}
// Swapping the elements
list.set(index1, ele2);
list.set(index2, ele1);
}
}
Output
Before Swapping Linked List :-
10 11 12 13 14 15
After Swapping Linked List :-
10 14 12 13 11 15
Time Complexity: O(N), where N is the Linked List length

Fixing a PathFinding code

I have this path finding code which does the first part of the finding by only going one square
public class PathFinding {
static Vector2 start;
static Vector2 end;
static Cell[][] cells;
static Node currentNode;
static Arena arena;
public static void calcPAth(Vector2 from, Vector2 to,
Cell[][] mapCells, Arena a) {
start = from;
end = to;
cells = mapCells;
arena = a;
List<Node> openList = new ArrayList<Node>();
List<Node> closedList = new ArrayList<Node>();
Gdx.app.log(PArena.LOG, "Lists Created");
currentNode = new Node(null, start);
openList.add(currentNode);
Gdx.app.log(PArena.LOG, "Added start to openList");
// check squares around this and add
int startPX = (int) currentNode.parentV.x / 32;
Gdx.app.log(PArena.LOG, "Start X" + startPX);
int startPY = (int) currentNode.parentV.y / 32;
Gdx.app.log(PArena.LOG, "Start Y" + startPY);
Gdx.app.log("", "");
//
int MIN_X = startPX - 1;
int MIN_Y = startPY - 1;
int MAX_X = startPX + 1;
int MAX_Y = startPY + 1;
int startPosX = (startPX - 1 < MIN_X) ? startPX : startPX - 1;
int startPosY = (startPY - 1 < MIN_Y) ? startPY : startPY - 1;
int endPosX = (startPX + 1 > MAX_X) ? startPX : startPX + 1;
int endPosY = (startPY + 1 > MAX_Y) ? startPY : startPY + 1;
// Check boundaries on start cell
for (int rowNum = startPosX; rowNum <= endPosX; rowNum++) {
for (int colNum = startPosY; colNum <= endPosY; colNum++) {
// All the neighbors will be grid[rowNum][colNum]
if (!cells[rowNum][colNum].getTile().getProperties()
.containsKey("blocked")) {
Node node = new Node(currentNode, new Vector2(
rowNum, colNum));
if (rowNum != startPX && colNum != startPY) {
node.setMovementCost(14);
} else
node.setMovementCost(10);
openList.add(node);
System.out.print(node.getFValue() + "|");
} else
System.out.print("B");
}
System.out.println("");
}
openList.remove(currentNode);
closedList.add(currentNode);
int n = openList.get(0).getFValue();
int index = 0;
for (Node temp : openList) {
if (temp.getFValue() < n) {
n = temp.getFValue();
index = openList.lastIndexOf(temp);
Gdx.app.log("n", "n = " + n);
}
}
currentNode = openList.get(index);
arena.colorSquare(currentNode.getVectorPos());
// need to calc move cost;
//
Gdx.app.log("", "");
openList.clear();
closedList.clear();
}
This is my Node class
public static class Node {
int hVal;
int gVal;
int fVal;
Node parentNode;
Vector2 parentV;
private Node(Node node, Vector2 p) {
setParent(node);
this.parentV = p;
calcHValue();
}
public void setMovementCost(int c) {
this.gVal = c;
calcFVal();
}
private void calcFVal() {
fVal = gVal + hVal;
// Gdx.app.log("Node", "HVal = " + hVal);
// Gdx.app.log("Node", "GVal = " + gVal);
// Gdx.app.log("Node", "FVal = " + fVal);
}
private void calcHValue() {
int x = (int) (parentV.x - end.x);
if (x < 0)
x *= -1;
int y = (int) (parentV.y - end.y);
if (y < 0)
y *= -1;
hVal = (int) (x + y) / 32;
// Gdx.app.log(PArena.LOG, "Heuristic Value" + hVal);
}
private void setParent(Node node) {
this.parentNode = node;
}
public int getFValue() {
return fVal;
}
public Vector2 getVectorPos() {
return parentV;
}
}
My problem is that my debugging outputs like this
15|11|15|
11|11|11|
15|11|15|
So basically it isnt actually calculating the total value. It is just adding the movement cost, not heuristic.
What is th problem? Am i missing a step?
You are missing the Successor list i think. An A* does have a Successorlist and while the openlist isnt empty you do the following stuff:
while (openList.size() != 0) {
successor.clear();
q = openList.remove(); //first element of the prio queue
// generate your neighbornodes of q and add them to the successorlist
//after this you iterate over the successor and check if its your goalnode.
//If so you do return it else you add it to the openlist. (still inside of the while!)
//Dont forget to check if the neighbor is inside of the close list!
//if so you do not need to add it to the successorlist
//Here is how it does look at mine A*. It also contains a check if there is a betterone
// calc
for (Node suc : successor) {
if (suc.x == (int) this.screen.character.mapPos.x
&& suc.y == (int) this.screen.character.mapPos.y)
return suc; //return the goalnode
boolean add = true;
if (betterIn(suc, openList))
add = false;
if (betterIn(suc, closeList))
add = false;
if (add)
openList.add(suc);
}
Last but not least you do delete the q note from the openlist and add it to the close ist.
}
closeList.add(q);
}//end of while
Some more minor improvmements would be that you do add a compareable to the Node..
#Override
public int compareTo(Node o) {
if ((this.g + this.h) < (o.g + o.h))
return -1;
else if ((this.g + this.h) >= (o.g + o.h))
return 1;
else
return 0;
}
also override the equals and the hashCode method for it for example like this:
#Override
public boolean equals(Object o) {
// override for a different compare
return ((Node) o).x == this.x && ((Node) o).y == this.y;
}
#Override
public int hashCode() {
return x + y;
}
After that your openList can be a PriorityQueue<Node> and the first object you are getting from the is always the one with the smallest h.
Dont forget to return our final Node to iterate over the getparent method to get the path.
private boolean betterIn(Node n, Collection<Node> l) {
for (Node no : l) {
if (no.x == n.x && no.y == n.y && (no.g + no.h) <= (n.g + n.h))
return true;
}
return false;
}

Two point crossover in Java

I have implemented a one point crossover as follows;
public void onePointCrossover(Individual indi) {
if (SGA.rand.nextDouble() < pc) {
int xoverpoint = SGA.rand.nextInt(length);
int tmp;
for (int i=xoverpoint; i<length; i++){
tmp = chromosome[i];
chromosome[i] = indi.chromosome[i];
indi.chromosome[i] = tmp;
}
}
}
One point crossover - crossover point is selected, binary string from beginning of chromosome to the crossover point is copied from one parent, the rest is copied from the second parent.
Parent 1 = chromosome and Parent 2 = indi.
I am turning the parents into children inplace.
I now need to also do a two point crossover but having some trouble, this is what I have so far but I believe the bottom half of the code is doing the same thing as a one point crossover rather than swapping the middle sections.
public void twoPointCrossover(Individual indi) {
if (SGA.rand.nextDouble() < pc) {
int xoverpoint = SGA.rand.nextInt(length);
int xoverpoint2 = SGA.rand.nextInt(length);
int tmp;
if (xoverpoint > xoverpoint2){
tmp = xoverpoint;
xoverpoint = xoverpoint2;
xoverpoint2 = tmp;
}
for (int i=xoverpoint; i<xoverpoint2; i++){
tmp = chromosome[i];
chromosome[i] = indi.chromosome[i];
indi.chromosome[i] = tmp;
}
}
}
}
This does not seem right and any help will be appreciated so much! Thanks!
You should check for i < (or <=) xoverpoint2 rather than i<length in the loop.
I'm working on the same problem now. Here is my solution:
// Two-Point Crossover function
public Genome twoPtCrossover(Genome partner) {
Genome child = new Genome(partner.genome.length);
int crosspoint1 = xd.nextInt(genome.length);
int crosspoint2 = xd.nextInt(genome.length);
// Ensure crosspoints are different...
if (crosspoint1 == crosspoint2){
if(crosspoint1 == 0){
crosspoint2++;
} else {
crosspoint1--;
}
}
// .. and crosspoint1 is lower than crosspoint2
if (crosspoint2 < crosspoint1) {
int temp = crosspoint1;
crosspoint1 = crosspoint2;
crosspoint2 = temp;
}
for (int i = 0; i < genome.length; i++) {
if (i < crosspoint1 || i > crosspoint2)
child.genome[i] = genome[i];
else
child.genome[i] = partner.genome[i];
}
return child;
}

Categories

Resources