1、一、了解一些概念:二分图:二分图又称作二部图,是图论中的一种特殊模型。 设G=(V,E)是一个无向图,如果顶点V可分割为两个互不相交的子集(A,B),并且图中的每条边(i,j)所关联的两个顶点i和j分别属于这两个不同的顶点集(i in A,j in B),则称图G为一个二分图。无向图G为二分图的充分必要条件是,G至少有两个顶点,且其所有回路的长度均为偶数。最大匹配:给定一个二分图G,在G的一个子图M中,M的边集中的任意两条边都不依附于同一个顶点,则称M是一个匹配. 选择这样的边数最大的子集称为图的最大匹配问题,如果一个匹配中,图中的每个顶点都和图中某条边相关联,则称此匹配为完全匹配,也称作完备匹配.最小覆盖:最小覆盖要求用最少的点(X集合或Y集合的都行)让每条边都至少和其中一个点关联。可以证明:最少的点(即覆盖数)=最大匹配数最小路径覆盖:用尽量少的不相交简单路径覆盖有向无环图G的所有结点。解决此类问题可以建立一个二分图模型。把所有顶点i拆成两个:X结点集中的i和Y结点集中的i',如果有边i->j,则在二分图中引入边i->j',设二分图最大匹配为m,则结果就是n-m。增广路(增广轨):若P是图G中一条连通两个未匹配顶点的路径,并且属于M的边和不属于M的边(即已匹配和待匹配的边)在P上交替出现,则称P为相对于M的一条增广路径(举例来说,有A、B集合,增广路由A中一个点通向B中一个点,再由B中这个点通向A中一个点……交替进行)。增广路径的性质:1 有奇数条边。2 起点在二分图的左半边,终点在右半边。3 路径上的点一定是一个在左半边,一个在右半边,交替出现。(其实二分图的性质就决定了这一点,因为二分图同一边的点之间没有边相连,不要忘记哦。)4 整条路径上没有重复的点。5 起点和终点都是目前还没有配对的点,而其它所有点都是已经配好对的。6 路径上的所有第奇数条边都不在原匹配中,所有第偶数条边都出现在原匹配中。7 最后,也是最重要的一条,把增广路径上的所有第奇数条边加入到原匹配中去,并把增广路径中的所有第偶数条边从原匹配中删除(这个操作称为增广路径的取反),则新的匹配数就比原匹配数增加了1个。了解了增广路的定义以及性质之后,我们仔细理解第7条性质。因为增广路径的长度为奇数,我们不妨设为2*K+1,又因为第一条是非匹配边,且匹配边与非匹配边交替出现,所以非匹配边有K+1条,匹配边有K条。此时,我们做取反操作,则匹配边的个数会在原来的基础上+1。求最大匹配的“匈牙利算法”即是此思想:无论从哪个匹配开始,每一次操作都让匹配数+1,不断扩充,直到找不到增广路径,此时便得到最大匹配。
2、二、知道匈牙利算法的原理:匈牙利算法:算法的核心就是根据一个初始匹配不停的找增广路,直到没有增广路为止。匈牙利算法的本质实际上和基于增广路特性的最大跽啻猢崇流算法还是相似的,只需要注意两点:(一)每个X节点都最多做一次增广路的起点;(二)如果一个Y节点已经匹配了,那么增广路到这儿的时候唯一的路径是走到Y节点的匹配点(可以回忆最大流算法中的后向边,这个时候后向边是可以增流的)。找增广路的时候既可以采用dfs也可以采用bfs,两者都可以保证O(nm)的复杂度,因为每找一条增广路的复杂度是O(m),而最多增广n次,dfs在实际实现中更加简短。匈牙利算法的基本模式:1、 初始时最大匹配为空2、 while (找得到增广路径)3、 do 把增广路径加入到最大匹配中。如果二分图的左半边一共有n个点,最多找n条增广路径,如果图中有m条边,每一条增广路径把所有边遍历一遍,所以时间复杂度为O(n*m);算法思想:算法的思路是不停的找增广轨, 并增加匹配的个数,增广轨顾名思义是指一条可以使匹配数变多的路径,在匹配问题中,增广轨的表现形式是一条"交错轨",也就 是说这条由图的边组成的路径, 它的第一条边是目前还没有参与匹配的,第二条边参与了匹配,第三条边没有..最后一条边没有参与匹配,并且始点和终点还没 有被选择过.这样交错进行,显然 他有奇数条边.那么对于这样一条路径,我们可以将第一条边改为已匹配,第二条边改为未匹配...以此类推.也就是将所有 的边进行"反色",容易发现这样修 改以后,匹配仍然是合法的,但是匹配数增加了一对.另外,单独的一条连接两个未匹配点的边显然也是交错轨.可以证明, 当不能再找到增广轨时,就得到了一个 最大匹配.这也就是匈牙利算法的思路.、二分图匹配中较为重要的三个公式:二分图最小顶点覆盖 = 二分图最大匹配;DAG图的最小路径覆盖 = 节点数(n)- 最大匹配数;二分图最大独立集 = 节点数(n)- 最大匹配数;
3、三、首先对于你的问题进行建模:如何将实际问题转化为二部图?下面举一个简单的机器人避障问题来说明:首先考虑到空间的坐标,如果是二维的那么便在平面上移动,那么便是(x,y)的定位,以及坐标的变换,这正好与二部图的两边对应。(同理,取坐标为(x,y,z)时,可以与三部图对应。)然后,我们知道空间无论是二维还是三维都是连续的,这样就无法构建算法。为了解决这个问题,这里我们要引进一个“块”的定义:“空间中连续无阻碍的多个点可以形成一个块”。那么我们可以将“块“看做是一个点(很多同学看到这肯定会想”物体的规模呢?“,这里我先只考虑路径的构建,路都构建好了,物体就只需要附加了。)而”块“中指定的一段便可以当作路径。
4、那么问题便进行到了“如何去定义块的范围”。那么将你的机器人所运行的区域铺平,构成一张有间隔的平面图纸(如果能用网格表示自然最好)将空间用进行分割,先横向,从空白处到阻挡处分割为一块,标上记号,同理再进行纵向分割,生成了一张网格图(如果接手的时候就已经变成了网格,那么直接连接横向(纵向)的网格直到阻挡处)。将横纵的标号写成2行,将可以行走的空白格用连接的横块与纵块表示(这里是为了之后算法里的关系矩阵好构建)
5、四、使用匈牙利算法:此时将第三步中写出来的块定义出来,举例如下:m=5;n=8;%横有5块表示为m,纵有5块表示为nA=[0 1 1 0 0 0 0 0 ;1 1 0 1 1 0 0 0; 0 1 1 0 0 0 1 0; 0 1 1 0 0 0 0 1; 0 0 0 1 1 0 1 0];%“1”表示网格中由横纵所定义的空白处存在,“0”表示不存在。使用匈牙利算法(baidu可得);最后可得最大匹配,略微改进便能得机器人最短的避障路径。
6、这便是《matlab处理图论问题:二部图的最大匹配》的一点实际用法了。关键点处在如何将实际问题转化成“图”(图多种多样),再去转化成算法所需。希望诸位发挥想象力大胆去构建,去解决问题。