Algorithm 求给定图中最小范围生成树的算法

Algorithm 求给定图中最小范围生成树的算法,algorithm,graph,range,minimum,spanning-tree,Algorithm,Graph,Range,Minimum,Spanning Tree,给定一个权重为w(e)的加权无向图G(v,e),求每对顶点(u,v)的边集∈G是连接的(简而言之,生成树),并且所选边的权重范围最小(或者最小权重和最大权重之间的差值最小) 我尝试了贪婪的方法,根据权重对边进行排序,然后选择排序数组中连续边之间权重差最小的两条边(g[index=current_left],g[index+1=current_right]),然后根据排序数组中的最小权重差向左或向右移动(当前左,当前左-j)或(当前右,当前右+j),其中j递增,直到找到至少有一个未访问顶点的边 例

给定一个权重为w(e)的加权无向图G(v,e),求每对顶点(u,v)的边集∈G是连接的(简而言之,
生成树
),并且所选边的权重范围最小(或者最小权重和最大权重之间的差值最小)

我尝试了贪婪的方法,根据权重对边进行排序,然后选择排序数组中连续边之间权重差最小的两条边(g[index=current_left],g[index+1=current_right]),然后根据排序数组中的最小权重差向左或向右移动(当前左,当前左-
j
)或(当前右,当前右+
j
),其中
j
递增,直到找到至少有一个未访问顶点的边

例如:

这里我们可以得到的最小范围是通过选择权重为{2,3,5}的边,范围是3

请指出一个建议算法失败的测试用例,并建议一个寻找这种生成树的算法

编辑:


预期的时间复杂度为O(| E | log | E |),其中| E |是边数。

您应该能够在
O(E*(MST计算成本))
:

其思想是,某些边权重必须是最优生成树中边之间的最小边权重;因此,请确定最小边权重,并找到一个仅包含比该权重重的边的MST。由于所有MST也是,因此这将起作用


这里有一个改进,在对数平方因子下是最优的;基本思想保持不变

sort edge array E[] by increasing weights

low := high := 0
opt_low := opt_high := 0
opt := infinity
connected := false

while (high < E.length - 1) or (connected):

    if not connected:
        high = high + 1
    else:
        low = low + 1

    update(connected)

    if connected:
        if E[high].weight - E[low].weight < opt:
            opt = E[high].weight - E[low].weight
            opt_low = low
            opt_high = high

print(opt, opt_low, opt_high)
通过增加权重对边缘数组E[]排序
低:=高:=0
选择低:=选择高:=0
opt:=无穷大
已连接:=错误
当(高

其想法是在边缘上保留一个滑动窗口,并使用连接性来维护该窗口。要维护连接性信息,您将使用特殊的数据结构。有许多数据结构允许以多段对数的时间成本来维护删除和添加边缘的连接性信息,您可以在这些数据结构。

G Bach infact描述的算法工作正常,运行时间为O(m*m),其中m是边数(考虑到mst的计算需要O(m)时间)。这是codeforces edu部分中提出的问题。

如何选择第一条边?显然,在您的示例中,如果您从权重为7的边开始,您无法找到最佳解决方案。对边进行排序时,我们得到2,3,5,7,2和3之间的差值为1,这是选择两条边可能产生的最小差值。因此,首先我选择2,3,然后在我相应地选择之后。那么,如果权重是1,2,100,102,104,108,你从选择1和2开始?我很确定你可以从这里构造一个反例。是的,是的,我知道了。那怎么解决呢?一个明显的解决方案是枚举所有边的子集,找到一个生成树,并且具有最小值权重。时间复杂度当然是指数级的。那么运行时间有什么限制吗?谢谢!!它可以优化到O(ElogE)?@RjlovesS我看不出来,但我没有证据证明
Ω(E*cost(MST))的下限
也可以。所以:可能吧,但我做不到。如果你知道怎么做,请把它作为答案发布,因为我对此很感兴趣。我想我们可以用O(ElogE*logE)来做我们可以用二进制来代替线性地处理每条边的最小值,也就是说,选择一个中间元素作为最小边,如果我们能够构造生成树,则处理右侧,如果我们不能处理左侧,以及O(ElogE)是针对MST的。你怎么说?@Rjloves我怀疑这是否有效。根据你的规则,取一个具有唯一最优生成树的完整图G,边权重在范围的下半部分,以及一个具有…的完整图G'在范围的上半部分。在这两种情况下,你都可以在第一次迭代中构建生成树这一事实并不说明问题下一步,您需要确定是否要查看较重或较轻的边。对于二进制搜索,您需要能够在每次迭代后丢弃搜索空间的线性部分,我不明白您为什么能够这样做。请注意,此答案可能对原始海报没有帮助。请详细解释。
sort edge array E[] by increasing weights

low := high := 0
opt_low := opt_high := 0
opt := infinity
connected := false

while (high < E.length - 1) or (connected):

    if not connected:
        high = high + 1
    else:
        low = low + 1

    update(connected)

    if connected:
        if E[high].weight - E[low].weight < opt:
            opt = E[high].weight - E[low].weight
            opt_low = low
            opt_high = high

print(opt, opt_low, opt_high)