当前位置:   article > 正文

Python算法入门day7——栈和队列的应用(迷宫问题)_python 队列的应用迷宫问题

python 队列的应用迷宫问题

【题目描述】

给一个二维列表,表示迷宫(0表示通道,1表示围墙)。给出算法,求一条走出迷宫的路径。

一、栈——深度优先搜索

1.回溯法

2.思路:从一个节点开始,上下左右任意找下一个能走的点,当找不到能走的点时,退回上一个点寻找是否有其他方向的点。

3.使用栈存储当前路径

4.使用匿名函数lambda定义坐标上下左右走,可以看看下面这篇

Python中lambda使用简单小结_alxe_made的博客-CSDN博客_lambda python用法lambda简单介绍1. 什么是lambda 简单来说,编程中提到的 lambda 表达式,通常是在需要一个函数,但是又不想费神去命名一个函数的场合下使用,也就是指匿名函数。这一用法跟所谓 λ 演算(题目说明里的维基链接)的关系,有点像原子弹和质能方程的关系,差别其实还是挺大的。举例子说明:g = lambda x : x+1g(1)输出:2可以这样...https://blog.csdn.net/alxe_made/article/details/80496690?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522164820741516782184693638%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fall.%2522%257D&request_id=164820741516782184693638&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~first_rank_ecpm_v1~rank_v31_ecpm-1-80496690.142%5Ev5%5Epc_search_result_cache,143%5Ev6%5Econtrol&utm_term=python%E9%87%8Clambda%E6%80%8E%E4%B9%88%E7%94%A8&spm=1018.2226.3001.4187

  1. maze=[
  2. [1,1,1,1,1,1,1,1,1,1],
  3. [1,0,0,1,0,0,0,1,0,1],
  4. [1,0,0,1,0,0,0,1,0,1],
  5. [1,0,0,0,0,1,1,0,0,1],
  6. [1,0,1,1,1,0,0,0,0,1],
  7. [1,0,0,0,1,0,0,0,0,1],
  8. [1,0,1,0,0,0,1,0,0,1],
  9. [1,0,1,1,1,0,1,1,0,1],
  10. [1,1,0,0,0,0,0,0,0,1],
  11. [1,1,1,1,1,1,1,1,1,1]
  12. ]#1代表围墙,0代表可以走的路
  13. #匿名函数
  14. dirs=[
  15. #x代表行,y代表列
  16. lambda x,y:(x+1,y),#上
  17. lambda x,y:(x,y+1),#右
  18. lambda x,y:(x-1,y),#下
  19. lambda x,y:(x,y-1)#左
  20. ]
  21. def maze_path(x1,y1,x2,y2):#起点坐标(x1,y1),终点坐标(x2,y2)
  22. stack=[]
  23. test=1
  24. stack.append((x1,y1))
  25. while(len(stack)>0):#如果栈中没有元素,代表起点的上下左右都不通,推出循环
  26. curNode=stack[-1]#表示当前的坐标以及for循环以后的新坐标,因为栈是先进后出的,所以stack[-1]表示最后一个坐标
  27. if curNode[0]==x2 and curNode[1]==y2:#表示走到终点了
  28. for i in stack:
  29. print(i)
  30. return True
  31. for dir in dirs:
  32. nextNode=dir(curNode[0],curNode[1])#下一个坐标,每个curNode都表示一个元组:0表示第x行,1表示第y列
  33. #判断下一跳是否为0,如果是0则将nextNode保存到栈,标记任意数,然后break,下一跳
  34. if maze[nextNode[0]][nextNode[1]]== 0:#等于0表示能走
  35. stack.append(nextNode)#有路则保存到栈中
  36. maze[nextNode[0]][nextNode[1]]=2#标记已经走过的路
  37. break #能找到一个就直接下一跳
  38. else:#回退
  39. maze[nextNode[0]][nextNode[1]]=2#走不通也代表走过,所以也要标记一下
  40. stack.pop()#回退
  41. #栈空
  42. else:
  43. print("没有路")
  44. return False
  45. maze_path(1,1,8,8)

【运行代码】


二、队列——广度优先搜索

1.找终点

【解题思路】

从一个节点开始,寻找所有接下来能继续走的点,继续不断寻找,直到找到出口。

使用队列存储当前正在考虑的节点。

可以用这张图来解释,扩起来的是用来存储当前的节点,一个节点进站,之前的父节点需要出列

假设x=13是终点,则下面延伸就是:(红色的代表队列里存储的数)

1 2 3 4 5 6 7

1 2 3 4 5 6 7 8 9 #6出队,将8,9元素加入队列中

1 2 3 4 5 6 7 8 9 10 #接着7出队,将10元素加入队列中

1 2 3 4 5 6 7 8 9 10 11#依次出队进队操作,直到终点加入到队中,结束

1 2 3 4 5 6 7 8 9 10 11 12

1 2 3 4 5 6 7 8 9 10 11 12 13

 2.输出路径

【解题思路】

从终点开始倒着找起点,存储到列表中

出队序列: 1  2  3  4  5  6  7

哪点来的:-1  0  1  2  2  3  4 

假设7这个点是要找的终点,则返回原先来的那个点

所以7是由5过来的,所以跳转到下标2,然后5又是由3过来的,所以输出下标2,然后依次类推

输出下标 1,0,-1,得到路径。


【代码运算】

需要注意的是,要创建一个队列来存储移出队列的元素

  1. from collections import deque #导入队列
  2. #首先直接套用栈的迷宫和匿名函数
  3. maze=[
  4. [1,1,1,1,1,1,1,1,1,1],
  5. [1,0,0,1,0,0,0,1,0,1],
  6. [1,0,0,1,0,0,0,1,0,1],
  7. [1,0,0,0,0,1,1,0,0,1],
  8. [1,0,1,1,1,0,0,0,0,1],
  9. [1,0,0,0,1,0,0,0,0,1],
  10. [1,0,1,0,0,0,1,0,0,1],
  11. [1,0,1,1,1,0,1,1,0,1],
  12. [1,1,0,0,0,0,0,0,0,1],
  13. [1,1,1,1,1,1,1,1,1,1]
  14. ]#1代表围墙,0代表可以走的路
  15. #匿名函数
  16. dirs=[
  17. #x代表行,y代表列
  18. lambda x,y:(x+1,y),#上
  19. lambda x,y:(x,y+1),#右
  20. lambda x,y:(x-1,y),#下
  21. lambda x,y:(x,y-1)#左
  22. ]
  23. #输出路径
  24. def print_r(path):
  25. #path里最后一个元素是终点
  26. curNode=path[-1]#终点
  27. realpath=[]#新列表
  28. #当第三个元素不是-1一直循环
  29. while curNode[2]!=-1:
  30. #如果不是-1,则把curNode放入新的列表里
  31. realpath.append((curNode[0],curNode[1]))
  32. #curNode[2]是由上一个点(len(path)-1)得来的
  33. #所以这样可以得到上一个点
  34. curNode=path[curNode[2]]
  35. #当等于-1时候,代表起点,将起点输出
  36. realpath.append((curNode[0],curNode[1]))
  37. realpath.reverse()#倒序
  38. for node in realpath:
  39. print(node)
  40. def maze_path_queue(x1,y1,x2,y2):
  41. queue=deque()#创建一个队列
  42. queue.append((x1,y1,-1))#创建三维列表(起点坐标,下标)
  43. path=[] #用于存储被队列移除的数的下标
  44. while len(queue)>0:#队列为空的时候表示上下左右都走不通
  45. curNode=queue.popleft()#表示移出队列的第一个数
  46. path.append(curNode)
  47. if curNode[0]==x2 and curNode[1]==y2:
  48. #找到终点,输出所有路径
  49. print_r(path)
  50. for dir in dirs:
  51. nextNode = dir(curNode[0],curNode[1])
  52. if maze[nextNode[0]][nextNode[1]]==0:
  53. queue.append((nextNode[0],nextNode[1],len(path)-1))
  54. maze[nextNode[0]][nextNode[1]]=2 #标记为已经走过的路
  55. #广义搜索不需要break
  56. #当队列为空时
  57. else:
  58. print("队列为空")
  59. return False
  60. maze_path_queue(1,1,8,8)

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/不正经/article/detail/703590
推荐阅读
相关标签
  

闽ICP备14008679号