1

任何人都可以帮助我更快地实现 Dijkstra 算法的 j2ME 吗?我有两个循环,一个在另一个里面。像这样

while(for each item in Q)
{
    //...do something.

    //the following loop is to find the minimum
    for(all un-visited nodes in Q)
    {
       //.. do something to get min.
    }
}

我有将近 23000 个节点和 50000 条边连接它们......在下面提到的所有改进之后,内部循环平均执行 169330131 次。在我的 w910i 手机上完成这需要 5 分钟,而在我的模拟器上则需要几分钟以上。这对我来说太过分了。有什么改进的建议吗?我已经实施了以下改进。

  1. 使用数组代替向量。
  2. 确保内部循环不考虑访问节点。我所有访问过的节点都在数组的末尾,我节点知道计数。所以,我可以很容易地完全跳过它们。
4

3 回答 3

2

我认为您在问题中的算法是错误的。内循环应该查看外循环中项目的每个未访问的邻居:

for each (item in Q)
{
  for each (unvisited neighbour of item)
  {
  }
}

将其与wikipedia 中的伪代码实现进行比较:

 1  function Dijkstra(Graph, source):
 2      for each vertex v in Graph:           // Initializations
 3          dist[v] := infinity               // Unknown distance function from source to v
 4          previous[v] := undefined          // Previous node in optimal path from source
 5      dist[source] := 0                     // Distance from source to source
 6      Q := the set of all nodes in Graph
        // All nodes in the graph are unoptimized - thus are in Q
 7      while Q is not empty:                 // The main loop
 8          u := vertex in Q with smallest dist[]
 9          if dist[u] = infinity:
10              break                         // all remaining vertices are inaccessible
11          remove u from Q
12          for each neighbor v of u:         // where v has not yet been removed from Q.
13              alt := dist[u] + dist_between(u, v) 
14              if alt < dist[v]:             // Relax (u,v,a)
15                  dist[v] := alt
16                  previous[v] := u
17      return previous[]
于 2009-05-10T07:59:16.410 回答
1

您的实施有问题。它的复杂度是 O(E + V * log2 (V))。

这意味着 50000 + 23000 * ~15 = 400 000 次迭代。

您当前的复杂性几乎是 O(V^2)。

于 2009-05-10T07:47:02.167 回答
1

我提到了这个算法。我在其他地方找到了一个更简单的算法。请注意,如果我必须在 Wikipedia 中实现一个,则有两个内部循环。

while Q is not empty: //Outer loop. 
  u := vertex in Q with smallest dist[];// First inner loop. 
  .... 
  for each neighbor v of u: //Second inner loop. 

第二个内环较小。它最多可以执行 4-5 次,因为每个节点最多有 5 条边。具有超过 2 条边的节点数量为 23000 个节点中的 1000 个。因此,内部循环的执行时间可以忽略不计。第一个内循环是问题所在。寻找最小的节点。由于我必须在 j2ME 设备上执行此操作,因此我必须使其占用尽可能少的空间。

于 2009-05-10T08:12:56.487 回答