I'm trying to implement the A*star Search Algorithm and I was successful with it, however it sometimes does not produce the optimal shortest path, I was wondering if I could optimise the algorithm to produce a better shortest path? (I mean the shortest path isn't actually the shortest path)
At the moment I am keeping track of the Parent Node for each neighbour to find the shortest path, I think this is where the problem lies and so when I add the FinishNode last to the VisitedNodesInOrder array, I can access the parent that got us to that cell the fastest, and I keep going back until I reach the startNode in which case the parent is null.
It doesn't work as intended when there are walls, because it doesn't see the walls until it reaches them and so it takes a non-optimal path, so when I am tracing back from the FinishNode, it follows the non-optimal path.
Is this suppose to work like this? Or is there a way for the Algorithm to consider the walls before trying to take the non-optimal path?
The grid is made up of a 2D Array of Node Object, which has a row, col and NodeType Property.
The neighbour of each Node consists of the 4 cells next to it (left, right, top, bottom)
const aStar = (grid, startNode, finishNode) => {
const n = grid.length;
const m = grid[0].length;
const endRow = finishNode.row;
const endCol = finishNode.col;
const visitedNodesInOrder = [];
const pq = new PriorityQueue((a, b) => a.distance < b.distance);
startNode.parent = null;
//Store in an object {node: {row, col, parent}, distance: x}
//Distance refers to distance to FinishNode
pq.push({node: startNode, distance: Math.abs(endRow - startNode.row) + Math.abs(endCol - startNode.col)});
while(!pq.isEmpty()){
const {node} = pq.pop();
const row = node.row;
const col = node.col;
const parent = node.parent;
if(grid[row][col].nodeType == NodeType.VISITED_NODE){
continue;
}
if (grid[row][col].nodeType === NodeType.FINISH_NODE) {
visitedNodesInOrder.push({row, col, parent});
break;
}
if (grid[row][col].nodeType === NodeType.WALL_NODE) {
continue;
}
if (row < n - 1) {
pq.push({node: {row: row + 1, col, parent: {row, col}}, distance: Math.abs(endRow - row + 1) + Math.abs(endCol - col)});
}
if (row > 0) {
pq.push({node: {row: row - 1, col, parent: {row, col}}, distance: Math.abs(endRow - row - 1) + Math.abs(endCol - col)});
}
if (col < m - 1) {
pq.push({node: {row: row, col: col + 1, parent: {row, col}}, distance: Math.abs(endRow - row) + Math.abs(endCol - col + 1)});
}
if (col > 0) {
pq.push({node: {row: row, col: col - 1, parent: {row, col}}, distance: Math.abs(endRow - row) + Math.abs(endCol - col - 1)});
}
if (grid[row][col].nodeType === NodeType.EMPTY_NODE) {
visitedNodesInOrder.push({row, col, parent: parent});
grid[row][col].nodeType = NodeType.VISITED_NODE;
}
}
return visitedNodesInOrder
};
The Blue in the picture represents visitedNodes, The black being the walls and the yellow path is the "shortest" path.