Use the Hungary algorithm to obtain the maximum matching of binary graphs.

Source: Internet
Author: User

Use the Hungary algorithm to obtain the maximum matching of binary graphs.

 

Reprinted by great gods !!

What is a bipartite graph and what is the maximum matching of a bipartite graph? I will not talk about these definitions. I can find them on the Internet. Two methods are available for the maximum matching of a bipartite graph. The first method is the largest stream (I suppose the reader already has knowledge about the network stream), and the second is the Hungarian algorithm I want to talk about now. This algorithm is actually the largest stream algorithm, but it matches the problem with the Binary Graph, simplifying the maximum flow algorithm and Improving the efficiency. The Hungarian algorithm is actually very simple, but there is no clear article on the Internet. So I decided to write it.
The core problem of the maximum flow algorithm is to find the augmented path (augment path ). The Hungarian algorithm is no exception. Its basic model is:

The maximum initial matching value is null.
While find the augmented path
Do adds the augmented path to the maximum match.
Visible and maximum stream algorithms are the same. However, the augmented path here has some special characteristics. Let me analyze it.
(Note: although the Hungary algorithm is essentially the largest stream algorithm, it does not need to create a network model. Therefore, the Source and Sink points are no longer required in the graph, but only a binary graph. No direction is required for each side .)

Image 1

Image 2

Figure 1 shows a match in the bipartite graph I have given: [] and []. Figure 2 shows an augmented path based on the matching: 3-> 6-> 2-> 5-> 1-> 4. We use it to describe the nature of the augmented path in the bipartite graph:

(1) There are odd edges.
(2) the start point is at the left half side of the bipartite graph, and the end point is at the right half side.
(3) The vertices on the path must be one on the left half side and one on the right half side. (In fact, the nature of the Bipartite Graph determines this, because the vertices on the same side of the bipartite graph are not connected by edges. Don't forget .)
(4) There are no repeated points in the entire path.
(5) the start and end points are not paired yet, and all other points are properly matched. (1. As shown in figure 2, [] and [] are matched points in Figure 1; start 3 and end 4 are not paired with other vertices yet .)
(6) All the odd edge of the path is not in the original match, and all the even edge of the path appears in the original match. (1. As shown in figure 2, the original matches are [] and [], the edges of the two matches are 2nd and 4th edges in the augmented path given in Figure 2. The 1st, 3, and 5 edges of the augmented path do not appear in the matching given in Figure 1 .)
(7) Finally, it is also the most important one. add all the odd-number edges in the augmented path to the original match, and delete all the edge numbers in the augmented path from the original match (this operation is called the inverse operation of the augmented path). Then, the new number of matches increases by 1 compared with the original number of matches. (2) The New Match is all the blue edges, and all the red edges are deleted from the original match. The number of new matches is 3 .)

It is hard to figure out that when there is no matching at the very beginning, the two gray edges in Figure 1 are also augmented paths. Therefore, the process of finding the maximum matching in this bipartite graph may be as follows:

(1) Find the augmented Path 1-> 5 and reverse it. Then, the number of matches increases to 1.
(2) Find the augmented Path 2-> 6 and reverse it. Then, the number of matches increases to 2.
(3) locate the augmented Path 3-> 6-> 2-> 5-> 1-> 4 and reverse it, then the number of matches increases to 3.
(4) The augmented path cannot be found again.

Of course, this is only a possible process. There may also be other order for finding the augmented path, or finding different augmented paths, and the final matching scheme may be different. However, the maximum number of matches must be the same.

A recursive method can also be used to describe the augmented path. This description is not necessarily the most accurate, but it reveals the general method for finding the augmented path:
The "Augmented path starting from Vertex A" must first be connected to vertex B that is not paired with Vertex A in the original match. If point B is not paired with any vertex in the original match, it is the end point of the augmented path. Otherwise, if point B is paired with point C, then this augmented path is from A to B, then from B to C, plus the "Augmented path Starting from point C ". In addition, the augmented path starting from C cannot overlap with the augmented path in the first half.

In comparison to 2, we need to find an augmented path starting from 3 and do the following three steps:
(1) First, starting from 3, it can connect to only 6 points, and 6 has been paired with 2 in Figure 1, therefore, the current augmented path is 3-> 6-> 2 plus the augmented path starting from 2.
(2) starting from 2, the points that it can connect to do not repeat with the first half of the paths are only 5, and 5 is indeed not paired with 2 in the original match. So from 2 to 5. But 5 has been paired with 1 in Figure 1, so the current augmented path is 3-> 6-> 2-> 5-> 1 plus the augmented path starting from 1.
(3) starting from 1, only four points can be connected that are not paired with themselves and do not overlap with the first half of the paths. Because 4 is not paired with any vertex in Figure 1, it is the end point. Therefore, the final augmented path is 3-> 6-> 2-> 5-> 1-> 4.

But strictly speaking, in the above process, the augmented paths starting from 2 (2-> 5-> 1-> 4) and from 1 (1-> 4) it is not a real augmented path. Because they do not conform to the 5th properties of the augmented path mentioned above, their starting points are already matched. Here we call them "Augmented paths" to facilitate the entire search process. The two paths can only be regarded as the returned results of two sub-processes not known to the outside world.
Obviously, from the above example, we can see that the method for searching the augmented path is DFS, and a recursive function can be written. Of course, BFS can also be used.

Now, the theoretical basics section is complete. However, to complete the Hungarian algorithm, an important theorem is required:

If the augmented path is not found from A point A, no matter how many augmented paths are found from other points to change the current matching, the augmented path will never be found from.

It is hard to say that the theorem is very complicated to use words to prove it. Either I have to draw another graph and I will save it here. In fact, you can draw several figures and try to give two examples. This theorem is not hard to figure out. (Give a prompt. If you try to give an inverse example, you can find the augmented path from A after finding another augmented path and changing the existing matching. In this case, we can find the augmented path from A before finding another augmented path. This is in conflict with assumptions .)
With this theorem, the Hungarian algorithm is formed. As follows:

The maximum initial matching value is null.
For every vertex I in the left half of a Bipartite Graph
Do searches for the augmented path from vertex I. If it is found, it is reversed (that is, the total number of matches is increased ).
If there are n vertices in the left half of a bipartite graph, a maximum of n augmented paths can be found. If there are m edges in the graph, all edges can be traversed at most once every time a augmented path (DFS or BFS) is found, and the time it takes is m. So the total time is O (n * m ).

Good luck.

The following are my projects. BFS is used to search for the augmented path. Although DFS may be relatively simple to write, I Don't Want To Recursive it into multiple layers.
Welcome to my project.

 

//////////////////////////////////////// /////////////// // Bipartite graphic and maximum matching with Hungarian algorithm. //////////////////////////////////////// //// // # include <list> # include <cstring> using namespace std; const int MAX_LEFT = 500; const int MAX_RIGHT = 500; class Bipartite {private: struct Edge {int to; Edge * next; Edge (int _) {to = _ to ;}}; Ed Ge * m_adjList [MAX_LEFT]; int m_lCnt; int m_rCnt; int m_lMatchR [MAX_RIGHT]; int m_rmatchlorophyll [MAX_LEFT]; int m_preL [MAX_LEFT]; bool m_visitR [MAX_RIGHT]; // This matrix is just used to prevent adding two repeated edges. bool m_matrix [MAX_LEFT] [MAX_RIGHT]; void clear () {for (int I = 0; I <m_lCnt; I ++) {Edge * e = m_adjList [I]; while (e! = NULL) {Edge * pre = e; e = e-> next; delete pre;} m_adjList [I] = NULL;} memset (m_matrix, 0, sizeof (m_matrix);} void findAugment (int start) {for (int I = 0; I <m_lCnt; I ++) {m_preL [I] =-1 ;} memset (m_visitR, 0, sizeof (bool) * m_rCnt); list <int> que; que. push_back (start); bool found = false; while (! Que. empty ()&&! Found) {int from = que. front (); que. pop_front (); Edge * edge = m_adjList [from]; while (edge! = NULL &&! Found) {int to = edge-> to; if (! M_visitR [to]) {m_visitR [to] = true; if (m_rmatchlorophyll [to] =-1) {found = true; reverse (from, );} else {que. push_back (m_rmatchlorophyll [to]); m_preL [m_rmatchlorophyll [to] = from ;}} edge = edge-> next ;}} void reverse (int left, int right) {m_rmatchlorophyll [right] = left; while (m_preL [left]! =-1) {int nextR = m_lMatchR [left]; m_rmatchlorophyll [nextR] = m_preL [left]; m_lMatchR [left] = right; left = m_preL [left]; right = nextR;} m_lMatchR [left] = right;} public: Bipartite () {memset (m_adjList, 0, sizeof (m_adjList); m_lCnt = 0; m_rCnt = 0 ;} ~ Bipartite () {clear ();} // Add an edge between vertex "left" and "right" while "left" and "right" are // the indices of two vertices in the left/right parts of the graph. indices // in the left and right parts are separated and they both begin from 0. void addEdge (int left, int right) {if (! M_matrix [left] [right]) {m_matrix [left] [right] = true; Edge * newEdge = new Edge (right); newEdge-> next = m_adjList [left]; m_adjList [left] = newEdge;} // Before invoking this function, "maxMatch ()" must be invoked. this function // returns the index of the matching vertex of "left" while "left" is the // index of a vertex in the left part of the graphic. int getLMatchR (int left) const {return m_lMat ChR [left];} // See "getLMatchR ()", and this function is opposite to it. int getrmatchlorophyll (int right) const {return m_rmatchlorophyll [right];} void init (int leftCnt, int rightCnt) {clear (); m_lCnt = leftCnt; m_rCnt = rightCnt; for (int I = 0; I <m_lCnt; I ++) {m_lMatchR [I] =-1 ;}for (int I = 0; I <m_rCnt; I ++) {m_rmatchlorophyll [I] =-1 ;}} int maxMatch () {for (int I = 0; I <m_lCnt; I ++) {findAugment (I );} Int result = 0; for (int I = 0; I <m_lCnt; I ++) {if (m_lMatchR [I]! =-1) {result ++ ;}} return result ;}; // Test suites. # include <iostream> int main () {Bipartite match; match. init (300,400); int a [] = {0, 0, 1, 1, 2, 2}; int B [] = {1, 2, 1, 3, 0, 1, 2}; for (int I = 0; I <7; I ++) {match. addEdge (a [I], B [I]);} int maxMatch = match. maxMatch (); cout <maxMatch <""; for (int I = 0; I <3; I ++) {cout <match. getLMatchR (I) <";}for (int I = 0; I <4; I ++) {cout <match. getrmatchlorophyll (I) <";}cout <endl; // Correct: 3 2 3 1-1 2 0 1 return 0 ;}View Code

 

Supplementary definitions and theorems:

Maximum number of matches: Maximum number of matched Edges
Minimum vertex coverage: Select the least vertex so that at least one endpoint of any edge is selected.
Maximum number of Independent Tasks: Select the most vertices so that any two points selected are not connected.
Minimum path overwrite count: For a DAG (directed acyclic graph), select at least one path so that each vertex belongs to and belongs to only one path. The path length can be 0 (that is, a single point ).

Theorem 1: Maximum number of matching = least vertex overwrite (this is the Konig theorem)
Theorem 2: maximum matching number = Maximum Independent Number
Theorem 3: Minimum path overwrite = vertex count-maximum matching count

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.