【问题标题】:Best way to traverse an almost complete undirected weighted graph遍历几乎完整的无向加权图的最佳方法
【发布时间】:2014-04-22 22:24:14
【问题描述】:

需要有关以下问题http://acm.ro/prob/probleme/B.pdf的优化解决方案的帮助。

根据成本,我要么仅使用新边遍历图形,要么仅使用 旧的边缘,它们都可以工作,但我需要在有限的毫秒内通过测试, 旧边缘的算法正在拖我的后腿。

我需要一种优化方法,欢迎提出任何建议

编辑:出于安全原因,我正在取消算法,对不起,我是新手,所以我不 知道我需要做什么来删除帖子,因为它有答案

【问题讨论】:

标签: java algorithm graph graph-algorithm


【解决方案1】:

我最初的算法建议依赖于对问题的错误解读。此外,在这种大小的图表上进行教科书广度优先搜索或 Dijkstra 不太可能在合理的时间内完成。对于大型案件,您可能会采用提前终止的技巧; Niklas B.链接到的线程提出了几个(以及其他一些方法)。我找不到可以证明有效的提前终止技巧。

但是,这些微优化说明仍然相关:

我建议不要为此使用 Java 的内置 Queue 容器(或在编程竞赛中使用任何其他内置 Java 容器)。它将您的 4 字节 int 变成一个庞大的 Integer 结构。这很可能是您的爆炸的来源。您可以使用 500000 长的 int[] 将数据存储在队列中,而将两个整数用于队列的前后。通常,您希望避免在 Java 竞赛编程中实例化 Objects,因为它们会产生开销。

同样,我建议将图形的边缘表示为单个大 int[] 或 500000 长 int[][] 以减少那部分开销。

【讨论】:

  • 问题陈述说“每辆新火车都替换旧火车”,所以我认为您确实也必须对旧火车路线进行 BFS。
  • j_random_hacker 是对的,你可以使用旧的边缘,它们只是成本不同
  • 我不认为这是解决方案,很抱歉我忘了提及这一点,在某些测试中,您有大约 300000 个节点,它们最初都相互连接,然后是其中一些被替换(或者更确切地说是两条边之间的成本),我认为最好的方法是只遍历新边,因为这些边更少......
  • 我正在尝试按照@tmyklebu 所说的那样做,它适用于一个小矩阵,例如 [100][100],但是当我尝试制作 [100000+][100000+] 时,它崩溃了,它给了我一个内存不足的错误,有什么想法吗?
  • @user2288240:不要明确形成旧火车边。 BFS 仅在新火车边缘。我将把答案的第一段更新为一种很快就会起作用的算法;我最初误读了新火车与旧火车并列运行的问题。
【解决方案2】:

我在您的代码中只看到一个队列。这意味着您只能从一个方向搜索。

你可能想看看

Bidirectional Search

【讨论】:

  • 它说:“双向搜索是一种图搜索算法,它在有向图中找到从初始顶点到目标顶点的最短路径。”,这是一个无向图,不确定这是否适用它。
  • 你可以想象一个无向图是一个有向图(双向)。改进是指数级的。如果假设平均度数为k,距离为L。那么单向搜索大约是k^L,而双向搜索大约是2 * K^(L/2)
  • 我将如何实现它?使用 2 个队列?第二个我用 N (最后一个节点)初始化然后 while(!queue.isEmpty() && !newqueue.isEmpty()) 然后我从每个列表中轮询一个元素,这是它变得有点模糊,做你知道我可以遵循的好的伪代码,还是现有的代码?
  • 在具有 500000^2 条边的图中双向搜索仍然太慢(如果我没记错的话,最短路径的长度可能 > 5)
  • 你可能是对的 Niklas B,如果这个解决方案只是将时间减半,那还不够,但我仍然愿意在找到足够体面的实现后尝试它......跨度>
猜你喜欢
  • 1970-01-01
  • 2010-10-04
  • 1970-01-01
  • 1970-01-01
  • 2012-05-16
  • 2019-06-14
  • 2018-03-09
  • 1970-01-01
  • 2018-11-01
相关资源
最近更新 更多