1

我使用矩阵d来呈现图。 d.(i).(j)表示ij之间的距离; v表示图中节点的数量。检测图中是否存在负循环的最快算法

这个图表中可能有负循环。

我想检查是否存在负循环。我写的东西从Floyd-Warshall变化如下:

let dr = Matrix.copy d in 

(* part 1 *) 
for i = 0 to v - 1 do 
    dr.(i).(i) <- 0 
done; 

(* part 2 *) 
try 
    for k = 0 to v - 1 do 
    for i = 0 to v - 1 do 
     for j = 0 to v - 1 do 
      let improvement = dr.(i).(k) + dr.(k).(j) in 
      if improvement < dr.(i).(j) then (
      if (i <> j) then 
      dr.(i).(j) <- improvement 
      else if improvement < 0 then 
      raise BreakLoop) 
     done 
    done 
    done; 
    false 
with 
    BreakLoop -> true 

我的问题是

  1. 上面是正确的代码?
  2. part 1有用吗?

因为我经常调用这个函数,我真的想尽可能快地调用它。所以我的问题是如果其他算法(尤其是Bellman-Ford)可以比那更快?

回答

0

关于代码正确性的第一个问题更适合http://codereview.stackexchange.com


的任Bellman-FordFloyd-Warshall适合于这个问题。业绩比较如下:

由于|E||V|^2界,Bellman-Ford是明显的赢家,是什么,我会建议你使用。


如果图表没有负周期是预期的正常情况下,它可能是适当做一个快速检查作为你的算法的第一步:不图包含任何负面的边缘?如果不是,那么它当然不包含任何负循环,并且您有一个O(|E|)最佳案例算法用于检测是否存在任何负循环。

+1

感谢您的评论...由于我唯一的图形表示是一个矩阵,Bellman-Ford的维基页面中的每一个边(u,v)都带有边w:w的步骤仍然需要通过两个循环实现'对于i = 0到v-1做'对于j = 0到v-1做...'。所以对我而言,'| E |'和'| V |^2'完全相同,不是吗? – SoftTimur

+2

@SoftTimur哦,我错过了关于你使用图表矩阵的部分。在那种情况下,是的,他们是一样的。 :)考虑到这一点,我仍然认为Bellman-Ford具有*轻微*优势,因为空间复杂性较低,但我同意您也可以使用。 –

相关问题