【问题标题】:How do I partition a bipartite graph by color?如何按颜色划分二部图?
【发布时间】:2010-12-11 22:15:34
【问题描述】:

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

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

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

【问题讨论】:

    标签: algorithm graph-theory bipartite


    【解决方案1】:

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

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

    【讨论】:

    • 或者干脆写一个递归 DFS 函数,传递一个颜色参数。
    • 大多数足够有趣的图都会导致递归 DFS 上的 SO。
    • 这只是一个 BFS。无需保留两个队列;一个就足够了(因为您正在标记节点的颜色)。
    • 这取决于您是标记节点本身还是将节点分成两组而不更改它们;后者在使用两个队列时效率更高。
    【解决方案2】:

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

    如果一个二分图是连通的,它的二分图可以由任意选择的顶点 v 的距离的奇偶性来定义:一个子集由到 v 的偶数距离的顶点组成,另一个子集由奇数距离的顶点组成去诉。

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

    【讨论】:

    • 我已经知道该图是二分的。我想把它分成不相交的集合。
    • 这个答案中的“测试”是一个建设性的过程;当测试成功时,您拥有两个不相交的部分。
    • @Jason,正如@ShreevatsaR 所说,运行测试必然会得到根据两组标记的顶点。
    【解决方案3】:

    遍历图并交替,如果不成功,则表示您的图不是二分图。

    【讨论】:

      【解决方案4】:

      如果您确定该图是双向的,那么您可以分配颜色交替它们以遍历每个顶点,因为它认为:

      一个图是二分的当且仅当它是 2-colorable 的。

      【讨论】:

        【解决方案5】:

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

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

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

        【讨论】:

          【解决方案6】:

          以防万一有人好奇,这是我想出的代码:

          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。

          【讨论】:

            猜你喜欢
            • 2018-04-25
            • 2023-01-25
            • 2011-09-21
            • 2020-05-14
            • 1970-01-01
            • 2022-01-11
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多