最大二分匹配匈牙利算法的python实现

Posted JamesPei的博客

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了最大二分匹配匈牙利算法的python实现相关的知识,希望对你有一定的参考价值。

二分图匹配是很常见的算法问题,一般用匈牙利算法解决二分图最大匹配问题,但是目前网上绝大多数都是C/C++实现版本,没有python版本,于是就用python实现了一下深度优先的匈牙利算法,本文使用的是递归的方式以便于理解,然而迭代的方式会更好,各位可以自行实现。

1、二分图、最大匹配

什么是二分图:二分图又称作二部图,是图论中的一种特殊模型。 设G=(V,E)是一个无向图,如果顶点V可分割为两个互不相交的子集(A,B),并且图中的每条边(i,j)所关联的两个顶点i和j分别属于这两个不同的顶点集(i in A,j in B),则称图G为一个二分图。 

技术分享

什么是匹配:把上图想象成3位工人和4种工作,连线代表工人愿意从事某项工作,但最终1个工人只能做一种工作,最终的配对结果连线就是一个匹配。匹配可以是空。 
什么是最大匹配:在有好感的基础上,能够最多发展几对。 

现在要用匈牙利算法找出最多能发展几对。 
[color=green][size=medium] 
匈牙利算法是解决寻找二分图最大匹配的。

更多二分图最大匹配的图解可以参考 http://xuxueliang.blog.51cto.com/5576502/1297344

以下是代码,为了图省事使用了类,实际上并不需要这样

M=[]
class DFS_hungary():

    def __init__(self, nx, ny, edge, cx, cy, visited):
        self.nx, self.ny=nx, ny
        self.edge = edge
        self.cx, self.cy=cx,cy
        self.visited=visited

    def max_match(self):
        res=0
        for i in self.nx:
            if self.cx[i]==-1:
                # self.visited={‘E‘: 0, ‘F‘: 0, ‘G‘: 0,‘H‘:0}
                for key in self.ny:         # 将visited置0表示未访问过
                    self.visited[key]=0
                res+=self.path(i)return res

    def path(self, u):
        for v in self.ny:
            if self.edge[u][v] and (not self.visited[v]):
                self.visited[v]=1
                if self.cy[v]==-1:
                    self.cx[u] = v
                    self.cy[v] = u
                    M.append((u,v))
                    return 1
                else:
                    M.remove((self.cy[v], v))
                    if self.path(self.cy[v]):
                        self.cx[u] = v
                        self.cy[v] = u
                        M.append((u, v))
                        return 1
        return 0

ok,接着测试一下:

if __name__ == __main__:
    nx, ny = [A, B, C, D], [E, F, G, H]
    edge = {A:{E: 1, F: 0, G: 1, H:0}, B:{E: 0, F: 1, G: 0, H:1}, C:{E: 1, F: 0, G: 0, H:1}, D:{E: 0, F: 0, G: 1, H:0}} # 1 表示可以匹配, 0 表示不能匹配
    cx, cy = {A:-1,B:-1,C:-1,D:-1}, {E:-1,F:-1,G:-1,H:-1}
    visited = {E: 0, F: 0, G: 0,H:0}

    print DFS_hungary(nx, ny, edge, cx, cy, visited).max_match()

结果为4,是正确的。各位也可以使用其它二分图来测试。

以上是关于最大二分匹配匈牙利算法的python实现的主要内容,如果未能解决你的问题,请参考以下文章

二分图匹配(匈牙利算法模板)

匈牙利算法-二分图的最大匹配

java 用于在未加权的二分图中找到最大匹配的匈牙利算法的Java实现

二分图的最大匹配——匈牙利算法

(转)二分图的最大匹配完美匹配和匈牙利算法

(转)二分图的最大匹配完美匹配和匈牙利算法