我有一个有向图G =(V,E),其中边有权重。有些边可能有负权重,但G不包含任何负周期。
我有一组新的边S,如果添加到G,将导致负循环。我想确定哪些边缘在添加到G时会导致负循环。我怎么能这样做?
答案 0 :(得分:0)
我认为您可以使用delta-debugging算法解决这个问题。这最初是为识别导致程序崩溃的最小测试用例或最小变更集而设计的,但它也可以在这里工作。
在delta调试算法中,您从一些有效的配置开始并具有一组更改C,其中将C应用于基线配置将导致失败。如果假设C服从特定属性,那么只能进行O(| C | 2 )测试,确定一组最小的更改,这些更改将导致失败。所需的属性如下:如果S是一组导致失败的变化而且S⊆S'则S'也会导致失败。
在您的情况下,基线集是原始图,您的更改集是您添加到图中的边集。如果添加一组导致出现负循环的边,则添加包含这些边的任何集合也会导致出现循环。因此,如果你有一个包含m个节点,n个边,并且你有z个候选边的图,你可以在Bellman-Ford的O(z 2 )迭代中运行O((m + z)) n))确定将导致负循环出现的最小边集。运行时将是O(z 2 (m + z)n),对于小z来说也不算太差。
有关该算法的详细信息,请参阅the original paper或this set of lecture slides。
希望这有帮助!
答案 1 :(得分:0)
Ford-Bellman算法能够检测图形是否具有负权重的循环。如果您的问题可以重写,如
给定图
G = (V, E)
和一组边S,找出是否在图中添加一个边创建一个负权重周期。
对于这样的配方,这很容易 - 你只需逐个添加(并删除,如果没有找到循环)新边缘,并检查图形现在是否具有负循环。
如果您的任务更通用,例如
鉴于... [相同],找出S中边缘的最小子集,导致图形具有负循环
然后你需要经营福特 - 贝尔曼更多次。我的意思是,首先 - 对于所有添加的一个边的子集(如上所述),然后是两个边的所有子集,依此类推。