深度优先,顾名思义是向纵深处遍历树或图,如下图所示:
遍历顺序为1–3–6–9–13–12–5–2–4–8–11–7–10
每次都看向树的右子树,当右子树全部看完后再回到树根向左看(回溯),因此采用堆栈的数据结构。
深度优先搜索遍历图
基本思想:深度优先搜索每次首先扩展最晚生成的节点分支,即搜索路线向“纵向”深入。每次搜索到分支的最深处时再使用回溯访问其它的分支。
因此,深度优先搜索使用了栈的数据结构。
算法描述:
- 把初始节点放入open表。
- 把open表的栈顶取出放入closed表。如果该节点可扩展,则将其子节点放入closed表。
- 如果节点的一个子节点是目标节点,则找到问题的解。
求最短路径
优化问题:
-
搜索深度
在实际搜索中,如果搜索到一条没有解的无穷分支,则不可能得到解,因此设置搜索深度是必要的,当搜索深度到达了界限则换一个分支进行搜索。但是在这种情况下可能搜索到的不是最优解,还有可能找不到解。
-
剪枝
使用深度优先寻找最短路径时,需要先把所有的可能路径找出来再作比较计算出最短路径。但是全部计算会大大增加搜索时间,因此,使用“剪枝”进行优化,即当前路径的长度小于当前最小路径长度时就放弃搜索当前分支,搜索其它分支。
python实现:
def DFS(start, end, depth_limit):
open.append([start, 0])
while len(open)>0:
# open出栈
currentNode = open.pop()
closed_count += 1
# closed表操作 把表中深度大于当前点的全部出栈,距离剪掉;然后当前点入栈
if currentNode[1] in cou:
count = currentNode[1]
for j in range(len(cou)):
if count==cou[j]:
loc = j
for j in range(loc, len(cou)):
tend = closed.pop()[0]
tstart = closed[len(closed)-1][0]
dis -= getdis(tstart, tend, nodes)
closed.append(currentNode)
dis += getdis(closed[len(closed)-2][0], currentNode[0], nodes)
# path
if currentNode[0]==end:
path = []
for n in closed:
path.append(n[0].id)
if dis<min:
min = dis
# 进栈
else :
# 找出所有邻居,邻居不在closed表内且深度小于限制且路径长度小于当前最小路径长度则入栈
for i in neighbour:
if nodes[i] not in nod and currentNode[1]<depth_limit and dis<min:
open.append([nodes[i], currentNode[1]+1])