通过小世界图找到路径的最有效方法是什么?

时间:2008-10-21 09:38:22

标签: algorithm graph-theory path-finding

我有一大堆加权节点,边缘将节点簇连接在一起。该图遵循典型的小世界布局。

我希望找到一种路径查找算法,它在处理器功率上并不昂贵,找到沿着最佳路径的路径,其中节点是最有利的加权,最快路径不是最重要的因素。 该算法还考虑了承载和流量重新路由。

(旁注:可以在这里使用神经网络吗?)

由于


我在看ACO。对于这类问题,还有比ACO更好的东西吗?


正确A*算法找到最低成本或最快路由,没有负载平衡。

假设最快或最短的路线不是最重要的路线,更重要的是遵循加权节点具有特定值的路径。 NO1。

NO 2。如果使用A *,该路由上的流量会过载,那么突然该路径是多余的。因此,与A *一样酷,它没有ACO的某些特征,即固有的负载平衡。

- 除非我误解并误解了A *

然后是什么击败了ACO?


它真的看起来像ACO和A *之间的展示,有很多关于A *的积极谈论,我一定会更深入地了解它。

首先回应大卫;我可以在后台运行ACO模拟并提出最佳路径,所以是的,有一个初始启动成本,但幸运的是,启动并不重要。所以我可以多次运行模拟。一个真正的麻烦是找到连接的源节点和目标节点。而A *似乎很容易就能做到这一点。现在当这个网络像数百万个节点一样变得非常大时会发生什么。 A *能否轻松扩展?

我将进一步研究A *。但是我给你留下了最后一个问题!

A *能否与Antnet(ACO)一样扩展?

7 个答案:

答案 0 :(得分:11)

一般说明

Dijkstra的算法及其优化的变体A *通过图表找到“最小”成本的路径。重要的是a)正确定义图表和b)定义适当的成本函数。

面对不断变化的成本函数,Dijksta需要重新计算解决方案。

对于负载平衡,我会扩展Dikstra,不仅要计算最佳路径,还要使用某种泛洪填充行为来创建一组可能的路径(按成本排序)以找到替代方案。只有关于具体问题和成本函数的知识才能回答这是否以及如何发挥作用。

另一方面,

Ant Colony Optimisation似乎在适应不断变化的成本函数方面更灵活,通过在成本函数改变之后/后继续迭代来实现。

效率

这在很大程度上取决于您的问题域。如果你有一个很好的启发式(参见Complexity section of the A* article)并且很少有成本变化,那么A *的多项式运行时可能有利于重复的重新计算。另一方面,ACO必须反复迭代才能收敛到近似解。如果非常频繁地发生成本变化,则以更快的速率继续迭代可能比更新A *解决方案更有效,因为信息保留在算法的状态内。 ACO不承诺 最佳解决方案,但可能在融入“良好”解决方案之前具有更高的启动成本。同样,这在很大程度上取决于您的特定领域,图表和成本函数以及您对最优性的要求。

答案 1 :(得分:8)

使用A *,路径成本不需要保持不变,因此您可以从下图开始:

A---1---B---1---C
|               |
\-------1-------/

我们想要从A到C.最初,路径寻找算法将选择A-C路径,因为A-B-C是2而A-C是1.我们可以在路径中添加一个额外的术语:

A---r---B---r---C
|               |
\-------r-------/

r(NM) = k(NM) + users(NM) / 10

,其中

r(NM) is the cost for a connection between N and M,
k(NM) is the constant cost for a connection between N and M,
users(NM) is the number of objects using the connection

当用户被添加到系统中时,路由AC将比20个用户(1 + 20/10)= 3的ABC更昂贵,ABC为2.当用户从系统中移除时,AC路由将变为最好的选择。

A *的实际功能是用于计算每个连接成本的启发式算法。

答案 2 :(得分:7)

这个问题最常用的算法是A* (A Star),这是一个带有添加启发式的广义Dijkstra's algorithm搜索 - 启发式的目的是将搜索指向搜索目标,以便进行典型搜索完成得更快。

此算法有许多变体,派生版本和改进,谷歌搜索或维基百科页面应该是一个很好的起点。

答案 3 :(得分:3)

绝对是A *。如果没有路径,A *将找到可能的最佳路径或根本没有路径。例如。这艘船的路径是用A *

计算的

A* Example on Game Map
(来源:cokeandcode.com

这是一个interactive Java Demo。请注意,此算法因睡眠而变慢,因此您会看到它正在执行。如果没有这种减速,它将在不到一秒的时间内找到路径。

算法简单但功能强大。每个节点有3个值,g是该节点的成本。 h是从该节点到目标的估计成本,f是两者的总和(它是对完整路径的猜测)。 A *维护两个列表,即打开和关闭列表。打开列表包含到目前为止尚未探索的所有节点。 Closed列出已探索的所有节点。如果算法已经测试了连接到该节点的每个节点,则节点计算为已探测(连接只能表示水平和垂直,但如果允许节点之间的对角线移动,则也是对角线。)

该算法可以描述为

  1. 让P为起点
  2. 将g,h和f值分配给P
  3. 将P添加到打开列表中(此时P是该列表中唯一的节点)。
  4. 让B成为打开列表中的最佳节点(最佳==最低f值)
    • 如果B是目标节点 - >退出,你找到了路径
    • 如果打开列表为空 - >退出,没有路径存在
  5. 设C是连接到B的有效节点
    • 将g,h和f分配给C
    • 检查C是打开还是关闭列表
      • 如果是,请检查新路径是否最有效(较低的f值)
        • 如果是,请更新路径
      • 否则将C添加到打开列表
    • 对连接到B
    • 的所有节点重复步骤5
  6. 将B添加到已关闭列表(我们探索了所有邻居)
  7. 从第4步开始重复。
  8. 另请参阅Wikipedia了解实施细节。

答案 4 :(得分:0)

普通的Dijkstra不够吗?

http://improve.dk/generic-dijkstras-algorithm/

答案 5 :(得分:0)

我听说过NN实现也可以解决这类问题。因此,如果您想使用NN,您最终会找到自己的方式;-)但与“遗传算法”相比,它们必须更低。

如果计算/时间消耗是一个问题,我强烈建议使用遗传算法。这就是他们特有的问题类型。

GA基于描述您对任何给定解决方案的满意度的函数。您可以修改此功能以满足您的需求(即,您不仅可以包括路径成本,还可以包括您希望的任何因素)。

答案 6 :(得分:0)

Dijkstras算法,你的小例子

graph = {}

graph["start"] = {}
graph["start"]["a"] = 6
graph["start"]["b"] = 2
graph["a"] = {}
graph["a"]["finish"] = 1
graph["b"] = {}
graph["b"]["a"] = 3
graph["b"]["finish"] = 5
graph["finish"] = {}

infinity = float("inf")
costs = {}
costs["a"] = 6
costs["b"] = 2
costs["finish"] = infinity
print "The weight of each node is: ", costs

parents = {}
parents["a"] = "start"
parents["b"] = "start"
parents["finish"] = None

processed = []

def find_lowest_cost_node(costs):
    lowest_cost = float("inf")
    lowest_cost_node = None
    for node in costs:
        cost = costs[node]
        if cost < lowest_cost and node not in processed:
            lowest_cost = cost
            lowest_cost_node = node
    return lowest_cost_node

node = find_lowest_cost_node(costs)
print "Start: the lowest cost node is", node, "with weight",\
    graph["start"]["{}".format(node)]

while node is not None:
    cost = costs[node]
    print "Continue execution ..."
    print "The weight of node {} is".format(node), cost
    neighbors = graph[node]
    if neighbors != {}:
        print "The node {} has neighbors:".format(node), neighbors
    else:
        print "It is finish, we have the answer: {}".format(cost)
    for neighbor in neighbors.keys():
        new_cost = cost + neighbors[neighbor]
        if costs[neighbor] > new_cost:
            costs[neighbor] = new_cost
            parents[neighbor] = node
    processed.append(node)
    print "This nodes we researched:", processed
    node = find_lowest_cost_node(costs)
    if node is not None:
        print "Look at the neighbor:", node

# to draw graph
import networkx
G = networkx.Graph()
G.add_nodes_from(graph)
G.add_edge("start", "a", weight=6)
G.add_edge("b", "a", weight=3)
G.add_edge("start", "b", weight=2)
G.add_edge("a", "finish", weight=1)
G.add_edge("b", "finish", weight=5)

import matplotlib.pyplot as plt
networkx.draw(G, with_labels=True)
plt.show()

print "But the shortest path is:", networkx.shortest_path(G, "start", "finish")