如何按颜色分割二分图?

时间:2009-10-31 18:21:15

标签: algorithm graph-theory bipartite

例如,假设我有一个图G =(V,E)其中

V = {A,B,C,D}
E = {(A,B),(A,D),(C,D)}

该图是二分的,因此可以分成两个不相交的集合{A,C}和{B,D}。我的第一个猜测是我可以简单地走图形并为每个顶点指定交替的颜色。是这种情况,还是比这更复杂/更简单?有没有已知的算法?

6 个答案:

答案 0 :(得分:5)

你的第一个猜测是正确的 - 遍历图表并交替。

算法应该很简单。我要保留两个节点队列,每种颜色一个。从队列中弹出节点交替,标记其颜色,并将任何未访问的相邻节点推入队列中以获得相反的颜色。当访问节点的数量+两个队列的长度=图中的节点数时终止。

答案 1 :(得分:2)

遍历图表并交替显示,如果没有成功,则意味着您的图表不是二分图。

答案 2 :(得分:1)

如果您确定图形是双星的,那么您可以指定交替它们的颜色以遍历每个顶点,因为它包含:

  

当且仅当它是2可着色时,图是二分的。

答案 3 :(得分:1)

来自维基百科(http://en.wikipedia.org/wiki/Bipartite_graph

如果连接了二分图,则其二分图可以通过距任意任意选择的顶点v的距离的奇偶校验来定义:一个子集由与v的偶数距离处的顶点组成,另一个子集由奇数距离处的顶点组成到v。

因此,可以通过使用这种奇偶校验技术在图的每个连通分量内分别将顶点分配给两个子集U和V,然后检查每个边以验证它是否具有端点,从而有效地测试图是否是二分图。分配给不同的子集。

答案 4 :(得分:1)

我在graph drawing tool中实现了它,您可以在JavaScript中看到我的代码。

我只是将第一个顶点标记为左边的部分,然后递归地标记它的邻居作为右边的部分,递归地将它们的邻居标记为左边的部分...如果找到正确标记的节点,则停止该分支的递归。如果您发现未正确标记的节点,则图形不是二分图。

也许它可以做得更简单,但在过去的几个月里,我有一些艰难的Prolog - Haskell编码日,也许它已经影响了我的大脑,现在我看到了所有东西的递归:-D

答案 5 :(得分:0)

万一有人好奇,这是我提出的代码:

def dfs(root, colorings):
    to_visit1 = deque()
    to_visit2 = deque()
    to_visit1.append(root)
    while len(to_visit1) != 0 or len(to_visit2) != 0:
        dfs_color(to_visit1, to_visit2, True, colorings)
        dfs_color(to_visit2, to_visit1, False, colorings)

def dfs_color(queue, opposite_queue, color, colorings):
    while len(queue) != 0:
    v = queue.pop()
    if v in adjacency_list:
        colorings[v] = color
        neighbors = adjacency_list[v]
        del adjacency_list[v]
        for neighbor in neighbors:
        opposite_queue.append(neighbor)

不可否认,这不是我最好的代码。我使用True / False作为颜色,因为当我使用递归时,只需说出not color即可。当然,我不得不改变它,因为我在更大的图表上吹了我的堆栈。此外,为了给予应有的信用,此代码基于DFS的维基百科代码。

虽然已经指出,我认为这可能只是一个伪装的BFS。