AI Lab File Main
AI Lab File Main
1 Implementation of A*
algorithm
2 Write a C program to
find sum and average
of three numbers.
4 Solving 8 puzzle
problem
5 Graph Coloring
6 Implementation of
Breadth First Search
and Depth First Search
7 Hill Climbing
implementation
Q 1. Implementation of A* algorithm
Code:
import heapq
while open_set:
_, current_g, current = heapq.heappop(open_set)
if current == goal:
path = []
while current in came_from:
path.append(current)
current = came_from[current]
path.append(start)
return path[::-1]
for neighbor, weight in graph[current].items():
tentative_g = g_score[current] + weight
if tentative_g < g_score[neighbor]:
came_from[neighbor] = current
g_score[neighbor] = tentative_g
f_score = tentative_g + heuristic[neighbor]
heapq.heappush(open_set, (f_score, tentative_g, neighbor))
return None
# Example usage
if __name__ == "__main__":
# Sample graph represented as an adjacency list with weights
graph = {
'A': {'B': 1, 'C': 4},
'B': {'A': 1, 'C': 2, 'D': 5},
'C': {'A': 4, 'B': 2, 'D': 1},
'D': {'B': 5, 'C': 1}
}
Output:
Q2. Implementation of AO* algorithm
Code:
import heapq
while open_set:
_, current_g, current = heapq.heappop(open_set)
if current == goal:
path = []
while current in came_from:
path.append(current)
current = came_from[current]
path.append(start)
return path[::-1]
for neighbor, weight in graph[current].items():
tentative_g = g_score[current] + weight
if tentative_g < g_score[neighbor]:
came_from[neighbor] = current
g_score[neighbor] = tentative_g
f_score = tentative_g + heuristic[neighbor]
heapq.heappush(open_set, (f_score, tentative_g, neighbor))
return None
# Example usage
if __name__ == "__main__":
# Sample graph represented as an adjacency list with weights
graph = {
'A': {'B': 1, 'C': 4},
'B': {'A': 1, 'C': 2, 'D': 5},
'C': {'A': 4, 'B': 2, 'D': 1},
'D': {'B': 5, 'C': 1}
}
Output:
Q3. Solution for water jug problem
Code:
while queue:
jug_a, jug_b, path = queue.pop(0)
if jug_a == target or jug_b == target:
return path + [(jug_a, jug_b)]
if (jug_a, jug_b) in visited:
continue
visited.add((jug_a, jug_b))
# Fill jug A
if jug_a < capacity_a:
queue.append((capacity_a, jug_b, path + [(jug_a, jug_b)]))
# Fill jug B
if jug_b < capacity_b:
queue.append((jug_a, capacity_b, path + [(jug_a, jug_b)]))
# Empty jug A
if jug_a > 0:
queue.append((0, jug_b, path + [(jug_a, jug_b)]))
# Empty jug B
if jug_b > 0:
queue.append((jug_a, 0, path + [(jug_a, jug_b)]))
# Pour from A to B
if jug_a > 0 and jug_b < capacity_b:
pour = min(jug_a, capacity_b - jug_b)
queue.append((jug_a - pour, jug_b + pour, path + [(jug_a, jug_b)]))
# Pour from B to A
if jug_b > 0 and jug_a < capacity_a:
pour = min(jug_b, capacity_a - jug_a)
queue.append((jug_a + pour, jug_b - pour, path + [(jug_a, jug_b)]))
return None
# Example usage
if __name__ == "__main__":
solution = water_jug_problem(4, 3, 2)
print("Solution path:")
for step in solution:
print(f"Jug A: {step[0]}, Jug B: {step[1]}")
Output:
Q4. Solving 8 puzzle problem
Code:
class EightPuzzle:
def __init__(self, initial_state, goal_state):
self.initial_state = initial_state
self.goal_state = goal_state
def find_blank(self, state):
for i in range(3):
for j in range(3):
if state[i][j] == 0:
return i, j
def solve_bfs(self):
queue = [(self.initial_state, [])]
visited = set([self.state_to_string(self.initial_state)])
while queue:
state, path = queue.pop(0)
if state == self.goal_state:
return path + [state]
for next_state in self.get_possible_moves(state):
state_str = self.state_to_string(next_state)
if state_str not in visited:
visited.add(state_str)
queue.append((next_state, path + [state]))
return None
# Example usage
if __name__ == "__main__":
initial_state = [
[1, 2, 3],
[4, 0, 6],
[7, 5, 8]
]
goal_state = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 0]
]
if solution:
print(f"Solution found in {len(solution)-1} steps:")
for i, state in enumerate(solution):
print(f"Step {i}:")
for row in state:
print(row)
print()
else:
print("No solution found.")
Output:
Q5. Graph Coloring
Code:
def backtrack(vertex_index):
if vertex_index == len(graph):
return True
vertex = list(graph.keys())[vertex_index]
for color in colors:
if is_safe(vertex, color):
color_assignment[vertex] = color
if backtrack(vertex_index + 1):
return True
color_assignment.pop(vertex, None)
return False
if backtrack(0):
return color_assignment
return None
# Example usage
if __name__ == "__main__":
# Sample graph represented as an adjacency list
graph = {
'A': ['B', 'C'],
'B': ['A', 'C', 'D'],
'C': ['A', 'B', 'D'],
'D': ['B', 'C']
}
# Available colors
colors = ['Red', 'Green', 'Blue']
if solution:
print("Graph coloring solution:")
for vertex, color in solution.items():
print(f"Vertex {vertex}: {color}")
else:
print("No solution found.")
Output:
Q6. Implementation of Breadth First Search and Depth First Search
Code:
def backtrack(vertex_index):
if vertex_index == len(graph):
return True
vertex = list(graph.keys())[vertex_index]
for color in colors:
if is_safe(vertex, color):
color_assignment[vertex] = color
if backtrack(vertex_index + 1):
return True
color_assignment.pop(vertex, None)
return False
if backtrack(0):
return color_assignment
return None
# Example usage
if __name__ == "__main__":
# Sample graph represented as an adjacency list
graph = {
'A': ['B', 'C'],
'B': ['A', 'C', 'D'],
'C': ['A', 'B', 'D'],
'D': ['B', 'C']
}
# Available colors
colors = ['Red', 'Green', 'Blue']
if solution:
print("Graph coloring solution:")
for vertex, color in solution.items():
print(f"Vertex {vertex}: {color}")
else:
print("No solution found.")
dfs_recursive(start)
return path
# Example usage
if __name__ == "__main__":
# Sample graph represented as an adjacency list
graph = {
'A': ['B', 'C'],
'B': ['A', 'D', 'E'],
'C': ['A', 'F'],
'D': ['B'],
'E': ['B', 'F'],
'F': ['C', 'E']
}
Output:
Q7. Hill Climbing implementation
Code:
for _ in range(max_iterations):
neighbors = problem.get_neighbors(current)
if not neighbors:
break
# Find the neighbor with the best value according to heuristic
neighbor_values = [(n, heuristic(n)) for n in neighbors]
best_neighbor, best_value = max(neighbor_values, key=lambda x: x[1])
# If the best neighbor is not better than current, we've reached a local
maximum
if heuristic(current) >= best_value:
break
current = best_neighbor
return current
class HillClimbingProblem:
def __init__(self, initial_state):
self.initial_state = initial_state
def get_neighbors(self, state):
# This should be implemented for specific problems
pass
# Example usage
if __name__ == "__main__":
# Define a simple heuristic function (to be maximized)
# This one represents a 2D function with a peak at (5, 7)
def heuristic(state):
x, y = state
return -(x-5)**2 - (y-7)**2
Output: