+ All Categories
Home > Documents > Shortest Path Solutions - SFU.caarashr/warren.pdf · This is a shortest path algorithm that avoids...

Shortest Path Solutions - SFU.caarashr/warren.pdf · This is a shortest path algorithm that avoids...

Date post: 28-May-2020
Category:
Upload: others
View: 12 times
Download: 0 times
Share this document with a friend
17
A* Algorithm BY WARREN RUSSELL
Transcript

A* Algorithm BY WARREN RUSSELL

Dijkstra’s Algorithm In real time, finding a path can be time consuming.

Especially with all the extra cells visited.

Is this practical? Could we do better?

A* (A Star) This is a shortest path algorithm that avoids exhaustive searches by only looking at promising nodes that are calculated using heuristics.

A heuristic is a process or method In this case, it is the process used to provided a better guess for shortest path searches.

Works by maintaining two lists, the open list and closed list. Open list holds all nodes found and waiting to be considered. Closed list holds all nodes already considered.

G, H, and F Each node is evaluated based on three important scores. G Score is the “cost so far”, or simply the incremental cost of

moving from the start node to this node G(n) = g(n.parent) + g(n.parent, n)

H Score is the heuristic estimate, or the guess for how far the goal is from the current node. It is usually computationally easy to calculate which is what makes A* so efficient.

F Score is simply the addition of G score and H Score. It is calculated for each node.

Pseudo Code – Initialize Variables function findPath( startNode, destinationNode ):Array {

_openList = new Array();

_closedList = new Array();

currentNode = startNode;

var testNode:Node;

var connectedNodes:Array;

var g:Number;

var h:Number;

var f:Number;

currentNode.g = 0;

currentNode.h = heuristic(currentNode, destinationNode, currentNode.travelCost);

currentNode.f = currentNode.g + currentNode.h;

Pseudo Code (Cont.) // loop variables while (currentNode != destinationNode) { connectedNodes = connectedNodeFunction( currentNode ); int length = connectedNodes.length; for (int i = 0; i < length; ++i) { testNode = connectedNodes[i]; if ( testNode == currentNode || testNode.traversable == false ) continue;

g = currentNode.g + currentNode.travelCost;

h = heuristic( testNode, destinationNode, currentNode.travelCost);

f = g + h;

Pseudo Code (Cont.)

if ( Pathfinding.isOpen(testNode, _openList) || Pathfinding.isClosed( testNode, _closedList) ) { if(testNode.f > f) { testNode.f = f; testNode.g = g; testNode.h = h; testNode.parentNode = currentNode; } } else { testNode.f = f; testNode.g = g; testNode.h = h; testNode.parentNode = currentNode; _openList.push(testNode); } _closedList.push( currentNode );

Pseudo Code (Last.) if (_openList.length == 0)

{

return null;

}

_openList.sort(compareF);

currentNode = _openList.shift() as Node;

++numOfLoops;

}

if ( numOfLoops <= iterations ) return buildPath(destinationNode, firstNode);

else return null;

}

Simple Example – using tie-breaker oldest lowest f first

Wall Goal

Wall

Start

g = 0

h = 6

f = 6

g = 1

h = 5

f = 6

g = 1

h = 5 f = 6

g = 1

h = 7

f = 8

g = 2

h = 4

f = 6

g = 2

h = 6

f = 8

g = 2

h = 4

f = 6

g = 2

h = 4

f = 6

g = 4

h = 4

f = 8

g = 4

h = 2

f = 6

g = 5

h = 3

f = 8

3

6

g = 3

h = f =

g = 3

h = 5

f = 8

g = 6

h = 0

f = 6

4

2

6

g = h = f =

g = 4

h = 4

f = 8

g = 5

h = 1

f = 6

g = 5

h = 3

f = 8

g = 3

h = 3

f = 6

g = 3

h = 5

f = 8

g = 3

h = 3

f = 6

Special Cases with heuristics in A* What if the H value is zero?

Only G value plays a role in the heuristic.

A* turns back into Dijkstra’s Algorithm!

Guaranteed to find the shortest path.

What if the G value is set to zero?

Only H value plays a role in the heuristic.

A* transforms into the greedy algorithm called Best-First-Search or B*

Best First Search

Dijkstra’s

Heuristics Manhattan distance

Best used when movement is restricted to 4 directions

h(n) = Cost * (abs(n.x-goal.x) + abs(n.y-goal.y))

Diagonal/Chebyshev

Used when movement is in 8 directions

h(n) = Cost * max(abs(n.x-goal.x), abs(n.y-goal.y))

Heuristics (cont.) Diagonal/Chebyshev

More sophisticated version if cost of moving diagonally is not equivalent to moving horizontally or vertically.

h_diagonal(n) = min(abs(n.x-goal.x), abs(n.y-goal.y))

h_straight(n) = (abs(n.x-goal.x) + abs(n.y-goal.y))

h(n) = DiagonalCost * h_diagonal(n) + Cost * (h_straight(n) - 2*h_diagonal(n)))

h_diagonal(n) = the number of steps you can take along a diagonal. h_straight(n) = the Manhattan distance Then combine the two by considering all diagonal steps to cost DiagonalCost. Then all remaining straight steps cost D.

More Heuristics… Euclidean/straight line distance

Used when any direction of movement is allowed.

h(n) = Cost * sqrt((n.x-goal.x)^2 + (n.y-goal.y)^2)

Demo

A* using Manhatten/Taxicab heuristic with movement in 4 directions

A* using Diagonal/Chebyshev heuristic with movement in 8 directions

Conditions for an Optimal Solution A* always finds the solution if it exists, but to be the optimal solution, the heuristic has to be consistent and admissible

A consistent (or monotone) heuristic function is a function that estimates the distance to the goal, and is always at most equal to the estimated distance from any neighboring vertex plus the step cost of reaching that neighbor. h(n) < c(n,p) + h(p) and h(goal) = 0

A heuristic function is said to be admissible if it never overestimates the cost of reaching the goal, i.e. the cost it estimates to reach the goal is not higher than the lowest possible cost from the current point in the path. An admissible heuristic is also known as an optimistic heuristic.

Running Time of A* The time complexity of A* depends on the heuristic. In the worst case, the number of nodes expanded is exponential in the length of the solution (the shortest path), but it is polynomial when the:

search space is a tree,

there is a single goal,

and the heuristic function h meets the following condition:

|h(x) - h*(x)| = O(log h*(x))

Improvements Beam Search Limit the size of the OpenList. When OpenList is full, drop the nodes with the worst chance of providing a good path. Drawback: OpenList needs to be kept sorted all the time. Limits possible data structures you can use.

Using less nodes is the number one improvement that can be made. It is common to use meshes instead.


Recommended