数组的二部匹配

时间:2016-06-13 07:17:19

标签: algorithm graph

我有数组A和B.我必须找到数组B的最大匹配,这样B [i]的每个索引都可以匹配A [j]的任何索引,当且仅当 A [j]时]!= B [i]和A [j]先前未匹配。例如:

A = {1 2 3 4}
B = {2 2 3 4}
Maximum Matching is 4 A[0]=B[3] , A[1]=B[2] , A[2]=B[1], A[3]=B[0]

A = {1 1 2}
B  = {1 1 2}
Maximum Matching 2 A[0]=B[2] , B[1]=No Matching , A[2]=B[0]

我知道这是最大的二分问题,但问题是 A = B <= 10 ^ 3且A [i],B [i] <10 ^ 6 的长度。哪个会超时我的二分解决方案。有没有更好的解决方案?

代码:

public static boolean is_match(int curr) {
    for(int i = 0; i < A.length; i++) {

        if(A[i] != curr && !V[i]) {

            V[i] = true;
            if(P[i] < 0 || is_match(P[i])) {
                P[i] = curr;
                return true;
            }
        }
    }
    return false;
}

我为每个B调用此函数:

for(int i:B){
    V = new boolean[n]
    if(is_match(i)) match++;
}

如何改进我的解决方案?

3 个答案:

答案 0 :(得分:1)

此问题可视为最大流量问题。

因此,条件是A[j]!=B[i] and A[j] is not previously matched,因此知道i中的索引A是否与j中的kB匹配B[j] == B[k]并不重要。

因此,不是将图表表示为2*n节点的二分,而是每个节点代表数组A和B中的索引,我们可以将问题表示为具有一个源节点,一个汇聚节点和表示A和B的唯一值的节点列表,以及节点a(表示A中的a值)到源节点的容量是A中具有的a的索引量价值b。类似地,映射到下沉节点的节点b的容量将等于B中的索引数具有值A = {1, 1, 2, 2}。从A到B的有效节点之间的容量是无穷大。

例如,使用数组B = {1, 2, 2, 3, 3, 3, 3}alphaChar

因此,我们创建了一个包含源节点和汇聚节点的流程图。

  • 此外,对于阵列A,我们创建了两个额外的节点,一个用于值1,另一个用于值2.源节点将连接到这两个节点。

  • 对于节点B,我们创建三个节点,一个用于值1,一个用于值2,一个用于值3.

  • 现在,源节点将仅连接到阵列A的节点,容量相等:2表示节点表示值1(因为阵列A中有两个1),2表示节点表示值2(有两个)阵列A)中的2。

  • Sink节点只能连接到阵列B的节点,容量为: 节点1表示值1(阵列B中只有1个);节点2表示值2(阵列B中有两个2),节点4表示值3(阵列B中有4个)。

  • 从阵列A到B的有效节点之间的连接将具有无限容量。

现在剩下的工作就是运行典型的最大流算法。

答案 1 :(得分:1)

我认为您可以将原始算法调整为O(n ^ 2)。

对于A中的每个节点:(即此循环将重复n次)

  1. 首先扫描以查看我们是否可以将此节点与B. O(n)
  2. 中的节点匹配
  3. 如果没有,那么我们知道B中所有不匹配的节点都与我们的A节点具有相同的值。调用此值a。扫描所有先前的匹配项,查看是否有任何A节点(!=a)与B节点(!=a)匹配。如果是这样,请更改此前一个节点的映射,并为新节点腾出空间。 O(n)
  4. 这是整体O(n ^ 2)。

    当B中不等于a的所有节点都已映射到A中等于a的节点时,第二遍将无法找到匹配项。这意味着有太多的节点等于a,因此解决方案是可能的,并且问题不可能每次都满足。

答案 2 :(得分:0)

二分匹配问题可以通过所谓的Hungarian algorithm解决,也可以建模为maximum flow problem;也许这些算法的实现更快。

作为流动问题的建模如下工作; A构成左侧分区的项目,B的项目构成右侧分区。在分区之间,在节点之间创建容量1的边缘,当且仅当它可以匹配它们时。将源节点放在最左侧,将其连接到左侧分区的每个节点,边缘为容量1;还将一个终端节点放在最右边,将其连接到右侧分区的每个节点,边缘容量为1。如果从源到终端的流量最大化,则通过在中间选择具有非零流量值的这些边缘,它将对应于最大匹配。