我有一个图,保证可以将其划分为两个相等大小的分区(一侧可能比另一侧大1),并且该分区上没有边。我最初以为这是NP难题,但我怀疑可能不是。有什么(有效的)方法可以解决这个问题?
答案 0 :(得分:1)
通过将两种众所周知的算法结合在一起,可以在O(n 2 )的时间内解决您的问题。
当我第一次看到您的问题时,我最初以为它与在图中找到maximum或minimum cut之类的事情有关。但是,由于您正在专门寻找一种将节点分为两组的方法,因此在这些组之间根本没有边缘,因此我认为您所寻找的更接近于找到connected components图形。毕竟,如果将图形分解为已连接的组件,则这些组件之间将不会有任何边。因此,问题可归结为以下几点:
找到图的所有连接组件,并记下每个组件中有多少个节点。
将两个连接的组件划分为大小大致相等的两组-具体来说,一侧的组的大小最多应比另一侧的组大。
< / li>步骤(1)是您可以使用广度优先或深度优先的搜索来识别所有连接的组件的步骤。这将花费您O(m + n)的时间,其中m是边的数量,n是节点的数量。
最初,步骤(2)似乎很难。它使人联想起partition problem,后者被称为NP-hard。分区问题的工作方式是这样的:给您输入一个数字列表,您想确定是否将这些数字分为两组,它们的总数彼此相等。 (可以解决此问题,以便您可以容忍一个正负的拆分而不改变复杂性)。该问题恰好是NP完全问题,这表明您的问题可能很难解决。
但是,有一点细微差别实际上使分区问题的表观NP硬度成为问题。在给出的数字以 binary 形式写出的情况下,分区问题很难解决。另一方面,如果数字以 unary 表示,则分区问题具有多项式时间解。更具体地说,存在一种用于分区问题的算法,该算法在时间O(kU)内运行,其中k是数字的数量,U是所有这些数字的总和。对于您正在描述的问题,您知道图形中连接的组件的大小总和必须为n,即图形中的节点数,并且您知道连接的组件的数量也较高由n界定。这意味着O(kU)的运行时间(插入k = O(n)和U = O(n))可以计算为O(n 2 ),可以在多项式时间。
(另一种查看方式-有一个pseudopolynomial time algorithm用于分区问题,但是由于在您的情况下,最大可能的总和受输入大小的实际多项式的限制,整个运行时是一个多项式。)
我上面提到的算法是一种标准的动态编程练习。您选择了一些数字顺序(不一定按排序顺序),然后填写2D表,其中每个条目都对应于以下问题的答案:“是否有前i个数字的子集加起来等于j?”如果您对这种算法不熟悉,我将由您自己来决定细节,因为要解决这个问题确实很漂亮,但要有一个相当简单而优雅的解决方案。
总体而言,此算法将在时间O(n 2 )上运行,因为您需要执行O(m + n)= O(n 2 )的工作找到连接的组件,然后是时间O(n 2 )来运行分区问题DP,以确定拆分是否存在。
希望这会有所帮助!