Download as pdf
Download as pdf
You are on page 1of 8
Artificial Intelligence Dr.Ghaidaa Almulla Morning Study fr Ass.tec.Nibras Ridha Practical Lecture -5 ‘Ass.tec. Huda Sameer Best-First Search Algorithm in Python Greedy Best Search Greedy best-first search algorithm always selects the path which appears best at that moment. It is the combination of depth-first search and breadth-first search algorithms. It uses the heuristic function and search. Best-first search allows us to take the advantages of both algorithms. With the help of best-first search, at each step, we can choose the most promising node. In the best first search algorithm, we expand the node which is closest to the goal node and the closest cost is estimated by heuristic function, i.e. f(n)= g(n). Were, h(n)= estimated cost from node n to the goal. The greedy best first algorithm is implemented by the priority queue. Best first search algorithm steps: 2 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. 2 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. 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. Artificial Intelligence Dr.Ghaidaa Almulla Morning Study fr Ass.tec.Nibras Ridha Practical Lecture -5 ‘Ass.tec. Huda Sameer Example: We have created a graph from a map in this problem, actual distances is used in the graph. The goal is to find the shortest path from one city to another city. We are using a Graph class and a Node class in the best-first search algorithm. We are using straight-line distances (air-travel distances) between cities as our heuristic, these distances will never overestimate the actual distances between cities. # This class represent a graph class Graph: # Initialize the class def _init_(self, graph_dict=None, directed=True): self.graph_dict = graph_dict or {} self.directed = directed Af not directed: self.make_undirected() # Ciwate aa WRASeucked gregh By: uading: symmetete ayes dot make_undirected (self) : for a in list (self.graph_ dict .keys()): for (b, dist) in self.graph dict [a].items(): self.graph_dict.setdefault (b, {}) [a] - dist # Add a link from A and B of given distance, and also the inverse link if the graph is undirected def connect (self, A, B, distanc: self.graph_dict.setdefault(a, {}) [B] = distance if not self.directed self.graph_dict.setdefault(B, {))[A] - distance 4 Get neighbors or a neighbor Artificial Intelligence Dr.Ghaidaa Almulla Morning Study fr Ass.tec.Nibras Ridha Practical Lecture -5 Ass.tec. Huda Sameer def get (self, a, b=None): links = self.graph_dict setdefault(a, (}) if b is None: return links else: return links.get (b) # Return a list of nodes in the graph def nodes (sel£): al set ([k for k in self.graph_dict-keys()]) 82 set([k2 for v in self.graph_dict.values() for k2, v2 in v.items() |) nodes = s1-union(s2) return list (nodes) # This class represent a node class Node: # Initialize the class def _init__(self, name:str, parent:str): self.name = name self.parent = parent self.g - 0 # Distance to start node self.h = 0 # Distance to goal node self.£ 0 # Total cost # Compare nodes def _eq_ (self, other): return self.name -= other.nane # Sort nodes Artificial Intelligence Dr.Ghaidaa Almulla Morning Study fr Ass.tec.Nibras Ridha Practical Lecture -5 Ass.tec. Huda Sameer def _lt_(self, other): return self.f < other.£ # Print node def __repr__(self): return ('({0},{1})'.format (self-position, self.f)) | # Best-first search def best_first_search (graph, heuristics, start, end): # Create lists for open nodes and closed nodes open = [] closed = [] # Create a start node and an goal node etart_node ~ Node (start, None) goal_node = Node (end, None) # Add the start node open. append (start_node) # Loop until the open list is empty while len (open) > 0: # Sort the open list to get the node with the lowest cost first open. sort () # Get the node with the lowest cost current_node = open. pop (0) # Add the current node to the closed list closed. append (current_node) # Check if we have reached the goal, return the path Af current_node goal_nede: path = [J Artificial Intelligence Dr.Ghaidaa Almulla Morning Study fr Ass.tec.Nibras Ridha Practical Lecture -5 Ass.tec. Huda Sameer while current_node != start_node: path. append (current_node.name + ': ' + atr(current_node.g)) current_node = current_node.parent path.append(start_node.name + ': ' + str(start_node.g)) # Return reversed path return path[::-1] # Get neighbours neighbors = graph.get (current_node-name) ¥ Loop neighbors for key, value in neighbors. items (): # Create a neighbor node neighbor ~ Node (key, current_node) # Check if the neighbor is in the closed list if (neighbor in closed) : continue # Calculate cost to goal neighbor.g = current _node.g + graph.get (curven neighbor. name) node .name, neighbor-h = heuristics.get (neighbor .name) neighbor.£ - neighbor. # Check if neighbor is in open list and if it has a lower f value if(add_to_open(open, neighbor) True): # Everything is green, add neighbor to open list open. append (neighbor) # Return None, no path is found return None Artificial Intelligence Dr.Ghaidaa Almulla Morning Study Ass.tec.Nibras Ridha Practical Lecture -5 Ass.tec.Huda Sameer # Check if a neighbor should be added to open list def add_to_open (open, neighbor) : for node in open: Af (neighbor -- node and neighbor.£ >- node.£): return False I return True # The main entry point for this module def main(): # Czeate a graph graph = Graph () # Create graph connections (Actual distance) qraph.connact ("Frankfurt', 'Worsburg', 111) graph.connect ("Frankfurt', ‘Mannheim’, 85) graph.connect (*Wurzburg', ‘Nurnberg', 104) graph connect (‘Wurzburg', "Stuttgart’, 140) gqraph.connect (‘Wurzburg', ‘Ulm’, 183) graph.connect ("Mannheim', ‘Nurnberg', 230) graph.connect (‘Mannheim', 'xarlsruhe', 67) graph.connect ("Karisruhe', ‘Basel’, 191) graph.connect ("Karlsruhe', 'Stuttgart', 64) graph.connect (‘Nurnberg', 'Ulm', 171) graph.connect (*Nurnberg', ‘Munchen, 170) qraph.connect ("Nurnberg', ‘Passau’, 220) graph.connect ("Stuttgart', ‘Ulm’, 107) graph.connect ("Basel', 'Bern', 91) graph.connect ("Basel', ‘Zurich’, 85) I i | | | i | | | : | | | i | | | : | | | i | | | : | | | i | | i | | | : | | | i | | | | | | | | 1 | | | | | | | | | ba Artificial Intelligence Dr.Ghaidaa Almulla Morning Study Ass.tec.Nibras Ridha Practical Lecture -5 Ass.tec.Huda Sameer graph.connect ("Bern', ‘Zurich', 120) qraph.connect (*Zurich", 'Menmingen', 184) graph connect (*Memmingen', ‘Uim', 55) graph.connect ("Menmingen', ‘Munchen', 115) graph.connect ("Munchen', "Ulm", 123) graph.connect ("Munchen', 'Passau', 189) graph.connect (*Munchen', 'Rosenheim', 99) graph. connect ("Rosenheim', ‘Salzburg’, 81) graph.connect ("Passau', 'Linz", 102) graph .connect ('Sa1zbu: ‘Linz’, 126) # Make graph undirected, create eymmetric connections graph make undirected |) # Create heuristics (straight-line distance, air-travel distance) heuristics = () heuristics["Basel'] = 204 heuristics["Bern'] = 247 heuristics['Frankfurt'] = 215 137 heuristics ['Karlsruhe"] heuristics["Linz'] - 318 heuristics ['Mannheim'] = 164 heuristics {'Munchen')] = 120 heuristics['memmingen'] = 47 heuristics['Nurnberg'] = 132 heuristics["Passau'] = 257 heuristics [‘Rosenheim'] = 168 Artificial Intelligence Dr.Ghaidaa Almulla Morning Study fr Ass.tec.Nibras Ridha Practical Lecture -5 Ass.tec. Huda Sameer heuristice|‘stuttgart') = 75 heuristics['Salzburg'] = 236 i ucisticet wuebors!l = 183 i heuristics['Zurich'] - 157 | heuristics["Ulm'] = 0 # Run search algorithm path = best_first_search(graph, heuristics, ‘Frankfurt’, ‘Ulm') print (path) print () # Tell python to run main method 4 mame "main": main) Output ['Frankfurt: 0', ‘Wurzburg: 111', "Ulm: 294")

You might also like