Documentos de Académico
Documentos de Profesional
Documentos de Cultura
Berge's Theorem
Wording . Matching the maximum if and only if there is increasing relative thereto
circuits.
The proof of necessity . We show that if a matching as possible, there is no
increased relative to a chain. Proof of this is constructive: we show you how to
increase through this magnifying circuit power matching unit.
To do this, perform the so-called matching alternating along the chain . We recall
that, by definition, the first edge circuit does not belong to matching, the second belongs to the third - again belongs to the fourth - owned, etc. Let's change the
status of all the edges along the chain : those edges that are not included in the
matching (the first, third and so on until the last) is included in the matching, and the
edges that were previously included in the matching (the second, fourth, and so on
up penultimate) - remove from it.
It is understood that the power matching with increased by one (because it was
added at one edge longer than the deleted). It remains to verify that we have built a
correct matching, ie, that no vertex of the graph does not have a right of two adjacent
edges of this matching. For all peaks alternating chain , except the first and last, it
follows from the alternation of the algorithm: first we have removed the top of each of
these adjacent edges, and then added. For the first and last vertex chain and
nothing could be broken as to interlace they were to be unsaturated. Finally, for all
the other peaks - not in the chain - obviously, nothing has changed.Thus, we really
built a matching, and one greater power than the old one, which completes the proof
of the necessity.
is not increasing
Algorithm Kuna
Kuhn's algorithm - a direct application of Theorem Berge. It can be summarized as
follows: first take an empty matching, and then - in the graph is possible to find
magnifying chain - will perform striping matching along the chain, and repeat the
process of finding increasing the chain. Once a circuit is not found - the process
stops - the current matching is maximum.
It remains to detail the method of finding increasing circuits. The algorithm Kuhn just looking for any of these circuits via bypass in depth or width . Kuhn's algorithm
looks at all the vertices of the graph at a time, starting from each round, trying to find
a magnifying circuit, starting at this summit.
It is more convenient to describe the algorithm, assuming that the graph is already
divided into two parts (in fact the algorithm can be implemented and so that he was
not allowed to enter the graph is clearly divided into two parts).
The algorithm looks at all the vertices of the first part of the graph:
. If
the current node is already filled with a matching current (ie already selected some
edge adjacent to it), then skip this vertex. Otherwise - the algorithm is trying to
saturate this summit, which starts search for increasing the chain, starting from this
node.
Search magnifying circuit by means of a special bypass in depth or width (usually for
ease of implementation is used to bypass the depth). Initially bypass in depth is the
current top of the unsaturated first part. To view all of the edges of the top, let the
current edge - that edge
. If the node is not yet saturated with matching, it
means that we were able to find a magnifying circuit: it consists of a single rib
; in this case, just include it in the edge matching and stop increasing the search
from the top of the chain . Otherwise - if the already saturated with some
edge
, then try to pass along this edge: thus we will try to find a magnifying
circuit passing through the ribs
,
. Simply move on in our crawl to the
top - now we are trying to find a chain of magnifying this summit.
One can understand that as a result of this tour, started from the top , or find
magnifying circuit, thereby saturate the top , such as a magnifying circuit does not
find (and, therefore, the vertex will not be able to become rich).
After all nodes
Working hours
Thus, the algorithm can be represented as Kuhn series of launches bypass in
depth / width over the entire graph. Consequently, all the algorithm is executed
during
However, this estimate may be a bit better . It turns out that the algorithm Kuhn
importantly, what proportion is chosen for the first, and which - for the second. In
fact, in the above described realization starts crawling depth / width of the peaks
occur only the first part, so the whole algorithm is executed in a time
where - the number of vertices of the first part. In the worst case, it is
(where - the number of vertices of the second part). This shows that it is cheaper,
when the first share has less number of vertices than the second. On a very
unbalanced graphs (when and very different), this translates into a significant
difference times of operation.
Realization
We give here the implementation of the above algorithm, based on the bypass in
depth and take a bipartite graph clearly broken into two parts of the graph. This
implementation is very concise and, perhaps, it is worth remembering in this form.
Here - the number of vertices in the first part, - in the second part,
- a list of
the top edges of the first part (ie, a list of numbers of vertices, in which the edges of
the lead ). Tops in both lobes are numbered independently, ie first share - with the
numbers
, the second - with the numbers
.
try_kuhn (v);
}
for (int i=0; i<k; ++i)
if (mt[i] != -1)
printf ("%d %d\n", mt[i]+1, i+1);
}
Once again, that Kuhn's algorithm is easy to implement, and so he worked on graphs
that are known, they are bipartite, but clear their division into two parts found. In this
case, it will have to abandon the easy division into two parts, and all the information
stored for all vertices. To do this, an array of lists is now specifies not only for the
vertices of the first part, and for all vertices (of course, now the tops of both shares
are numbered in total numbering - from before ). Arrays
and
now also
determined for the vertices of both lobes, and, accordingly, they must be maintained
in this state.
Better implementation
We modify the algorithm is as follows. Prior to the main loop algorithm will find some
simple algorithm arbitrary matching (a simple heuristic algorithm ), and only then
will perform a series of function calls kuhn (), which will improve this matching. As a
result, the algorithm will run noticeably faster on random graphs - because in most
graphs you can easily dial a matching large enough weight with the help of
heuristics, and later found to improve the matching up to the maximum already Kuhn
conventional algorithm. Thus, we save on starting a crawl depth of the peaks, which
we have already included using heuristics to the current matching.
For example , you can just go through all the vertices of the first part, and for each
of them to find any edge that can be added to matching, and add it. Even such a
simple heuristic algorithm can accelerate Kuna several times.
It should be noted that the main loop will have to be modified slightly. Because the
function is called
in the main loop is assumed that the current node is not
included in the matching, it is necessary to add the appropriate checks.
The implementation of the code will change only in the function main ():
int main() {
... ...
mt.assign (k, -1);
vector<char> used1 (n);
for (int i=0; i<n; ++i)
for (size_t j=0; j<g[i].size(); ++j)
if (mt[g[i][j]] == -1) {
mt[g[i][j]] = i;
used1[i] = true;
break;
}
for (int i=0; i<n; ++i) {
if (used1[i]) continue;