I'd like to ask you a question about the maze There is a maze like
1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 0 1 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 1
1 0 1 0 1 0 1 1 1 0 1 1 1 0 1 1 1 1 1 0 1
1 0 0 0 1 0 0 0 1 0 1 2 1 0 0 0 1 0 0 0 1
1 1 1 1 1 1 1 0 1 0 1 0 1 1 1 0 1 1 1 0 1
1 0 0 0 0 2 1 0 0 0 1 0 0 0 0 0 0 0 1 0 1
1 0 1 1 1 1 1 0 1 0 1 1 1 1 1 0 1 0 1 0 1
1 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 1
1 0 1 0 1 0 1 1 1 0 1 0 1 0 1 1 1 1 1 0 1
1 0 0 0 1 0 1 2 1 0 1 0 1 0 1 2 0 0 0 0 1
1 1 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 1 1
1 0 0 0 0 2 1 0 1 0 1 0 1 2 1 0 1 0 0 0 1
1 0 1 1 1 1 1 0 1 0 1 0 1 1 1 0 1 0 1 0 1
1 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 1
1 0 1 0 1 0 1 1 1 1 1 0 1 0 1 1 1 1 1 0 1
1 0 1 0 0 0 0 0 0 0 1 0 0 0 1 2 0 0 0 0 1
1 0 1 1 1 0 1 1 1 0 1 0 1 0 1 1 1 1 1 1 1
1 0 0 0 1 0 0 0 1 2 1 0 1 0 0 0 1 0 0 0 1
1 0 1 1 1 1 1 0 1 1 1 0 1 1 1 0 1 0 1 0 1
1 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 1 0 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1
The start is (0,1)
and The end is (20,19)
The number 1
represents the wall
, the number 0
represents the path
, and the number 2
represents the treasure
. There must be a path between treasures
What I want to do is start at the entrance, go through all the treasures and leave at the exit, hoping to find the shortest path, and record the order of the shortest path and the treasure traversal
I have tried the following code, but this code does not consider the treasure traversal order, but in a fixed traversal order, so I think it is wrong
import heapq
DIRECTIONS = [(0, 1), (0, -1), (1, 0), (-1, 0)]
def heuristic(a, b):
return abs(a[0] - b[0]) + abs(a[1] - b[1])
def a_star_search(graph, start, end):
frontier = []
heapq.heappush(frontier, (0, start))
came_from = {}
cost_so_far = {}
came_from[start] = None
cost_so_far[start] = 0
while frontier:
current = heapq.heappop(frontier)[1]
if current == end:
break
for dx, dy in DIRECTIONS:
next_node = (current[0] + dx, current[1] + dy)
if (0 <= next_node[0] < len(graph) and 0 <= next_node[1] < len(graph[0]) and
graph[next_node[0]][next_node[1]] != 1):
new_cost = cost_so_far[current] + 1
if next_node not in cost_so_far or new_cost < cost_so_far[next_node]:
cost_so_far[next_node] = new_cost
priority = new_cost + heuristic(end, next_node)
heapq.heappush(frontier, (priority, next_node))
came_from[next_node] = current
path = []
while current is not None:
path.append(current)
current = came_from[current]
path.reverse()
return path
def write_list_to_file(lst, filename):
with open(filename, 'w') as file:
for row in lst:
file.write(' '.join(str(element) for element in row))
file.write('\n')
def read_list_from_file(filename):
lst = []
with open(filename, 'r') as file:
for line in file:
row = [int(element) for element in line.strip().split()]
lst.append(row)
return lst
graph = read_list_from_file('output.txt')
targets = [(i, j) for i, row in enumerate(graph) for j, cell in enumerate(row) if cell == 2]
write_list_to_file(targets,'target.txt')
start = (0, 1)
path = []
for end in targets:
path.extend(a_star_search(graph, start, end)[:-1])
start = end
path.extend(a_star_search(graph, start, (20, 19)))
print(path)
write_list_to_file(path,'pathalgorithm.txt')
My problem is not similar on the website, because I still need to consider the impact of the wall, so I hope to get your help
A day later I have tried to solve this problem, and I would like to ask everyone to help me check whether it is correct
def write_list_to_file(lst, filename):
with open(filename, 'w') as file:
for row in lst:
file.write(' '.join(str(element) for element in row))
file.write('\n')
def read_list_from_file(filename):
lst = []
with open(filename, 'r') as file:
for line in file:
row = [int(element) for element in line.strip().split()]
lst.append(row)
return lst
def heuristic(a, b):
return abs(a[0] - b[0]) + abs(a[1] - b[1])
def a_star_search(maze, start, end):
queue = [(0, start, [], 0)]
heapq.heapify(queue)
visited = set()
while queue:
_, current, path, cost = heapq.heappop(queue)
if current == end:
return path + [end]
if current in visited:
continue
visited.add(current)
for dx, dy in [(1, 0), (0, 1), (-1, 0), (0, -1)]:
x, y = current[0] + dx, current[1] + dy
if 0 <= x < len(maze) and 0 <= y < len(maze[0]) and maze[x][y] != 1:
heapq.heappush(queue, (cost + heuristic((x, y), end), (x, y), path + [current], cost + 1))
return None
def find_shortest_path(maze, start, end, treasures):
all_points = [start] + treasures + [end]
shortest_paths = {(a, b): a_star_search(maze, a, b) for a in all_points for b in all_points if a != b}
min_distance = float("inf")
min_path = None
for treasure_order in permutations(treasures):
total_distance = 0
path = [start]
for i in range(len(treasure_order)):
if i == 0:
a, b = start, treasure_order[i]
else:
a, b = treasure_order[i-1], treasure_order[i]
total_distance += len(shortest_paths[(a, b)]) - 1
path.extend(shortest_paths[(a, b)][1:])
total_distance += len(shortest_paths[(treasure_order[-1], end)]) - 1
path.extend(shortest_paths[(treasure_order[-1], end)][1:])
if total_distance < min_distance:
min_distance = total_distance
min_path = path
return min_path, min_distance
maze = read_list_from_file('output.txt')
start = (0, 1)
end = (20, 19)
treasures = [(x, y) for x in range(len(maze)) for y in range(len(maze[0])) if maze[x][y] == 2]
shortest_path, shortest_distance = find_shortest_path(maze, start, end, treasures)
print("Shortest path:", shortest_path)
print("Shortest distance:", shortest_distance)
treasures_order=[]
for path in shortest_path:
if path in treasures or path ==start or path == end:
treasures_order.append(path)
print(treasures_order)
write_list_to_file(shortest_path,'path3.txt')
The result is shortest_path
0 1
1 1
2 1
3 1
3 2
3 3
2 3
1 3
1 4
1 5
2 5
3 5
3 6
3 7
4 7
5 7
6 7
7 7
7 6
7 5
7 4
7 3
8 3
9 3
9 2
9 1
8 1
7 1
6 1
5 1
5 2
5 3
5 4
5 5
5 4
5 3
5 2
5 1
6 1
7 1
8 1
9 1
9 2
9 3
10 3
11 3
11 4
11 5
11 4
11 3
11 2
11 1
12 1
13 1
13 2
13 3
14 3
15 3
15 4
15 5
15 6
15 7
15 8
15 9
16 9
17 9
16 9
15 9
15 8
15 7
15 6
15 5
14 5
13 5
13 6
13 7
12 7
11 7
10 7
9 7
10 7
11 7
12 7
13 7
13 8
13 9
12 9
11 9
10 9
9 9
8 9
7 9
7 10
7 11
7 12
7 13
8 13
9 13
10 13
11 13
10 13
9 13
8 13
7 13
7 14
7 15
6 15
5 15
5 14
5 13
5 12
5 11
4 11
3 11
4 11
5 11
5 12
5 13
5 14
5 15
5 16
5 17
6 17
7 17
7 18
7 19
8 19
9 19
9 18
9 17
9 16
9 15
9 16
9 17
10 17
11 17
11 18
11 19
12 19
13 19
14 19
15 19
15 18
15 17
15 16
15 15
15 16
15 17
15 18
15 19
14 19
13 19
12 19
11 19
11 18
11 17
12 17
13 17
13 16
13 15
13 14
13 13
14 13
15 13
16 13
17 13
17 14
17 15
18 15
19 15
19 16
19 17
18 17
17 17
17 18
17 19
18 19
19 19
20 19
and the shortest_distance is 178 The traversal order of the treasure is
[(0, 1), (5, 5), (11, 5), (17, 9), (9, 7), (11, 13), (3, 11), (9, 15), (15, 15), (20, 19)]
I am not sure if this is the shortest path, so I still hope you can teach me,I would appreciate very much.
new question
I suddenly thought of a new question, I now do not want the shortest total path, but want to make the least number of turns, that is, as far as possible to take the shape of 'Z', please do you have any good suggestions