图搜索算法

时间:2008-09-09 20:54:56

标签: graph-theory graph-algorithm

我正在寻找具有一些不寻常属性的图算法。

图表中的每条边都是“向上”边缘或“向下”边缘。

有效路径可以是无限数量的“向上”,然后是无限数量的“向下”,反之亦然。然而,它不能多次改变方向。

,例如,有效路径可能是A“向上”B“向上”C“向下”E“向下”F 无效路径可能是“向上”B“向下”C“向上”D

找到两个节点之间最短有效路径的好算法是什么?如何找到所有等长的最短路径?

5 个答案:

答案 0 :(得分:11)

假设您没有任何启发式方法,dijkstra's algorithm的变体就足够了。每次考虑新边缘时,都要存储有关其“祖先”的信息。然后,检查不变量(仅一个方向更改),如果违反则回溯。

这里的祖先是沿着最短路径到达当前节点的所有边缘。存储祖先信息的一种好方法是作为一对数字。如果U为up且D为down,则特定边缘的祖先可以为UUUDDDD,即3, 4对。由于不变量,你不需要第三个数字。

由于我们使用了dijkstra算法,因此找到了多条最短路径。

答案 1 :(得分:4)

也许您可以将图表转换为常规有向图,然后使用现有算法。

一种方法是将图形分成两个图形,一个具有所有上边缘,一个具有所有下边缘,并且在图形1上的所有节点和图形2上的相应节点之间具有有向边缘。

首先解决从图1开始到图2结束然后反过来,然后检查最短的解决方案。

答案 2 :(得分:2)

有人会认为你的标准BFS应该适用于此。无论何时将节点添加到打开列表中,都可以将其包装到一个结构中,该结构包含它所使用的方向(向上或向下)以及一个布尔标志,指示它是否已切换方向。这些可用于确定该节点的哪些传出边有效。

要查找长度相等的所有最短路径,请包括结构中到目前为止遍历的边数。当您找到第一条最短路径时,请记下路径长度并停止将节点添加到打开的列表中。继续浏览列表中的其余节点,直到检查了当前长度的所有路径,然后停止。

答案 3 :(得分:2)

具有特制成本(G分数)和启发式(H分数)功能的

A*可以处理它。

对于成本,您可以跟踪路径中方向更改的数量,并在第二次更改时添加无限成本(即切断对这些分支的搜索)。

启发式需要更多的思考,特别是当你想保持启发式允许(永远不会过高估计与目标的最小距离)和单调时。 (只有这样才能保证A *找到最佳解决方案。)

也许有关于可用于创建启发式的域的更多信息? (即图中节点的x,y坐标?)

当然,根据您想要解决的图形的大小,您可以首先尝试更简单的算法,例如广度优先搜索或Dijkstra算法:基本上每个搜索算法都可以,并且对于每个算法,您将需要一个成本函数(或者类似的)无论如何。

答案 4 :(得分:1)

如果你有一个标准的图搜索功能,比如库中的Graph.shortest(from, to),你可以用C#/伪代码循环和最小化:

[ (fst.shortest(A, C) + nxt.shortest(C, B)) 
    for C in nodes , (fst, nxt) in [(up, down), (down, up)] ].reduce(min)

如果您需要记住最小路径/路径,那么您的标准函数会返回数据,您也可以发音

[ [fst, nxt, C, fst.shortest(A, C), nxt.shortest(C,B)]
    for C in nodes , (fst, nxt) in [(up, down), (down, up)] ].reduce(myMin)

其中myMin应该比较两个[fst, nxt, C, AC, BD]元组并保留距离较低的元组,或两者都假设reduce是智能函数。

如果我们的图表很大并且根本不使用内存(如果它们是动态生成的话可能的话),这会产生一些内存开销,但实际上没有任何速度开销,imho。