前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >深度优先搜索(DFS)两点之间的可行路径

深度优先搜索(DFS)两点之间的可行路径

作者头像
带萝卜
发布2020-10-23 11:39:46
2K0
发布2020-10-23 11:39:46
举报
文章被收录于专栏:我的机器学习之路

DFS是面试中常见的算法,在求路径问题中非常好用。

下面以一个图为例:

假如我们的目标是求点1到点6的所有路径,可以采用深度优先搜索法: 先将节点1加入路径,然后从1的后置节点中选择一个节点,1有两个后置节点,分别是2和3; 这里先选择2,路径为[1,2]; 然后再从2的后置节点中选择,只能选择4,路径为[1,2,4]; 从4的后置节点中选择5,路径为[1,2,4,5]; 从5的后置节点中选择6,路径为[1,2,4,5,6]形成一条完整的从1到6的路径。

这个问题可以由“求从1到6的所有路径”拆解成“从2到6的所有路径”和“从3到6的所有路径”两个问题,然后再往下依次拆解,这种形式的问题可以很方便地采用递归算法解决。

为了演示DFS算法的递归实现,要先将这个图转化为压缩邻接矩阵的形式

代码语言:javascript
复制
graph = [
[2,3],
[4],
[4,6],
[5],
[6],
]

然后进行DFS搜索

代码语言:javascript
复制
paths = []
path = []
def dfs(start,index,end,graph):
    path.append(index)
    if index == end:
        paths.append(path.copy())
        path.pop()

    else:
        for item in graph[index-1]:
            if item not in path:
                dfs(start,item,end,graph)
        path.pop()

dfs(1,1,6,graph)
for i,p in enumerate(paths):
    print("path %d" % i + str(p))
output:
path 0[1, 2, 4, 5, 6]
path 1[1, 3, 4, 5, 6]
path 2[1, 3, 6]

递归过程比较难理解,可以在代码中加入print语句,就可以很直观地查看到搜索过程了:

代码语言:javascript
复制
paths = []
path = []
def dfs(start,index,end,graph):
    path.append(index)
    if index == end:
        paths.append(path.copy())
        path.pop()
        print("找到终点%d,得到路径,往前回溯一位,查看节点%d是否有其他路径" % (index,path[-1]))

    else:
        print("依次搜索节点%d,%d的后置节点有 %s"% (index,index,str(graph[index-1])))
        for item in graph[index-1]:
            print("搜索节点%d的后置节点%d" % (index,item))
            if item not in path:
                dfs(start,item,end,graph)
        path.pop()
        if path != []:
            print("节点%d的后置节点搜索完毕,往前回溯一位,查看节点%d处是否有其他路径" % (index,path[-1]))
        else:
            print("循环结束,已无其他路径!")
dfs(1,1,6,graph)
for i,p in enumerate(paths):   
    print("path %d" % i + str(p))


[output]:
依次搜索节点1,1的后置节点有 [2, 3]
搜索节点1的后置节点2
依次搜索节点2,2的后置节点有 [4]
搜索节点2的后置节点4
依次搜索节点4,4的后置节点有 [5]
搜索节点4的后置节点5
依次搜索节点5,5的后置节点有 [6]
搜索节点5的后置节点6
找到终点6,得到路径,往前回溯一位,查看节点5是否有其他路径
节点5的后置节点搜索完毕,往前回溯一位,查看节点4处是否有其他路径
节点4的后置节点搜索完毕,往前回溯一位,查看节点2处是否有其他路径
节点2的后置节点搜索完毕,往前回溯一位,查看节点1处是否有其他路径
搜索节点1的后置节点3
依次搜索节点3,3的后置节点有 [4, 6]
搜索节点3的后置节点4
依次搜索节点4,4的后置节点有 [5]
搜索节点4的后置节点5
依次搜索节点5,5的后置节点有 [6]
搜索节点5的后置节点6
找到终点6,得到路径,往前回溯一位,查看节点5是否有其他路径
节点5的后置节点搜索完毕,往前回溯一位,查看节点4处是否有其他路径
节点4的后置节点搜索完毕,往前回溯一位,查看节点3处是否有其他路径
搜索节点3的后置节点6
找到终点6,得到路径,往前回溯一位,查看节点3是否有其他路径
节点3的后置节点搜索完毕,往前回溯一位,查看节点1处是否有其他路径
循环结束,已无其他路径!
path 0[1, 2, 4, 5, 6]
path 1[1, 3, 4, 5, 6]
path 2[1, 3, 6]

如此一来,是不是一目了然?

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档