【发布时间】:2008-11-13 16:20:20
【问题描述】:
我正在尝试编写一种算法,该算法将在图中找到度数小于其邻居的所有顶点的集合。我最初的方法是找到每个顶点的度数,然后遍历列表,将每个顶点的度数与其邻居的度数进行比较。不幸的是,这看起来可能非常耗时。有没有更有效的方法来找到这个集合?
【问题讨论】:
我正在尝试编写一种算法,该算法将在图中找到度数小于其邻居的所有顶点的集合。我最初的方法是找到每个顶点的度数,然后遍历列表,将每个顶点的度数与其邻居的度数进行比较。不幸的是,这看起来可能非常耗时。有没有更有效的方法来找到这个集合?
【问题讨论】:
一条评论 - 如果您正在使用无向图(谢谢,Brian R. Bondy),一旦您确定一个顶点的度数小于其所有邻居的度数,您就不会'不需要检查邻居,因为他们都不会拥有该属性。考虑使用这些知识来帮助您并加快速度。
【讨论】:
也许“这看起来可能非常耗时”,但有更好的方法来找出答案:-)
假设您已将图形存储为邻接列表。要找到您正在寻找的集合,您必须查看所有边缘,因此我们为算法设置了 Ω(|E|) 的下界。找到每个顶点的度数需要时间 O(|E|)(因为您只查看每条边一次;另一个证明是使用 ∑d(v)=2|E| 的事实)。比较每个顶点与其所有邻居的度数也只需要 O(|E|) 时间(同样,对于每条边,您只进行一次比较)。这意味着您的算法在 O(|E|) 时间内运行(大约 2|E|“步骤”,但 CPU 指令的精确数量取决于您的实现),这符合下限。因此,在最坏的情况下,您的“蛮力”算法本质上是(直到一个小常数)尽可能快,因此不值得进一步优化。
如果您正在为实际应用程序执行此操作,并且您确实发现您的算法花费了太多时间,那么请使用分析器来查找要优化的部分。优化算法的第二阶段是否至关重要,这一点并不明显。
【讨论】:
我想一个无向图的贪心方法如下:
let Q = all nodes which haven't been checked (initialize all V)
let Q* = all nodes which satisfy the required condition (initialize to empty)
start with an arbitrary node, v in Q
while Q is not empty
let minDeg be the minimum degree of all v's neighbors
if degree(v) < minDeg
add v to Q*
remove all neighbors of v from Q
remove v from Q
set v = new arbitrary node, v in Q
else
remove v from Q
set v = v's neighbor in Q of minimum degree
这种算法可能稍微高效一些,因为在每次迭代中,它要么找到一个令人满意的节点,要么检查一个度数较低的新节点并从图中删除一个节点。
在最坏的情况下,它相当于你的蛮力算法。不过,平均而言,我认为它应该表现更好。
【讨论】: