Skip to content

Latest commit

 

History

History

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 
 
 
 
 

README.md

Search

Given two inputs, the intial state and the goal state, the AI will navigate to find the optimal solution of a series of actions

Search Problem Terms

Agent

Agent is an entity that perceives its environment and acts upon that environment. For instance, this entity could be an AI program, the environment could be the state of a chess game, and the AI will determine the action under that state, in another word, how to take the next move

State

A configuration of an agent in its environment, also can be understood as the state of the game in a chess game

Initial State

The state from which the search algorithm starts, the environment when the agent first kick in

Actions

All possible choices that can be made by an agent in a state

Transition Model

A description of what state results from performing any applicable action in any state
i.e. result(s, a) return the state in s by performing the action a

Screen Shot 2022-06-19 at 8 46 33 PM

State Space

The set of all states reachable from the initial state by any sequence of actions

Screen Shot 2022-06-19 at 8 46 55 PM

Goal Test

The condition that determines whether a given state is a goal state, if certain state passes the goal test, which means the algorithm should be terminated since we have found the solution

Path Cost

A numerical cost associated with a given path
The cost of each edge (between two vertices) could be 1 or more than 1
i.e. when navigating a path on the map, we do not only consider the distance but also trying to minimize the path cost, which in real life is the traffic condition on certain roads. If there's a bad traffic on a certain road, then the cost of that road is high

Screen Shot 2022-06-19 at 8 47 16 PM

Algorithms

Exhausts each one direction before trying another direction. If there are several possible ways, the agent will choose randomly. So, DFS might not be efficient to find the path due to this randomness, and it does not guarantee to find the shortest path

For example:

Screen Shot 2022-06-19 at 8 48 56 PM

OR

Screen Shot 2022-06-19 at 8 50 04 PM

DFS typically uses a stack data structure to store all of the possible actions. Below is the pseudo code for the DFS implementation

DFS(G,v)   ( v is the vertex where the search starts )
    Stack S := {};   ( start with an empty stack )
    for each vertex u, set visited[u] := false;
    push S, v;
    while (S is not empty) do
        u = pop S;

        if u is destination then
            return path from v to u

        if (not visited[u]) then
            visited[u] = true;
            for each unvisited neighbour w of u
                push S, w;

Follow multiple directions at the same time, taking one step in each possible direction before taking the second step in each direction
Guarantee the shortest path, but takes relatively a long time as it seeks each directions setp by step. Also, BFS only considers unweighted path and ignore the path cost, so it's more efficient to use A* when doing map navigation rather than BFS

Screen Shot 2022-06-19 at 8 48 21 PM

BFS typically uses a queue data structure to store all of the possible actions. Below is the pseudo code for the BFS implementation, the only difference between DFS and BFS is one uses stack and one uses queue

BFS (G, s)  (G is the graph and s is the source node)
    let Q be queue
    Q.enqueue( s )
    mark s as visited

    while ( Q is not empty)
        v  =  Q.dequeue( )

        if v is destination then
            return path from s to v

        for all neighbours w of v in Graph G
            if w is not visited
                Q.enqueue( w )

Example

Check out examples directory for Python implementation of DFS and BFS that solves mazes

At any time, choose the state that is closest to the goal as the next state (only consider the estimated cost to the goal), as estimated by a heuristic function h(n). However, it only consider the distance between the current node to the destination but not the cost to reach this node from the source. The greedy algorithm does not guarantee the shortest path

Screen Shot 2022-06-19 at 8 55 53 PM

Manhattan distance vs Euclidean distance. We use either of these to estimate the cost from current state to the goal, then choose the action that minimizes the cost

Consider both the cost of path until now and the estimated cost to the goal, g(n) + h(n)

  • g(n) = cumalative cost reaching the current node
  • h(n) = estimated cost to the destination node

Thus, A* is the best path search algorithm as it considers the distance, weight, cost, etc. and it guarantees to find the shortest path

Screen Shot 2022-06-19 at 8 53 16 PM

A* (G, s)  (G is the graph and s is the source node)

    # Order the queue by ascending order of g(n) + h(n)
    let Q be priority_queue
    Q.enqueue( s )
    mark s as visited

    while ( Q is not empty)
        v  =  Q.dequeue( )

        if v is destination then
            return path from s to v

        for all neighbours w of v in Graph G
            if w is not visited
                Q.enqueue( w )

Adversarial Search

A recursive or backtracking algorithm which is used in decision-making and game theory. It provides an optimal move for the player assuming that opponent is also playing optimally. For instance, in the figure below, the green player is trying to maximize the score and the red player is to minimize to score, which is exactly the same in any game

Screen Shot 2022-06-19 at 8 53 37 PM

An optimization technique for the Minimax Algorithm
For example, if we want to find the max of three nodes and we know the current node will be definitely less than the previous node, then we do not need to explore every other subnodes of it

Screen Shot 2022-06-19 at 8 53 53 PM

Depth-Limited Minimax

A type of Minimax Algorithm that only search to a certain depth, arrive at a decision more quickly

function minimax(node, depth, maximizingPlayer) is
    if depth == 0 or node is a terminal node then
        return static evaluation of node

    if MaximizingPlayer then    // for Maximizer Player
        maxEva= -infinity
        for each child of node do
        eva= minimax(child, depth-1, false)
        maxEva= max(maxEva,eva) //gives Maximum of the values
        return maxEva

    else    // for Minimizer player
        minEva= +infinity
        for each child of node do
        eva= minimax(child, depth-1, true)
        minEva= min(minEva, eva)    //gives minimum of the values
        return minEva

Examples

Check out some examples that practice these theories