Best match for binary graph (KM algorithm) __ algorithm

Source: Internet
Author: User
Tags bool int size min printf
Looking for a standard to study a bit, modified into their own style, paste it up.

Reference:
KM algorithm by giving each vertex a label (called the top mark) to the problem of finding the maximum right matching to the problem of complete matching. The top mark of the Vertex XI is a[i], the top mark of the vertex Yi is b [i], and the Benquan between the Vertex XI and the YJ is w[i,j]. At any point in the algorithm execution, A[i]+b[j]>=w[i,j] is always true for either edge (I,J). Km the correctness of the algorithm is based on the following theorem:
If the sub-graph (i,j) consisting of all the edges (a[i]+b[j]=w[i,j) in the binary graph (called Equal sub-graph) has a complete match, then this complete match is the maximum weight matching of the binary graph.
This theorem is obvious. Because for any one of the binary graphs, if it is contained in an equal sub-graph, then its Benquan and equals the top label of all vertices, and if it has an edge that is not included in the equal sub-graph, then its Benquan and is smaller than the top of all vertices and. So the complete match of the equal sub-graph must be the maximal right match of the binary graph.
Initially in order for A[I]+B[J]>=W[I,J] to be established, the a[i] is the maximum weight of all the edges associated with vertex XI, b[j]=0. If the current equality sub-graph does not have a complete match, modify the top label as follows to make the equality sub-graph expand until the equality sub-graph has a complete match.
We're asking for a complete match for the current equality sub-graph to fail because we can't find a staggered path from it for an X vertex. At this point we get a staggered tree whose leaf nodes are all x vertices. Now we're going to reduce the top of the x vertex in the staggered tree by a certain value. The top of the d,y vertex all increases the same value D, then we find:
The value of a[i]+b[j] does not change at both ends of the edge (I,J) in the interlaced tree. That is, it originally belonged to an equal sub-graph, which is still part of the equal child.
None of the sides (I,J), A[i], and b[j] in the interlaced tree have changed. That is, it originally belonged to (or does not belong to) an equal sub-graph, and now still belongs to (or does not belong to) an equal sub-graph.
The X-end is not in the staggered tree, and the Y-end is in the edge of the Interleaved tree (I,J), and its a[i]+b[j] value increases. It originally does not belong to the equality sub-graph, and is still not part of the equality sub-graph.
The X-end is in the staggered tree, and the Y-end is not on the Edge (I,J) in the interlaced tree, and its a[i]+b[j] value is decreased. It is also said that it originally did not belong to the equal sub-graph, it may now enter the equal sub-graph, so that the equal sub-graph has been expanded.
Now the problem is to ask for D value. For A[I]+B[J]>=W[I,J] to always be true, and at least one edge into the equal sub-graph, d should be equal to min{a[i]+b[j]-w[i,j]| Xi in the staggered tree, Yi is not in the interlaced tree}.
The above is the basic idea of the KM algorithm. But the simple implementation method, the time complexity of O (N4)-Need to find O (n) Secondary augmentation path, each augmentation needs to modify the O (N) sub-index, each time the top is modified to enumerate the edges to find D value, the complexity of O (N2). In fact, the complexity of the KM algorithm can be achieved O (N3). We give each y vertex a "slack" function slack, which is initialized to infinity each time we start looking for an augmented path. While looking for an augmented path, when checking for edges (i,j), if it is not in the equal sub-graph, let slack[j] become the smaller value of the original value and a [i]+b[j]-w[i,j]. This way, when you modify the top label, take all the minimum values in the slack value of the y vertices that are not in the interleaved tree as the D value. However, it is important to note that all slack values are subtracted from D when the top label is modified.

#include < Cstdio >
#include < Memory.h >
#include < algorithm >//Using the Min function
using namespace Std;

const int MAX = 1024;

int n; Size of X
int weight [MAX] [MAX]; X-To-Y mappings (weights)
int LX [MAX], ly [MAX]; Label
BOOL SX [MAX], SY [MAX]; Have you ever been searched?
int match [MAX]; Y (i) matches X (match [i])

Initialize weights
void init (int size);
Find the augmented path from X (U) and return true if found
BOOL Path (int u);
Parameter maxsum is true, returns the maximum weight match, otherwise the minimum weight match
int Bestmatch (BOOL maxsum = TRUE);

void init (int size)
{
According to the actual situation, add code to initialize
n = size;
for (int i = 0; i < n; i + +)
for (int j = 0; J < N; j + +)
scanf ("%d", & weight [i] [j]);
}


BOOL Path (int u)
{
SX [U] = true;
for (int v = 0; v < n; v + +)
if (! sy [v] && Lx[u] + ly [v] = = weight [u] [v])
{
sy [v] = true;
if (match [v] = =-1 | | Path (match [v]))
{
Match [v] = u;
return true;
}
}
return false;
}

int Bestmatch (bool maxsum)
{
int I, J;
if (! Maxsum)
{
for (i = 0; i < n; i + +)
for (j = 0; J < N; j + +)
weight [i] [j] =-weight [i] [j];
}

Initialize label
for (i = 0; i < n; i + +)
{
LX [i] =-0x1fffffff;
ly [i] = 0;
for (j = 0; J < N; j + +)
if (lx [i] < weight [i] [j])
LX [i] = weight [i] [j];
}

memset (Match,-1, sizeof (match));
for (int u = 0; u < n; U + +)
while (1)
{
memset (SX, 0, sizeof (SX));
memset (sy, 0, sizeof (SY));
if (Path (U))
break;

modifying labels
int dx = 0x7FFFFFFF;
for (i = 0; i < n; i + +)
if (sx [i])
for (j = 0; J < N; j + +)
if (! Sy [j])
DX = min (lx[i] + ly [j]-weight [i] [j], DX);
for (i = 0; i < n; i + +)
{
if (sx [i])
LX [i]-= DX;
if (sy [i])
ly [i] + = DX;
}
}

int sum = 0;
for (i = 0; i < n; i + +)
sum + = weight [match [i]] [i];

if (! Maxsum)
{
sum =-sum;
for (i = 0; i < n; i + +)
for (j = 0; J < N; j + +)
weight [i] [j] =-weight [i] [j]; If you need to keep weight [] [] The original value, you need to restore it
}
return sum;
}


int main ()
{
int n;
scanf ("%d", &n);
Init (n);
int cost = Bestmatch (true);

printf ("%d", cost);
for (int i = 0; i < n; i + +)
{
printf ("Y%d-X%d", I, match [i]);
}

return 0;
}

/*
5
3 4 6) 4 9
6 4 5) 3 8
7 5 3) 4 2
6 3 2) 2 5
8 4 5) 4 7
Execute Bestmatch (true) with a result of 29
*/

/*
5
7 6 4) 6 1
4 6 5) 7 2
3 5 7) 6 8
4 7 8) 8 5
2 6 5) 6 3
Executes Bestmatch (false) with a result of 21
*/
This implementation is different from the one depicted in the graph book, which is the same as the Hungarian algorithm method (constantly looking for augmented roads. ), instead of calling the Hungarian algorithm in the process like a book:

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.