Directory
1 Problem Description
2 Solutions
1 problem description
What is the maximum weight matching problem for two-point graphs?
The most powerful two-point matching problem is to give a weighted value to each side of the binary graph, select some disjoint edges, and get the maximum total weight value.
2 Solutions
for the explanation of this issue, refer to end reference 1:
Solving this problem can be used KM algorithm. Understanding km algorithms need to first understand " feasible top mark " Span style= The concept of "font-family: Song Body". A feasible top-mark is a value for each point on either side of the binary graph lx[i] or ly[j] w[i][j] all have lx[i] +ly[j]-w[i][j]>=0 lx[i]+ly[j]==w[i][j] A perfect match in the derived sub-diagram of the edge composition, the perfect match must be the maximum weight match in the original. The reason is simple: the sum of the weights of this match is exactly equal to all the top targets and, because of the inequality above, the weights and values of any other matching scheme will not be greater than all the top targets and.
But the problem is that the export sub-chart for the current top-mark does not necessarily have a perfect match. In this case, the top label can be adjusted in some way. The method of adjustment is: based on the last unsuccessful search for the staggered road Dfs i was accessed and j edge not accessed (I,J) lx[i]+ly[j]-w[i][j] d d d d
at the beginning, randomly specify a feasible top mark, for example lx[i]=max{w[i][j]|j is the right point },ly[i]=0. Then, for each vertex , a find procedure similar to the Hungary algorithm , if a find does not succeed, follow this the point to which find is accessed makes the above adjustments to the feasible top mark. This will allow you to find the perfect match gradually.
It is important to note that in accordance with the aboveDthe definition to seekDwords needO (n^2)the time, becauseDneed to be askedO (n^2)times, this becomes the bottleneck of the algorithm. This can be optimized: setSlack[j]represents the point to the rightJFor all edges that are not in the exported sub-graph.Lx[i]+ly[j]-w[i][j]the minimum value, inFindprocess, if an edge is not in the exported sub-graph, use it to the correspondingSlackvalue to be updated. Then askDjust useO (N)time to findSlackThe minimum value is available.
The test data used by the following code is as follows:
The specific code is as follows:
PackageCom.liuzhen.practice;ImportJava.util.Scanner; Public classMain { Public Static intMAX = 100; Public Static intN; Public Static int[] Value =New int[MAX] [MAX];//the weight value of a given binary graph Public Static int[] lx =New int[MAX];//a feasible top mark for the left-half vertex of a binary graph Public Static int[] ly =New int[MAX];//a feasible top-mark for the right-half vertex of a binary graph Public Static Boolean[] SX =New Boolean[MAX];//used to record whether vertices of the left half of a binary chart are in the final result Public Static Boolean[] sy =New Boolean[MAX];//used to record whether the vertices in the right half of a binary chart are in the final result Public Static int[] Pre =New int[MAX];//vertex x used to record vertex y matches in the final result Public BooleanDfsintx) {//using the Hungarian algorithm to find the augmented pathSX[X] =true;//represents the left half vertex x contained in the final result for(inty = 0;y < n;y++) { if(!sy[y] && lx[x] + ly[y] = =Value[x][y]) {Sy[y]=true;//represents the right half vertex y contained in the final result if(Pre[y] = =-1 | |DFS (Pre[y])) {Pre[y]=x; return true; } } } return false; } Public intGETKM (intjudge) { if(Judge = =-1) {//The minimum weight matching of the representative search for binary graphs for(inti = 0;i < n;i++) for(intj = 0;j < n;j++) Value[i][j]=-1 * value[i][j];//change the weight to the opposite number, which is equivalent to finding the most powerful match } //Initialize Lx[i] and Ly[i] for(inti = 0;i < n;i++) {Ly[i]= 0; Lx[i]=Integer.min_value; for(intj = 0;j < n;j++) { if(Value[i][j] >Lx[i]) lx[i]=Value[i][j]; } } for(inti = 0;i < n;i++) Pre[i]=-1;//Initialize the right-half vertex y with a matching vertex of-1 for(intx = 0;x < n;x++) {//starting from the left half vertex, find the equal sub-graph perfect Match of the binary graph perfect match while(true) { for(inti = 0;i < n;i++) {//each search for an augmented path of x, initialize Sx[i] and sy[i] are traversedSx[i] =false; Sy[i]=false; } if(Dfs (x))//find the augmented path from X, end the loop, and look for the next X's augmented path Break; //The following is an adjustment for lx[i] and Ly[i] values for an augmented path that does not find vertex x intMin =Integer.max_value; for(inti = 0;i < n;i++) { if(Sx[i]) {//When Sx[i] has been traversed for(intj = 0;j < n;j++) { if(!sy[j]) {//When Sy[j] is not traversed if(Lx[i] + ly[j]-VALUE[I][J] <min) min= Lx[i] + ly[j]-Value[i][j]; } } } } if(min = = 0) return-1; for(inti = 0;i < n;i++) { if(Sx[i]) lx[i]= Lx[i]-min; if(Sy[i]) ly[i]= Ly[i] +min; } } } intsum = 0; for(inty = 0;y < n;y++) {System.out.println ("Y Vertex" +y+ "and x vertex" +pre[y]+ "match"); if(Pre[y]! =-1) Sum= Sum +Value[pre[y]][y]; } if(Judge = =-1) Sum=-1 *sum; returnsum; } Public Static voidMain (string[] args) {main test=NewMain (); Scanner in=NewScanner (system.in); N=In.nextint (); intK = In.nextint ();//the number of forward edges of a given binary graph for(inti = 0;i < k;i++) { intx =In.nextint (); inty =In.nextint (); intv =In.nextint (); Value[x][y]=v; } System.out.println (TEST.GETKM (1)); }}
Operation Result:
5100 0 1 0 2 2 3 4 3 4y Vertex 3 and x vertex 0 match y Vertex 2 and x vertex 1 match y vertex 0 and x vertex 2 match y vertex 1 and x Vertex 3 match y vertex 4 and x vertex 4 match 3
Resources:
1. the KM algorithm to find the maximal right dichotomy
2. Two graph maximum weight matching-km algorithm
3. binary graph with weights matching km algorithm and cost flow model establishment
Algorithm Note _139: Maximum weight allocation for binary graphs (Java)