迷宫问题
Stack Method
优点:代码简单
缺点:不一定是最短路径
自己写的
maze = [
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
[1, 0, 1, 0, 0, 1, 1, 1, 0, 1],
[1, 0, 0, 0, 1, 1, 0, 0, 0, 1],
[1, 0, 1, 0, 0, 1, 0, 1, 0, 1],
[1, 0, 0, 0, 0, 0, 0, 1, 0, 1],
[1, 1, 1, 0, 1, 1, 0, 0, 0, 1],
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
]
def maze_path(x1, y1, x2, y2):
stack = []
stack.append((x1, y1))
while (len(stack) > 0 and (x2, y2) != stack[-1]):
curNode = stack[-1]
maze[curNode[0]][curNode[1]] = 1
upNode = (curNode[0]-1, curNode[1])
rightNode = (curNode[0], curNode[1]+1)
downNode = (curNode[0]+1, curNode[1])
leftNode = (curNode[0], curNode[1]-1)
if not maze[upNode[0]][upNode[1]]:
stack.append(upNode)
continue
if not maze[rightNode[0]][rightNode[1]]:
stack.append(rightNode)
continue
if not maze[downNode[0]][downNode[1]]:
stack.append(downNode)
continue
if not maze[leftNode[0]][leftNode[1]]:
stack.append(leftNode)
continue
while (maze[curNode[0]][curNode[1]]):
stack.pop()
curNode = stack[-1]
# 要重新为四周点赋值
upNode = (curNode[0] - 1, curNode[1])
rightNode = (curNode[0], curNode[1] + 1)
downNode = (curNode[0] + 1, curNode[1])
leftNode = (curNode[0], curNode[1] - 1)
if not maze[upNode[0]][upNode[1]]:
stack.append(upNode)
break
if not maze[rightNode[0]][rightNode[1]]:
stack.append(rightNode)
break
if not maze[downNode[0]][downNode[1]]:
stack.append(downNode)
break
if not maze[leftNode[0]][leftNode[1]]:
stack.append(leftNode)
break
return stack
print(maze_path(1, 1, 5, 8))
教学中需要学习的
列表封装坐标
dirs = [
lambda x,y: (x+1, y),
lambda x,y: (x-1, y),
lambda x,y: (x, y-1),
lambda x,y: (x, y+1)
]
Queue Method
自己写的
import collections
maze = [
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
[1, 0, 1, 0, 0, 1, 1, 1, 0, 1],
[1, 0, 0, 0, 1, 1, 0, 0, 0, 1],
[1, 0, 1, 0, 0, 1, 0, 1, 0, 1],
[1, 0, 0, 0, 0, 0, 0, 1, 0, 1],
[1, 1, 1, 0, 1, 1, 0, 0, 0, 1],
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
]
def maze_path1(x1, y1, x2, y2):
queue = collections.deque()
queue.append((x1, y1))
queComplete = [
[(x1, y1)],
[-1]
]
dirs = [
lambda x, y: (x + 1, y),
lambda x, y: (x - 1, y),
lambda x, y: (x, y - 1),
lambda x, y: (x, y + 1)
]
while len(queue):
tmp = queue.copy()
for que in tmp:
for dir in dirs:
nextNode = dir(que[0], que[1])
if not maze[nextNode[0]][nextNode[1]]:
queComplete[0].append(nextNode)
queComplete[1].append(queComplete[0].index(que))
queue.append(nextNode)
maze[nextNode[0]][nextNode[1]] = 2
if nextNode == (x2, y2):
return queComplete
continue
queue.popleft()
# print(maze_path1(1, 1, 5, 8))
li = maze_path1(1, 1, 5, 8)
print(li)
queue1 = collections.deque()
index = len(li[0]) - 1
while (index > -1):
queue1.appendleft(li[0][index])
index = li[1][index]
print(queue1)
教学中需要学习的
while循环每次出队一个元素即可保证顺序,不需要特意关注同时进行的几步
在队列首位的步骤一定是最先进行的步骤,因此不会存在后步先走的情况
def maze_path_queue(x1, y1, x2, y2):
queue = deque()
queue.append((x1, y1, -1))
path = []
while len(queue)>0:
curNode = queue.pop()
path.append(curNode)
for dir in dirs:
nextNode = dir(curNode[0], curNode[1])
if maze[nextNode[0]][nextNode[1]] == 0:
queue.append((nextNode[0], nextNode[1], len(path)-1))
maze[nextNode[0]][nextNode[1]] = 2