Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                

Unit 2

Download as pdf or txt
Download as pdf or txt
You are on page 1of 125

UNIT II SEARCH TECHNIQUES

Problem solving agents, searching for solutions;


uniform search strategies: breadth first search,
depth first search, depth limited search,
bidirectional search, comparing uniform search
strategies. Heuristic search strategies Greedy
best-first search, A* search, AO* search, memory
bounded heuristic search: local search
algorithms & optimization problems: Hill climbing
search, simulated annealing search, local beam
search
Problems, Problem Search and Space
• Problem Spaces and Search Problem solving
is a process of generating solutions from
observed data.
• A Problem is characterized by a set of goals,
• a set of objects, and
• a set of operations.
• Problem space is an abstract space.
Problem-solving agent
• The problem-solving agent performs precisely by
defining problems and its several solutions.
• According to psychology, “a problem-solving
refers to a state where we wish to reach to a
definite goal from a present state or condition.”
• According to computer science, “a problem-
solving is a part of artificial intelligence which
encompasses a number of techniques such as
algorithms, heuristics to solve a problem.”
• Therefore, a problem-solving agent is a goal-
driven agent and focuses on satisfying the goal.
Example of problem solving agent
Example Problems

• Basically, there are two types of problem approaches:

• Toy Problem: It is a concise and exact description of


the problem which is used by the researchers to
compare the performance of algorithms.

• Real-world Problem: It is real-world based problems


which require solutions. Unlike a toy problem, it does
not depend on descriptions, but we can have a general
formulation of the problem.
Most popularly used problem solving
with the help of AI
• 8 puzzle problem
• N-Queen Problem.
• Ball Collecting / Vacuum Cleaner Problem
• Tower of Hanoi Problem.
• Travelling Salesman Problem.
• Water-Jug Problem.
Searching for Solutions
• Search: Searching is a step by step procedure to solve a
search-problem in a given search space. A search
problem can have three main factors:
– Search Space: Search space represents a set of
possible solutions, which a system may have.
– Start State: It is a state from where agent begins the
search.
– Goal test: It is a function which observe the current
state and returns whether the goal state is achieved or
not.
• Search tree: A tree representation of search problem is
called Search tree. The root of the search tree is the root
node which is corresponding to the initial state.
Searching for Solutions
• Actions: It gives the description of all the
available actions to the agent.
• Transition model: A description of what each
action do, can be represented as a transition
model.
• Path Cost: It is a function which assigns a
numeric cost to each path.
• Solution: It is an action sequence which leads
from the start node to the goal node.
• Optimal Solution: If a solution has the lowest
cost among all solutions.
Properties of Search Algorithms:
The four essential properties of search algorithms to
compare the efficiency of these algorithms:
• Completeness: A search algorithm is said to be
complete if it guarantees to return a solution if at least
any solution exists for any random input.
• Optimality: If a solution found for an algorithm is
guaranteed to be the best solution (lowest path cost)
among all other solutions, then such a solution for is
said to be an optimal solution.
• Time Complexity: Time complexity is a measure of
time for an algorithm to complete its task.
• Space Complexity: It is the maximum storage space
required at any point during the search, as the
complexity of the problem.
Types of search algorithms
• Based on the search problems we can classify the search
algorithms into uninformed (Blind search) search and
informed search (Heuristic search) algorithms.
Uninformed Search Algorithms
• Uninformed search is a class of general-purpose search
algorithms which operates in brute force-way.
• Uninformed search algorithms do not have additional
information about state or search space other than
how to traverse the tree, so it is also called blind
search.
• Following are the various types of uninformed search
algorithms:
1. Breadth-first Search
2. Depth-first Search
3. Depth-limited Search
4. Iterative deepening depth-first search
5. Uniform cost search
6. Bidirectional Search
1. Breadth-first Search:
• Breadth-first search (BFS) is one of the most important
uninformed search strategies in artificial intelligence to
explore a search space systematically.
• BFS explores all the neighbouring nodes of the initial
state before moving on to explore their neighbours.
• This strategy ensures that the shortest path to the goal
is found.
• The algorithm works by starting at the initial state and
adding all its neighbours to a queue.
• It then dequeues the first node in the queue, adds
neighbours to the end of the queue, and repeats the
process until the goal state is found or the queue is
empty.
Example: BFS
• In the below tree structure, we have shown the traversing of the tree
using BFS algorithm from the root node S to goal node K.
• BFS search algorithm traverse in layers, so it will follow the path which is
shown by the dotted arrow, and the traversed path will be:

• S---> A--->B---->C--->D---->G--->H--->E---->F---->I---->K
Breadth-first Search
• Time Complexity: Time Complexity of BFS algorithm
can be obtained by the number of nodes traversed in
BFS until the shallowest Node. Where the d= depth of
shallowest solution and b is a node at every state.
T (b) = 1+b2+b3+.......+ bd= O (bd)
• Space Complexity: Space complexity of BFS algorithm
is given by the Memory size of frontier which is O(bd).
• Completeness: BFS is complete, which means if the
shallowest goal node is at some finite depth, then BFS
will find a solution.
• Optimality: BFS is optimal if path cost is a non-
decreasing function of the depth of the node.
BFS
Advantages:
• BFS will provide a solution if any solution exists.
• If there are more than one solutions for a given
problem, then BFS will provide the minimal
solution which requires the least number of
steps.
Disadvantages:
• It requires lots of memory since each level of the
tree must be saved into memory to expand the
next level.
• BFS needs lots of time if the solution is far away
from the root node.
Assignment problem : BFS
2. Depth-first Search
• Depth-first search (DFS) is popular among the
uninformed search strategies in artificial intelligence to
explore and traverse a graph or tree data structure.
• The algorithm starts at a given node in the graph and
explores as far as possible along each branch before
backtracking.
• DFS is a recursive algorithm that follows the following
steps:
1. Mark the starting node as visited.
2. Explore all adjacent nodes that have not been visited.
3. For each unvisited adjacent node, repeat steps 1 and
2 recursively.
4. Backtrack if all adjacent nodes have been visited or
there are no unvisited nodes.
Depth-first Search
• DFS can be implemented using a stack data
structure or recursion.
• The recursive implementation is simpler to
understand but can cause a stack overflow if the
graph or tree is too large.
• DFS has several applications in AI, including
pathfinding, searching for solutions to a problem,
and exploring the state space of a problem.
• It is particularly useful when the solution is far
from the starting node because it can explore the
graph deeply before exploring widely.
Example : DFS
• In the below search tree, we have shown the flow of depth-first search,
and it will follow the order as:
Root node--->Left node ----> right node.
• It will start searching from root node S, and traverse A, then B, then D and
E, after traversing E, it will backtrack the tree as E has no other successor
and still goal node is not found. After backtracking it will traverse node C
and then G, and here it will terminate as it found goal node.
Pseudocode: DFS
DFS
• Completeness: DFS search algorithm is complete within
finite state space as it will expand every node within a
limited search tree.
• Time Complexity: Time complexity of DFS will be
equivalent to the node traversed by the algorithm. It is
given by:
T(n)= 1+ n2+ n3 +.........+ nm=O(nm)
• Where, m= maximum depth of any node and this can be
much larger than d (Shallowest solution depth)
• Space Complexity: DFS algorithm needs to store only single
path from the root node, hence space complexity of DFS is
equivalent to the size of the fringe set, which is O(bm)
• Optimal: DFS search algorithm is non-optimal, as it may
generate a large number of steps or high cost to reach to
the goal node.
DFS
Advantage:
• DFS requires very less memory as it only needs to
store a stack of the nodes on the path from root
node to the current node.
• It takes less time to reach to the goal node than
BFS algorithm (if it traverses in the right path).
Disadvantage:
• There is the possibility that many states keep re-
occurring, and there is no guarantee of finding
the solution.
• DFS algorithm goes for deep down searching and
sometime it may go to the infinite loop.
Assignment problem : DFS
3. Depth-Limited Search Algorithm:
• A depth-limited search algorithm is similar to
depth-first search with a predetermined limit.
• Depth-limited search can solve the drawback of
the infinite path in the Depth-first search.
• In this algorithm, the node at the depth limit will
treat as it has no successor nodes further.
• Depth-limited search can be terminated with two
Conditions of failure:
• Standard failure value: It indicates that problem
does not have any solution.
• Cutoff failure value: It defines no solution for the
problem within a given depth limit.
Algorithm to find DLS.
Step 1: Start with the initial state of the problem.

Step 2: Explore the current state and generate its


successors.

Step 3: If the depth of the current state is equal to


the predefined limit, stop the search.

Step 4: Else, recursively apply the DLS to explore the


branch till the level with limit is reached.

Step 5: Repeat the above steps until a goal state is


reached or all the states till that level is traversed.
Example: Depth-Limited Search Algorithm
Start from the Initial State, i.e. A and
expand its neighbours B and C.

Perform DFS and visit neighbour B. This is


Level Number 1, and since our Depth Limit
is 2, we can continue to visit the neighbour
of B, i.e. D and G.

Expand the neighbour D, and Since the


Depth limit is reached, backtrack to node B.

Expand the other neighbour, G. Since G is


equal to the goal state, stop the search and
return the path.

Hence, the resultant path is A -> B -> D ->


G.
DLS
• Completeness: DLS search algorithm is complete
if the solution is above the depth-limit.
• Time Complexity: Time complexity of DLS
algorithm is O(bℓ). Where b is the number of
nodes and ℓ is the level limit.
• Space Complexity: Space complexity of DLS
algorithm is O(b×ℓ).
• Optimal: Depth-limited search can be viewed as a
special case of DFS, and it is also not optimal
Depth-Limited Search Algorithm
Advantages:
• Depth-limited search is Memory efficient.
Disadvantages:
• Depth-limited search also has a disadvantage
of incompleteness.
• It may not be optimal if the problem has more
than one solution.
Assignment : DLS
Consider the given graph with Depth Limit(l)=2,
Target Node = H and the given source node = A
4. Uniform-cost Search Algorithm:
• Uniform-cost search is a searching algorithm used for
traversing a weighted tree or graph.
• This algorithm comes into play when a different cost is
available for each edge.
• The primary goal of the uniform-cost search is to find a
path to the goal node which has the lowest cumulative
cost.
• Uniform-cost search expands nodes according to their path
costs form the root node.
• It can be used to solve any graph/tree where the optimal
cost is in demand.
• A uniform-cost search algorithm is implemented by the
priority queue.
• It gives maximum priority to the lowest cumulative cost.
• Uniform cost search is equivalent to BFS algorithm if the
path cost of all edges is the same.
Uniform-cost Search Algorithm
Completeness:
• Uniform-cost search is complete, such as if there is a solution, UCS
will find it.
Time Complexity:
• Let C* is Cost of the optimal solution, and ε is each step to get
closer to the goal node. Then the number of steps is = C*/ε+1. Here
we have taken +1, as we start from state 0 and end to C*/ε.
• Hence, the worst-case time complexity of Uniform-cost search is
O(b1 + [C*/ε]).
Space Complexity:
• The same logic is for space complexity so, the worst-case space
complexity of Uniform-cost search is O(b1 + [C*/ε]).
Optimal:
• Uniform-cost search is always optimal as it only selects a path with
the lowest path cost.
Uniform-cost Search Algorithm
Advantages:
• Uniform cost search is optimal because at every
state the path with the least cost is chosen.
Disadvantages:
• It does not care about the number of steps
involve in searching and only concerned about
path cost.
• Due to which this algorithm may be stuck in an
infinite loop.
Assignment Problem
5. Iterative deepening depth-first
Search:
• The iterative deepening algorithm is a combination of
DFS and BFS algorithms.
• This search algorithm finds out the best depth limit and
does it by gradually increasing the limit until a goal is
found.
• This algorithm performs depth-first search up to a
certain "depth limit", and it keeps increasing the depth
limit after each iteration until the goal node is found.
• This Search algorithm combines the benefits of
Breadth-first search's fast search and depth-first
search's memory efficiency.
• The iterative search algorithm is useful uninformed
search when search space is large, and depth of goal
node is unknown.
Algorithm to perform IDDFS.
Step 1: Set the depth limit as 0, which means the search will
be performed only up to the 0th level.

Step 2: Start from the initial state and perform the DLS with a
current depth limit of 0.

Step 3: If the goal state is found, return it.

Step 4: Else, increase the depth limit by 1 and repeat the


above steps.

Step 5: Repeat until the goal state is reached or all the nodes
are explored.
Example : IDDFS
Set the depth limit as 0 and start the search
from the initial state, i.e. A.

Since A is not equal to Goal Node, and there


are no unexplored nodes left till level 0,
Increment the limit by 1.

Again start from the initial state, A and perform


DLS till level 1. Following is the explored
path: A -> B -> C.

Again, the Goal Node is not found; increment


the limit by 1. Now depth limit is equal to 2.

Now, the explored path is A -> B -> D ->


G. Since the Goal state is found, we will stop
the search.
IDDFS
Completeness:
• This algorithm is complete is ifthe branching factor is
finite.
Time Complexity:
• Let's suppose b is the branching factor and depth is d
then the worst-case time complexity is O(bd).
Space Complexity:
• The space complexity of IDDFS will be O(bd).
Optimal:
• IDDFS algorithm is optimal if path cost is a non-
decreasing function of the depth of the node.
IDDFS
Advantages:
• It combines the benefits of BFS and DFS
search algorithm in terms of fast search and
memory efficiency.
Disadvantages:
• The main drawback of IDDFS is that it repeats
all the work of the previous phase.
Assignment: IDDFS
Bidirectional search
• Bidirectional search algorithm runs two simultaneous
searches, one form initial state called as forward-search and
other from goal node called as backward-search, to find the
goal node.
• Bidirectional search replaces one single search graph with two
small subgraphs in which one starts the search from an initial
vertex and other starts from goal vertex.
• The search stops when these two graphs intersect each other.
• Bidirectional search can use search techniques such as BFS,
DFS, DLS, etc.
Example:
In the below search tree, bidirectional search algorithm is applied.
This algorithm divides one graph/tree into two sub-graphs.
It starts traversing from node 1 in the forward direction and starts from goal
node 16 in the backward direction.
The algorithm terminates at node 9 where two searches meet.
Bidirectional Search
• Completeness: Bidirectional Search is
complete if we use BFS in both searches.
• Time Complexity: Time complexity of
bidirectional search using BFS is O(bd).
• Space Complexity: Space complexity of
bidirectional search is O(bd).
• Optimal: Bidirectional search is Optimal.
Bidirectional search
Advantages:
• Bidirectional search is fast.
• Bidirectional search requires less memory
Disadvantages:
• Implementation of the bidirectional search
tree is difficult.
• In bidirectional search, one should know the
goal state in advance.
Heuristic search strategies Greedy
best-first search
Informed Search Algorithms
• Informed search algorithm contains an array of
knowledge such as how far we are from the goal,
path cost, how to reach to goal node, etc.
• This knowledge help agents to explore less to the
search space and find more efficiently the goal
node.
• The informed search algorithm is more useful for
large search space.
• Informed search algorithm uses the idea of
heuristic, so it is also called Heuristic search.
Heuristics function:
• Heuristic is a function which is used in Informed
Search, and it finds the most promising path.
• It takes the current state of the agent as its input and
produces the estimation of how close agent is from the
goal.
• The heuristic method, however, might not always give
the best solution, but it guaranteed to find a good
solution in reasonable time.
• Heuristic function estimates how close a state is to the
goal.
• It is represented by h(n), and it calculates the cost of
an optimal path between the pair of states.
• The value of the heuristic function is always positive.
Admissibility of the heuristic function
is given as:
h(n) <= h*(n)
• Here h(n) is heuristic cost, and h*(n) is the
estimated cost.
• Hence heuristic cost should be less than or
equal to the estimated cost.
Pure Heuristic Search:
• Pure heuristic search is the simplest form of
heuristic search algorithms.
• It expands nodes based on their heuristic value
h(n).
• It maintains two lists, OPEN and CLOSED list.
• In the CLOSED list, it places those nodes which
have already expanded and in the OPEN list, it
places nodes which have yet not been expanded.
• On each iteration, each node n with the lowest
heuristic value is expanded and generates all its
successors and n is placed to the closed list.
• The algorithm continues unit a goal state is
found.
In the informed search we will discuss
two main algorithms

• Best First Search Algorithm(Greedy search)


• A* Search Algorithm
• AO* Search Algorithm
• Memory bounded heuristic search
1. IDA* (Iterative Deepening A*)
2. RBFS (recursive best-first search).
3. MA* (Memory-bounded A*) and
4. SMA*(Simplified memory MA*)
Greedy best-first search
• It is an informed search algorithm where the evaluation
function is strictly equal to the heuristic function, disregarding
the edge weights in a weighted graph because only the
heuristic value is considered.
• In order to search for a goal node it expands the node that is
closest to the goal as determined by the heuristic function.
• This approach assumes that it is likely to lead to a solution
quickly.
• However, the solution from a greedy best-first search may
not be optimal since a shorter path may exist.
• In this algorithm, search cost is at a minimum since the
solution is found without expanding a node that is not on the
solution path.
• This algorithm is minimal, but not complete, since it can lead
to a dead end.
• It’s called “Greedy” because at each step it tries to get as
close to the goal as it can.
Evaluation Function

• The evaluation function, f(n), for the greedy


best-first search algorithm is the following:
• f(n) = h(n) Here, the evaluation function is
equal to the heuristic function.
• Since this search disregards edge weights,
finding the lowest-cost path is not guaranteed.
Greedy Best first search algorithm:
Step 1: Place the starting node into the OPEN list.
Step 2: If the OPEN list is empty, Stop and return failure.
Step 3: Remove the node n, from the OPEN list which has the
lowest value of h(n), and places it in the CLOSED list.
Step 4: Expand the node n, and generate the successors of
node n.
Step 5: Check each successor of node n, and find whether any
node is a goal node or not. If any successor node is goal
node, then return success and terminate the search, else
proceed to Step 6.
Step 6: For each successor node, algorithm checks for
evaluation function f(n), and then check if the node has
been in either OPEN or CLOSED list. If the node has not
been in both list, then add it to the OPEN list.
Step 7: Return to Step 2.
Example : Consider finding the path from P to S in the following
graph:
In this example, the cost is measured strictly using the heuristic value. In
other words, how close it is to the target.
U has the lowest cost compared to M and R, so the search will continue by exploring U.
Finally, S has a heuristic value of 0 since that is the target node:
The total cost for the path (P -> C -> U -> S) evaluates to 11. The
potential problem with a greedy best-first search is revealed by
the path (P -> R -> E -> S) having a cost of 10, which is lower than
(P -> C -> U -> S). Greedy best-first search ignored this path
because it does not consider the edge weights.
Greedy Best first search algorithm
• Time Complexity: The worst case time complexity
of Greedy best first search is O(bm).
• Space Complexity: The worst case space
complexity of Greedy best first search is O(bm).
Where, m is the maximum depth of the search
space.
• Complete: Greedy best-first search is also
incomplete, even if the given state space is finite.
• Optimal: Greedy best first search algorithm is not
optimal.
Greedy Best first search algorithm:
Advantages:
• Best first search can switch between BFS and DFS
by gaining the advantages of both the algorithms.
• This algorithm is more efficient than BFS and DFS
algorithms.
Disadvantages:
• It can behave as an unguided depth-first search in
the worst case scenario.
• It can get stuck in a loop as DFS.
• This algorithm is not optimal.
A* Search Algorithm:
• A* search is the most commonly known form of
best-first search.
• It uses heuristic function h(n), and cost to reach
the node n from the start state g(n).
• It has combined features of UCS and greedy best-
first search, by which it solve the problem
efficiently.
• A* search algorithm finds the shortest path
through the search space using the heuristic
function.
• This search algorithm expands less search tree
and provides optimal result faster.
• A* algorithm is similar to UCS except that it uses
g(n)+h(n) instead of g(n).
A* Search Algorithm:
•In A* search algorithm, we use search heuristic as well as the
cost to reach the node.
•Hence we can combine both costs as following, and this sum is
called as a fitness number.

At each point in the search space, only those node is expanded


which have the lowest value of f(n), and the algorithm terminates
when the goal node is found.
Algorithm of A* search:
Step1: Place the starting node in the OPEN list.

Step 2: Check if the OPEN list is empty or not, if the list is empty then return failure

and stops.

Step 3: Select the node from the OPEN list which has the smallest value of evaluation

function (g+h), if node n is goal node then return success and stop, otherwise

Step 4: Expand node n and generate all of its successors, and put n into the closed list.

For each successor n', check whether n' is already in the OPEN or CLOSED list, if

not then compute evaluation function for n' and place into Open list.

Step 5: Else if node n' is already in OPEN and CLOSED, then it should be attached to

the back pointer which reflects the lowest g(n') value.

Step 6: Return to Step 2.


Example: In this example, we will traverse the given graph using
the A*algorithm .
• The heuristic value of all states is given in the below table so
we will calculate the f(n) of each state using the formula f(n)=
g(n) + h(n), where g(n) is the cost to reach any node from start
state.
• Here we will use OPEN and CLOSED list.
Solution:
Solution
Initialization: {(S, 5)}
Iteration1: {(S--> A, 4), (S-->G, 10)}
Iteration2: {(S--> A-->C, 4), (S--> A-->B, 7), (S-->G, 10)}
Iteration3: {(S--> A-->C--->G, 6), (S--> A-->C--->D, 11), (S--> A--
>B, 7), (S-->G, 10)}
Iteration 4 will give the final result, as S--->A--->C--->G it
provides the optimal path with cost 6.

• A* algorithm returns the path which occurred first, and it


does not search for all remaining paths.
• The efficiency of A* algorithm depends on the quality of
heuristic.
• A* algorithm expands all nodes which satisfy the condition
f(n)
A* Algorithm
Complete: A* algorithm is complete as long as:
• Branching factor is finite.
• Cost at every action is fixed.
Optimal: A* search algorithm is optimal if it follows below two
conditions:
• Admissible: the first condition requires for optimality is that h(n)
should be an admissible heuristic for A* tree search. An admissible
heuristic is optimistic in nature.
• Consistency: Second required condition is consistency for only A*
graph-search.
• If the heuristic function is admissible, then A* tree search will
always find the least cost path.
Time Complexity: The time complexity of A* search algorithm
depends on heuristic function, and the number of nodes expanded
is exponential to the depth of solution d. So the time complexity is
O(b^d), where b is the branching factor.
Space Complexity: The space complexity of A* search algorithm
is O(b^d)
A* search algorithm
Advantages:
• A* search algorithm is the best algorithm than other
search algorithms.
• A* search algorithm is optimal and complete.
• This algorithm can solve very complex problems.
Disadvantages:
• It does not always produce the shortest path as it
mostly based on heuristics and approximation.
• A* search algorithm has some complexity issues.
• The main drawback of A* is memory requirement as it
keeps all generated nodes in the memory, so it is not
practical for various large-scale problems.
Solve using A* algorithm
AO* search algorithm
• The AO* best algorithm for solving cyclic AND-OR graphs.
• The problem is divided into set of sub problems, where
each sub problem can be solved separately.
• The AND side of the graph represents those tasks that need
to be done with each other to reach the goal, while the OR
side stands alone for a single task.
AO* works based on this formula:
• f(n)= g(n) + h(n),
• where g(n) is the actual cost of going from the starting
node to the current node,
• h(n) is the estimated or heuristic cost of going from the
current node to the goal node, and
• f(n) is the actual cost of going from the starting node to the
goal node.
Difference Between A* Algorithm and
AO* Algorithm
Memory bounded heuristic search
• IDA* (Iterative Deepening A*)
• RBFS (recursive best-first search).
• MA* (Memory-bounded A*) or
SMA*(simplified memory MA*)
Example : IDA*
• In the below tree, the f score is written inside the nodes means the f score
is already computed and the start node is 2 whereas the goal node is 15.
the explored node is colored green color.
• so now we have to go to a given goal by using IDA* algorithm.
Advantages
• IDA* is guaranteed to find the optimal solution if one exists.
• IDA* avoids the exponential time complexity of traditional Depth
First Search. by using an “iterative deepening” approach, where the
search depth is gradually increased.
• IDA* uses a limited amount of memory as compared to the A*
algorithm because it uses Depth First Search.
• IDA* is an admissible heuristic, it never overestimates the cost of
reaching the goal.
• It’s efficient in handling large numbers of states and large branch
factors.
Disadvantages
• Explore the visited node again and again. it doesn’t keep track of
the visited nodes.
• IDA* may be slower to get a solution than other search algorithms
like A* or Breadth-First Search because it explores and repeats the
explore node again and again.
• It takes more time and power than the A* algorithm.
SMA* or Simplified Memory Bounded
A*
• SMA* or Simplified Memory Bounded A* is a
shortest path algorithm based on the A*
algorithm.
• The main advantage of SMA* is that it uses a
bounded memory, while the A* algorithm
might need exponential memory.
• All other characteristics of SMA* are inherited
from A*.
`

You might also like