匹配图的算法

时间:2017-07-11 18:47:56

标签: algorithm graph graph-algorithm bipartite

如果我们有一些与边连接的节点(如与街道交叉),并且每个节点的值为0到3.边的值为0.

现在我想编写一个算法,将节点的值分配给值边,因此在算法终止后,所有节点的值都为0,所有边都为<= 1。

例如,给出此图:

Like this Graph

我想制作这个:

to this

我的解决方案:

我已经定义了数据类型Crossing and Street:

public class Crossing{
    int value;
}

public class Street{
    int value;
    Crossing A, B;
}

算法遍历交叉点并将值分配给街道(请注意,交叉点只能将其值分配给相邻的街道。)

void allocate(Crossing[] crossings, Street[] streets){
    foreach(crossings as c){ //iterate through every Crossing
        foreach(streets as s){ //Find the streets, which are adjacent to c
            if((s.A == c || s.B == c) && s.value < 1 && c.value != 0) 
                // The value of the crossing is >0 and the value of the 
                // street is 0.
                c.value -= 1;
                s.value += 1;
        }
    }
}

我的算法能运作吗?如果是:它是否有效,或者是否有更好的解决方案?

1 个答案:

答案 0 :(得分:0)

我担心你的算法不会一直有效。

例如,如果我们有节点ABC,A和B的值为1(C的值为0),那么如果B的值被赋予AB交叉而不是BC交叉,那么算法将失败(因为那时) A值无处可去。)

我建议阅读最大流量算法,例如this topcoder tutorial

要使用最大流算法解决此问题,您需要定义新的有向图。这个新图表包含每个交叉点的节点,以及每个街道的节点(以及源节点和汇聚节点)。

你需要边缘:

  1. 从源头到每个交叉口,其容量等于交叉口的值
  2. 从每个交叉口到其连接的街道,容量为1
  3. 从每条街道到容量为1的汇聚节点
  4. 如果构建从源到汇的最大流量,那么从交叉口到街道的边缘流量将告诉您如何分配值。