0% found this document useful (0 votes)
71 views10 pages

Lab 5 Ai

The document describes implementing greedy best-first search and A* search algorithms to solve 8-puzzle and route finding problems respectively. It includes code for defining Node, Puzzle and Solver classes to perform greedy search on the 8-puzzle problem. It also provides code for implementing the A* search algorithm to find the shortest path between nodes of a graph using a heuristic function.

Uploaded by

Atif Jalal
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
71 views10 pages

Lab 5 Ai

The document describes implementing greedy best-first search and A* search algorithms to solve 8-puzzle and route finding problems respectively. It includes code for defining Node, Puzzle and Solver classes to perform greedy search on the 8-puzzle problem. It also provides code for implementing the A* search algorithm to find the shortest path between nodes of a graph using a heuristic function.

Uploaded by

Atif Jalal
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 10

Bahria University CSL-411: Artificial Intelligence Lab

Department of Computer Science BSIT-Semester 06 (Fall 2021)


Atif Jalal
02-235191-027

Lab 05: Informed Search (Greedy and A* Algorithms)

Exercise 1& 2 (Greedy best first search)

Write a python program that solves the following 8 puzzle problem using greedy best first
search

1 5 4

3 7 2

6 8 0

Python Code:

import random
import itertools
import collections

class Node:
"""
A class representing an Solver node
- 'puzzle' is a Puzzle instance
- 'parent' is the preceding node generated by the solver, if any
- 'action' is the action taken to produce puzzle, if any
"""
def __init__(self, puzzle, parent=None, action=None):
self.puzzle = puzzle
self.parent = parent
self.action = action

@property
def state(self):
"""
CS Department, BUKC 2/4 Semester 6 (Fall 2021)
CSL-411: AI Lab Lab 05: Greedy and A* Algorithms

Return a hashable representation of self


"""
return str(self)

@property
def path(self):
"""
Reconstruct a path from to the root 'parent'
"""
node, p = self, []
while node:
p.append(node)
node = node.parent
yield from reversed(p)

@property
def solved(self):
""" Wrapper to check if 'puzzle' is solved """
return self.puzzle.solved

@property
def actions(self):
""" Wrapper for 'actions' accessible at current state """
return self.puzzle.actions

def __str__(self):
CS Department, BUKC 3/4 Semester 6 (Fall 2021)
CSL-411: AI Lab Lab 05: Greedy and A* Algorithms

return str(self.puzzle)

class Solver:
"""
An '8-puzzle' solver
- 'start' is a Puzzle instance
"""
def __init__(self, start):
self.start = start

def solve(self):
"""
Perform breadth first search and return a path
to the solution, if it exists
"""
queue = collections.deque([Node(self.start)])
seen = set()
seen.add(queue[0].state)
while queue:
node = queue.pop()
if node.solved:
return node.path

for move, action in node.actions:


child = Node(move(), node, action)
CS Department, BUKC 4/4 Semester 6 (Fall 2021)
CSL-411: AI Lab Lab 05: Greedy and A* Algorithms

if child.state not in seen:


queue.appendleft(child)
seen.add(child.state)

class Puzzle:
"""
A class representing an '8-puzzle'.
- 'board' should be a square list of lists with integer entries 0...width^2 - 1
e.g. [[1,2,3],[4,0,6],[7,5,8]]
"""
def __init__(self, board):
self.width = len(board[0])
self.board = board

@property
def solved(self):
"""
The puzzle is solved if the flattened board's numbers are in
increasing order from left to right and the '0' tile is in the
last position on the board
"""
N = self.width * self.width
return str(self) == ''.join(map(str, range(1,N))) + '0'

@property
def actions(self):
CS Department, BUKC 5/4 Semester 6 (Fall 2021)
CSL-411: AI Lab Lab 05: Greedy and A* Algorithms

"""
Return a list of 'move', 'action' pairs. 'move' can be called
to return a new puzzle that results in sliding the '0' tile in
the direction of 'action'.
"""
def create_move(at, to):
return lambda: self._move(at, to)

moves = []
for i, j in itertools.product(range(self.width),
range(self.width)):
direcs = {'R':(i, j-1),
'L':(i, j+1),
'D':(i-1, j),
'U':(i+1, j)}

for action, (r, c) in direcs.items():


if r >= 0 and c >= 0 and r < self.width and c < self.width and \
self.board[r][c] == 0:
move = create_move((i,j), (r,c)), action
moves.append(move)
return moves

def shuffle(self):
"""
Return a new puzzle that has been shuffled with 1000 random moves
CS Department, BUKC 6/4 Semester 6 (Fall 2021)
CSL-411: AI Lab Lab 05: Greedy and A* Algorithms

"""
puzzle = self
for _ in range(1000):
puzzle = random.choice(puzzle.actions)[0]()
return puzzle

def copy(self):
"""
Return a new puzzle with the same board as 'self'
"""
board = []
for row in self.board:
board.append([x for x in row])
return Puzzle(board)

def _move(self, at, to):


"""
Return a new puzzle where 'at' and 'to' tiles have been swapped.
NOTE: all moves should be 'actions' that have been executed
"""
copy = self.copy()
i, j = at
r, c = to
copy.board[i][j], copy.board[r][c] = copy.board[r][c], copy.board[i][j]
return copy
CS Department, BUKC 7/4 Semester 6 (Fall 2021)
CSL-411: AI Lab Lab 05: Greedy and A* Algorithms

def pprint(self):
for row in self.board:
print(row)
print()

def __str__(self):
return ''.join(map(str, self))

def __iter__(self):
for row in self.board:
yield from row

# example of use
board = [[1,5,4],[3,7,2],[6,8,0]]

puzzle = Puzzle(board)
puzzle = puzzle.shuffle()
s = Solver(puzzle)
p = s.solve()

for node in p:
print(node.action)
node.puzzle.pprint()
Output:
CS Department, BUKC 8/4 Semester 6 (Fall 2021)
CSL-411: AI Lab Lab 05: Greedy and A* Algorithms

Exercise 2 (Astar Algorithm)

Implement above network and calculate heuristic value of above network using formulae
√ ( y 2− y 1 )2 +( x 2−x 1 )2 . Write Python program to implement A* Search Algorithms for above route
finding problem.

Python Code:
def aStarAlgo(start_node, stop_node):

open_set = set(start_node)
closed_set = set()
g = {}
parents = {}
g[start_node] = 0
parents[start_node] = start_node

while len(open_set) > 0:


n = None

for v in open_set:
if n == None or g[v] + heuristic(v) < g[n] + heuristic(n):
n=v

if n == stop_node or Graph_nodes[n] == None:


pass
else:
for (m, weight) in get_neighbors(n):

if m not in open_set and m not in closed_set:


open_set.add(m)
parents[m] = n
g[m] = g[n] + weight
CS Department, BUKC 9/4 Semester 6 (Fall 2021)
CSL-411: AI Lab Lab 05: Greedy and A* Algorithms

else:
if g[m] > g[n] + weight:

g[m] = g[n] + weight


parents[m] = n

if m in closed_set:
closed_set.remove(m)
open_set.add(m)

if n == None:
print('Path does not exist!')
return None

if n == stop_node:
path = []

while parents[n] != n:
path.append(n)
n = parents[n]

path.append(start_node)

path.reverse()

print('Path found: {}'.format(path))


return path

open_set.remove(n)
closed_set.add(n)

print('Path does not exist!')


return None

def get_neighbors(v):
if v in Graph_nodes:
return Graph_nodes[v]
else:
return None

def heuristic(n):
H_dist = {
'A': 11,
'B': 6,
'C': 99,
'D': 1,
CS Department, BUKC 10/4 Semester 6 (Fall 2021)
CSL-411: AI Lab Lab 05: Greedy and A* Algorithms

'E': 7,
'G': 0,

return H_dist[n]

Graph_nodes = {
'A': [('B', 2), ('E', 3)],
'B': [('C', 1),('G', 9)],
'C': None,
'E': [('D', 6)],
'D': [('G', 1)],

}
aStarAlgo('A', 'G')
Output:

You might also like