Reproduced the great God!!
What is a binary graph, what is the maximum match of the binary graph, these definitions I will not speak, the Internet can be easily found. There are two methods for maximum matching of binary graphs, the first of which is the maximum flow (I assume that the reader already has the knowledge of the network flow); The second is the Hungarian algorithm I'm going to talk about now. This algorithm is plainly the maximum flow algorithm, but it is based on the binary map matching the characteristics of the problem, the maximum flow algorithm to simplify, improve efficiency. The Hungarian algorithm is actually very simple, but the online search does not have anything to say clearly the article. So I decided to write a little bit.
The core problem of the maximum flow algorithm is to find the augmented path (augment path). The Hungarian algorithm is no exception, its basic pattern is:
Initial maximum match is empty
While the augmented path can be found
Do add the augmented path to the maximum match
The visible and maximum flow algorithms are the same. But here the augmented path has its certain particularity, let me analyze it.
(Note: Although the Hungarian algorithm is essentially the maximum flow algorithm, it does not need to build a network model, so the source and sink points are no longer needed in the diagram, just a two-part diagram.) Each edge does not need to have a direction. )
Image Figure 1
Image Figure 2
Figure 1 shows a match in the binary diagram I gave: [1,5] and [2,6]. Figure 2 is an augmented path found on the basis of this match: 3->6->2->5->1->4. Let's take a look at the nature of the augmented path in the binary diagram:
(1) There is an odd number of edges.
(2) The starting point is in the left half of the dichotomy, ending at the right half.
(3) The point on the path must be one in the left half, and one in the right half, alternating. (In fact, the nature of the binary chart determines this point, because the two points of the same side of the point is not connected to the side, do not forget oh.) )
(4) There are no duplicate points on the entire path.
(5) The starting and ending points are not currently paired, and all the other points are well-matched. (1, Figure 2, [1,5] and [2,6] in Figure 1 are two pairs already paired with the point, and the beginning 3 and end of 4 are not currently matched with other points. )
(6) All the odd-number edges on the path are not in the original match, and all of the even-odd bars appear in the original match. (1, Figure 2 shows that the original match is [1,5] and [2,6], the two side of the edge in Figure 2 given in the augmented path of the edge is the 2nd and 4th edge. The 1th, 3, and 5 edges of the augmented path do not appear in the match shown in Figure 1. )
(7) Finally, the most important one, adding all the odd bars on the augmented path to the original match, and removing all the odd bars in the augmented path from the original match (this operation is called the inverse of the augmented path), the new match number increases by 1 compared to the original match number. (2 shows that the new match is all blue edges, and all red edges are removed from the original match.) The new match number is 3. )
It is not difficult to figure out that, at the beginning, when there is no match, the two gray edges in Fig. 1 are themselves augmented paths. So the process of finding the maximum match in this binary chart may be as follows:
(1) Find the augmented path 1->5 and reverse it, then the match number increases to 1.
(2) Find the augmented path 2->6 and reverse it, then the match number increases to 2.
(3) Find the augmented path 3->6->2->5->1->4 and reverse it, then the match number increases to 3.
(4) Can not find the augmented path, end.
Of course, this is just a possible process. There may also be other ways to find the augmented path, or to find different augmented paths, and the final matching scheme may not be the same. But the maximum number of matches must be the same.
The augmented path can also be described in a recursive way. This description is not necessarily the most accurate, but it reveals a general way to find an augmented path:
"Augmented path from point a" must first connect to a point B that is not paired with point A in the original match. If point B is not paired with any point in the original match, it is the end point of the augmented path, whereas if point B is paired with point C, the augmented path is from a to B, then from B to C, plus the "augmented path from point C". Also, the augmented path from C does not have a duplicate point with the augmented paths of the first half.
Compared to 2, we are looking for an augmented path from 3 to do the following 3 steps:
(1) First starting from 3, it can connect to the point of only 6, and 6 in Figure 1 has been paired with 2, so the current augmented path is 3->6->2 plus the augmented path from 2.
(2) Starting from 2, it can be connected to the first half of the path is not repeat the point of only 5, and 5 does not match the original matching with 2. So from 2 even to 5. However, 5 is already paired with 1 in Figure 1, so the current augmented path is 3->6->2->5->1 plus the augmented path from 1.
(3) Starting from 1, the point that can not be connected to self-pairing and not with the first half of the path repeats only 4. Since 4 is not paired with any point in Figure 1, it is the end point. So the final augmented path is 3->6->2->5->1->4.
But strictly speaking, the augmented path (2->5->1->4) from 2 and the augmented path from 1 (1->4) in the above process are not really augmented paths. Since they do not conform to the 5th nature of the augmented path previously spoken, their starting point is the point at which they have been fitted. We call them "augmented paths" here just to make it easier to explain the entire search process. The two paths themselves are only two of the returned results of sub-processes not known to the outside world.
Obviously, the above example shows that the method of searching for an augmented path is DFS, which can be written as a recursive function. Of course, using BFS can also be fully realized.
At this point, the theoretical basis of the part is finished. But to complete the Hungarian algorithm, an important theorem is also needed:
If you start from a point A and do not find an augmented path, then no augmented path will ever be found from a, no matter how many augmented paths are found from another point to change the current match.
To prove that this theorem is very complicated by words, it is hard to say, or I have to draw a picture, I will save it here. In fact, you draw a few pictures yourself, trying to give two counter-examples, this theorem is not difficult to figure out. (Give a hint.) If you try to give a counter example to show that you can find an augmented path from a when you find another augmented path and change the existing match. Then, in this case, it is certain that the augmented path can be found from a before the other augmented paths are found. This is inconsistent with the hypothesis. )
With this theorem, the Hungarian algorithm is formed. As follows:
Initial maximum match is empty
Each point of the left half of the for binary diagram I
Do from point I to find the augmented path. If found, it is reversed (that is, the total number of matches is increased).
If there is a total of n points in the left half of the binary graph, then the maximum number of n-augmented paths is found. If the graph has m-bars, then it is necessary to traverse all the edges in each search for an augmented path (DFS or BFS), which takes the time that is M. So the total time is probably O (n * m).
On UVA, the two-figure matching topic has 670 and 10080, good luck.
Here are my standard routines. is to search the augmented path with BFS. Although Dfs may be easier to write, I don't want it to be recursive to many layers.
Welcome to my standard thread.
///////////////////////////////////////////////////////////////////////bipartite graphic and maximum matching with Hungarian algorithm./////////////////////////////////////////////////////////////////////#include <list>#include<cstring>using namespacestd;Const intMax_left = -;Const intMax_right = -;classbipartite {Private: structEdge {intto ; Edge*Next; Edge (int_to) { to=_to; } }; Edge*M_adjlist[max_left]; intm_lcnt; intm_rcnt; intM_lmatchr[max_right]; intM_rmatchl[max_left]; intM_prel[max_left]; BOOLM_visitr[max_right]; //This matrix was just used to prevent adding the repeated edges. BOOLM_matrix[max_left][max_right]; voidClear () { for(inti =0; i < m_lcnt; i++) {Edge* E =M_adjlist[i]; while(E! =NULL) {Edge* Pre =e; E= e->Next; DeletePre; } M_adjlist[i]=NULL; } memset (M_matrix,0,sizeof(M_matrix)); } voidFindaugment (intstart) { for(inti =0; i < m_lcnt; i++) {M_prel[i]= -1; } memset (M_visitr,0,sizeof(BOOL) *m_rcnt); List<int>que; Que.push_back (start); BOOLFound =false; while(!que.empty () &&!found) { int from=Que.front (); Que.pop_front (); Edge* Edge = m_adjlist[ from]; while(Edge! = NULL &&!)found) { intto = edge->to ; if(!M_visitr[to]) {M_visitr[to]=true; if(M_rmatchl[to] = =-1) {found=true; Reverse ( from, to); } Else{que.push_back (m_rmatchl[to]); M_prel[m_rmatchl[to]]= from; }} Edge= edge->Next; } } } voidReverseintLeftintRight ) {M_rmatchl[right]=Left ; while(M_prel[left]! =-1) { intNEXTR =M_lmatchr[left]; M_RMATCHL[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 the vertices in the left/right parts of the graph. Indices//The parts is separated and they both begin from 0. voidAddedge (intLeftintRight ) { if(!M_matrix[left][right]) {M_matrix[left][right]=true; Edge* NewEdge =NewEdge (right); NewEdge->next =M_adjlist[left]; M_adjlist[left]=NewEdge; } } //before invoking this function, "maxmatch ()" Must is invoked. This function//returns the index of the matching vertex of ' left ' while ' left ' is the//index of a vertex in the graphic. intGETLMATCHR (intLeftConst { returnM_lmatchr[left]; } //See "GETLMATCHR ()", and this function are opposite to it. intGetrmatchl (intRightConst { returnM_rmatchl[right]; } voidInitintLEFTCNT,intrightcnt) {Clear (); M_lcnt=leftcnt; M_rcnt=rightcnt; for(inti =0; i < m_lcnt; i++) {M_lmatchr[i]= -1; } for(inti =0; i < m_rcnt; i++) {M_rmatchl[i]= -1; } } intMaxmatch () { for(inti =0; i < m_lcnt; i++) {findaugment (i); } intresult =0; for(inti =0; i < m_lcnt; i++) { if(M_lmatchr[i]! =-1) {result++; } } returnresult; }};//Test Suites.#include <iostream>intMain () {bipartite match; Match.init ( -, -); intA[] = {0,0,1,1,2,2,2}; intB[] = {1,2,1,3,0,1,2}; for(inti =0; I <7; i++) {Match.addedge (A[i], b[i]); } intMaxmatch =Match.maxmatch (); cout<< Maxmatch <<" "; for(inti =0; I <3; i++) {cout<< MATCH.GETLMATCHR (i) <<" "; } for(inti =0; I <4; i++) {cout<< Match.getrmatchl (i) <<" "; } cout<< Endl;//Correct:3 2 3 1-1 2 0 1 return 0;}
View Code
Supplemental Definitions and theorems:
Maximum matches: the number of matching edges that match the maximum
minimum Point coverage : Select a minimum point so that at least one end of any edge is selected
maximum independent number : Select the most points so that any selected two points are not connected
Minimum path coverage : For a DAG (directed acyclic graph), select the fewest paths 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 matches = minimum point coverage (this is the Konig theorem)
Theorem 2: Maximum number of matches = maximum Independent number
Theorem 3: Minimum path coverage = number of vertices-maximum number of matches
Using Hungarian algorithm to find the maximum matching of two-fractal graphs