[经典] 深搜寻路问题

除了各种Dijkstra,Floyd算法,很多寻路问题都是带有条件,很难应用类似方法,这时的通用做法是深搜剪枝

1. 如POJ1724, N个城市, 编号1到N。城市间有R条单向道路。 每条道路连接两个城市,有长度和过路费两个属性。 Bob只有K块钱,他想从城市1走到城市N。问最短共需要走多长的路。如果到不了N,输出-1

2<=N<=100
0<=K<=10000
1<=R<=10000
每条路的长度 L, 1 <= L <= 100 每条路的过路费T , 0 <= T <= 100

解题思路:

【初始想法】从城市1开始DFS遍历整个图,找到所有能到达N的解法,选一个最优的。

【最优性剪枝】从城市1开始DFS遍历整个图,如果当前找到的最优解肯定没有上一个好了,则直接放弃。

【具体做法】保存中间计算结果,用于最优性剪枝。用midL[k][m] 表示:走到城市k时总过路费为m的条件下,最优路径的长度。若在 后续的搜索中,再次走到k时,如果总路费恰好为m,且此时的路径长度已经超过 midL[k][m],则不必再走下去了。 

【另外】还可以运用A*算法,预测一下从当前状态到解的状态至少要花的代价W(可以很粗略很乐观, 小于真实的最小代价),如果W加上到达当前状态时已经花费的代价,必 然不小于目前找到的最优解,则剪枝 

2. 限制更强的有指定途经点问题。N个城市,编号1到N。起点是1,终点是N(N<=16)。任意两个城市间都有路,A->B和B->A的路可能不一样长。 已知所有路的长度,问从1出发到达N且经每个城市恰好一次的最短路径的长度。

【最优性剪枝】的保存中间计算结果的做法,但如何存储到某个状态的“目前最小代价” 呢?状态由两部分构成: 1)已经走过的城市(除最后一个城市外,其他城市顺序不重要) 2) 走过的最后一个城市,除解状态以外的状态总数上限:14*2^14,可以用一个的14*2^14二维数组存放到达某个状态的“目前为止最小代价” 

【另外】运用A*算法,可是怎么预测从当前状态到解状态的至少代价? 假设还有 c1,c2....N 这k个城市还没有走到,则接下来一定要走k段两个城市间的道路,且这k段路终点分别是c1,c2 ... N,取终点为c1的路中最短的那条,再取终点为c2的路中最短的那条 .... 取终点为N的路中最短的那条。它们的长度之和,一定不大于把这k个城市都走到的最短路径的长度。 

转载于:https://www.cnblogs.com/littletail/p/5334146.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是使用DFS算法在有向图中寻找所有三节点以上的环径的matlab代码: ``` function [cycles] = find_cycles(graph) % FIND_CYCLES finds all cycles in a directed graph using DFS algorithm % Input: graph - adjacency matrix of the directed graph % Output: cycles - cell array containing all cycles in the graph n = size(graph, 1); visited = zeros(1, n); stack = zeros(1, n); top = 0; cycles = {}; for i = 1:n if visited(i) == 0 [visited, stack, top, cycles] = dfs(i, graph, visited, stack, top, cycles); end end end function [visited, stack, top, cycles] = dfs(node, graph, visited, stack, top, cycles) % DFS algorithm to recursively traverse the graph visited(node) = 1; stack(top+1) = node; top = top + 1; for i = 1:size(graph, 1) if graph(node, i) == 1 if visited(i) == 0 [visited, stack, top, cycles] = dfs(i, graph, visited, stack, top, cycles); elseif any(stack(1:top) == i) cycle = stack(top:-1, 1); cycle = [cycle, i]; cycles{end+1} = cycle; end end end top = top - 1; end ``` 该函数接受一个邻接矩阵作为输入,并返回一个包含所有环径的单元格数组。该算法使用深度优先搜索来遍历图,并在遇到已访问过的节点时检测是否有环。如果有环,则将其径添加到结果中。最后,返回所有找到的环径。 下面是一个使用示例: ``` graph = [0 1 0 0 0; 0 0 1 0 0; 1 0 0 1 1; 0 0 0 0 1; 0 0 0 1 0]; cycles = find_cycles(graph); ``` 这个例子中,我们输入了一个五个节点的有向图,并使用`find_cycles`函数找到了所有环。结果将存储在`cycles`变量中,其中每个单元格包含一个环径。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值