AIMLLab 2
AIMLLab 2
1. A* Algorithm
1. def a_star(graph, heuristics, start, goal):
2.
3. open_set = PriorityQueue()
4. open_set.put((0, start))
5.
6.
7. g_score = {node: float('inf') for node in graph}
8. g_score[start] = 0
9.
10.
11. f_score = {node: float('inf') for node in graph}
12. f_score[start] = heuristics[start]
13.
14. # Dictionary to store the path
15. came_from = {}
16.
17. while not open_set.empty():
18. # Get the node with the lowest f(n)
19. current_f, current_node = open_set.get()
20.
21. # Check if the goal is reached
22. if current_node == goal:
23. return reconstruct_path(came_from, current_node)
24.
25. # Explore neighbors
26. for neighbor, weight in graph[current_node]:
27. # Calculate tentative g_score
28. tentative_g_score = g_score[current_node] + weight
29.
30. # If this path is better, update the values
31. if tentative_g_score < g_score[neighbor]:
32. came_from[neighbor] = current_node
33. g_score[neighbor] = tentative_g_score
34. f_score[neighbor] = tentative_g_score + heuristics[neighbor]
35. open_set.put((f_score[neighbor], neighbor))
36.
37. # If no path is found
38. return None
39.
40. def reconstruct_path(came_from, current_node):
41. path = []
42. while current_node in came_from:
43. path.append(current_node)
44. current_node = came_from[current_node]
45. path.append(current_node) # Add the start node
46. path.reverse()
47. return path
48.
49.
50.
51.
52.
53. # Input graph and heuristics
54. graph = {
55. 'C': [('A', 2), ('B', 1)],
56. 'A': [('B', 4), ('D', 3), ('C', 2)],
57. 'B': [('D', 3), ('E', 7), ('F', 1), ('A', 4), ('C', 1)],
58. 'D': [('E', 2), ('F', 1), ('B', 3), ('A', 3)],
59. 'E': [('F', 1), ('D', 2), ('B', 7)],
60. 'F': [('G', 1), ('H', 1), ('E', 1), ('D', 1), ('B', 1)],
61. 'G': [('H', 1), ('F', 1)],
62. 'H': [('G', 1), ('F', 1)]
63. }
64.
65. heuristics = {
66. 'A': 3,
67. 'B': 2,
68. 'C': 7,
69. 'D': 5,
70. 'E': 1,
71. 'F': 2,
72. 'G': 0,
73. 'H': 0
74. }
75.
76. # Start and goal nodes
77. start = 'C'
78. goal = 'G' # You can also try 'H'
79.
80. # Run A* algorithm
81. path = a_star(graph, heuristics, start, goal)
82.
83. # Output the result
84. if path:
85. print(f"Path from {start} to {goal}: {' -> '.join(path)}")
86. else:
87. print(f"No path found from {start} to {goal}.")
88.
Output:
Path from C to G: C -> B -> F -> G
2. A* Grid Algorithm
1. import heapq
2.
3. def a_star_grid(grid, start, goal, time_limit):
4. # Directions the agent can move: up, down, left, right
5. directions = [(-1, 0), (1, 0), (0, -1), (0, 1)]
6.
7. # Get the number of rows and columns in the grid
8. rows = len(grid)
9. cols = len(grid[0])
10.
11. # Check if the start or goal is blocked
12. if grid[start[0]][start[1]] == float('inf') or grid[goal[0]][goal[1]] == float('inf'):
13. return None, float('inf'), False
14.
15. # Priority queue to store nodes to be explored: (f(n), g(n), (x, y))
16. open_set = [(0, 0, start)]
17.
18. # Dictionary to store the cost to reach each node
19. g_score = {(i, j): float('inf') for i in range(rows) for j in range(cols)}
20. g_score[start] = 0
21.
22. # Dictionary to store the total estimated cost (f(n))
23. f_score = {(i, j): float('inf') for i in range(rows) for j in range(cols)}
24. f_score[start] = manhattan_distance(start, goal)
25.
26. # Dictionary to store the path
27. came_from = {}
28.
29. while open_set:
30. # Get the node with the lowest f(n)
31. current_f, current_g, (x, y) = heapq.heappop(open_set)
32.
33. # Check if the goal is reached
34. if (x, y) == goal:
35. path = reconstruct_path(came_from, (x, y))
36. total_cost = g_score[(x, y)]
37. feasible = total_cost <= time_limit
38. return path, total_cost, feasible
39.
40. # Explore neighbors
41. for dx, dy in directions:
42. nx, ny = x + dx, y + dy
43. if 0 <= nx < rows and 0 <= ny < cols: # Check if the neighbor is within the
grid
44. if grid[nx][ny] == float('inf'): # Skip blocked roads
45. continue
46.
47. # Calculate tentative g_score
48. tentative_g_score = g_score[(x, y)] + grid[nx][ny]
49.
50. # If this path is better, update the values
51. if tentative_g_score < g_score[(nx, ny)]:
52. came_from[(nx, ny)] = (x, y)
53. g_score[(nx, ny)] = tentative_g_score
54. f_score[(nx, ny)] = tentative_g_score + manhattan_distance((nx, ny),
goal)
55. heapq.heappush(open_set, (f_score[(nx, ny)], tentative_g_score, (nx,
ny)))
56.
57. # If no path is found
58. return None, float('inf'), False
59.
60. def manhattan_distance(a, b):
61. return abs(a[0] - b[0]) + abs(a[1] - b[1])
62.
63. def reconstruct_path(came_from, current):
64. path = []
65. while current in came_from:
66. path.append(current)
67. current = came_from[current]
68. path.append(current) # Add the start node
69. path.reverse()
70. return path
71.
72. # Input grid
73. grid = [
74. [1, 1, 5, 5, 1],
75. [1, 1, float('inf'), 5, 1],
76. [5, float('inf'), 1, 1, 1],
77. [1, 1, 1, float('inf'), 5],
78. [1, 5, 1, 1, 1]
79. ]
80.
81. # Start and goal positions
82. start = (0, 0)
83. goal = (4, 4)
84.
85. # Time limit
86. time_limit = 12
87.
88. # Run A* algorithm
89. path, total_cost, feasible = a_star_grid(grid, start, goal, time_limit)
90.
91. # Output the result
92. if path:
93. print(f"Optimal path: {path}")
94. print(f"Total traversal cost: {total_cost}")
95. print(f"Feasible within time limit? {'Yes' if feasible else 'No'}")
96. else:
97. print("No path found.")
98.
Output:
Optimal path: [(0, 0), (1, 0), (2, 0), (3, 0), (3, 1), (3, 2), (4, 2), (4, 3), (4, 4)]