最近两天学习了Hopcroft-Karp算法,查看了网上的不是资料、博客、讲义,颇有心得,所以要写下来,以避免后来人继续走我的弯路。国外大学教授写的针对计算机系学生的讲义 (Lecture Note),一上来就是定理、定义,符号的推导,技术负责性的分析。新学者不适合看,因为你要真正透彻地把他们的讲义看懂,需要看他们的前面的讲义里面关于符号的约定等等,可能花费的时间比较多。国内人写的博客又太简略,给出了算法,然后就是代码,云里雾里的,让人看不懂。经过我这两天的学习,我认为最好的学习Hopcroft-Karp算法的路径为:
- 先看南京大学某教授的pdf版的讲义( ),该讲义带有动画演示,能让你快速抓住Hopcroft-Karp背后支撑的二分图中的基本概念,尤其是与该算法相关连的概念。通过动画演示,你更能清晰的看到Hocroft-Karp算法运行的一个实例,能快速了解该算法。
- 有了第一步的基础后,你可以再去看老外们写的讲义,这时你会对他们中讲的概念有直观印象,而不至于云里雾里。当然,如果你由于毅力,推荐看两位图灵奖获得者,至今仍然奋斗在科研第一线的、计算机界的大牛John E. Hopcroft & Richard M. Karp 写的原文《A $n^{5/2}$ Algorithm for Maximum Matchings in Bipartite Graphs》,发表在1973年 SIAM J. Computing上面的文章。我在图书馆网站的SIAM J. Computing页面没有检索到该文章,好像只到1980年以后的文章才有。幸运的是,我在csdn上下载页面上搜索到了该文章。
- 当然,有了上面2步后,你会急着看该算法的实现代码。我在网上搜到了Python代码实现和C++代码实现,鉴于C++实现的广泛性,为着便于理解算法实现的角度,我推荐网页 (http://esoerik.blogspot.com/2012/07/hopcroft-karp-maximum-bipartite.html)上的代码。推荐理由是它具有一个很好的二分图表示数据结构,该实现不依赖于其他的软件包库,是一个独立的算法实现代码,输入包括匹配的最大数,和每个具体的匹配元素。虽然它是个命令行程序,但也可以方便的移植到GUI程序中去。
学习该算法,最好坚持把它看懂,可以在vs2010中允许一个简单的测试用例,利用vs2010的Debug功能跟进和查看每个变量在运行时的具体值,以更透彻地理解该算法。我所喜爱的即简单又能阐明算法过程的一个用例为:
/** Test case 2 **/
/*m.addVertex(m.U_Vertex, "A");
m.addVertex(m.U_Vertex, "B");
m.addVertex(m.U_Vertex, "C");
m.addVertex(m.U_Vertex, "D");
m.addVertex(m.V_Vertex, "1");
m.addVertex(m.V_Vertex, "2");
m.addVertex(m.V_Vertex, "3");
m.addVertex(m.V_Vertex, "4");
m.addEdge("A","1");
m.addEdge("A","2");
m.addEdge("A","3");
m.addEdge("B","2");
m.addEdge("C","1");
m.addEdge("C","3");
m.addEdge("C","4");
m.addEdge("D","3");*/
好玩吗?玩下去把!