计算图形着色代码复杂度方面的差异

问题描述

请考虑以下代码。假设所讨论的图具有N个节点,每个节点最多具有D个邻居,并且D + 1种颜色可用于为这些节点着色,以使没有两个与边连接的节点具有相同的颜色分配给它们。我认为以下代码的复杂度是O(N * D),因为对于N个节点中的每个节点,我们循环访问该节点的D个邻居,以填充集合非法颜色,然后遍历包含D + 1的颜色列表颜色。但是给定的复杂度是O(N + M),其中M是边的数量。我在这里做什么错了?

def color_graph(graph,colors):
    for node in graph:
        if node in node.neighbors:
            raise Exception('Legal coloring impossible for node with loop: %s' %
                            node.label)

        # Get the node's neighbors' colors,as a set so we
        # can check if a color is illegal in constant time
        illegal_colors = set([
            neighbor.color
            for neighbor in node.neighbors
            if neighbor.color
        ])

        # Assign the first legal color
        for color in colors:
            if color not in illegal_colors:
                node.color = color
                break

解决方法

边数M,最大度数D和节点数N满足不等式: M <= N * D / 2

因此O(N+M)包含在O(N*(D+1))中。

在算法中,您遍历每个节点的每个邻居。确切的复杂度不是N*D,而是d1 + d2 + d3 + ... + dN,其中di是节点i的度数。此总和等于2*M,最大为N*D,但可能会更少。

因此,算法的复杂度为O(N+M)。因此它也是O(N*(D+1))。请注意,O(N*(D+1)) = O(N*D)是假设D >= 1的。

说算法在O(N+M)中运行比说在O(N*D)中运行要精确得多。如果大多数节点的邻居数少于D,则M+N可能比N*D小。

还要注意,O(M+N) = O(M)是在每个节点至少有一个邻居的前提下进行的。

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...