الگوریتم هاپکرافت-کارپ

مسیرهای افزایشی

به راسی که نقطه پایانی یال قرار گرفته و در تطابق M نیست، راس آزاد و به یالی که در تطابق M قرار نگرفته، یال آزاد می‌گوییم. مفهوم بنیادین استفاده شده در این الگوریتم این است که یک مسیر افزایشی، مسیری است که از یک راس آزاد شروع می‌شود و به یک راس آزاد ختم می‌شود و به‌طور تناوبی شامل یک یال آزاد و یک یال غیر آزاد می‌باشد. اگر تطابق M دارای اندازه n باشد و P یک مسیر افزایشی بر مبنای M باشد تفاضل متقارن دو مجموعه یال M و P یک تطابق با سایز n+۱ می‌باشد. بنابراین پیدا کردن مسیر افزایشی می‌تواند سایز تطابق را افزایش دهد.

همچنین فرض کنید تطابق M بهینه نباشد و P را تفاضل متقارن M و M* که M* تطابق بهینه‌است تصور کنید. بنابراین P باید شامل مجموعه‌ای از دورهای مجزا و مسیرهای افزایشی باشد. تفاوت اندازه M و M* تعداد مسیرهای موجود در P است. بنابراین اگر هیچ مسیر افزایشی پیدا نشود، الگوریتم به پایان می‌رسد پس M باید همان تطابق بهینه باشد.

تحلیل الگوریتم

هر مرحله شامل یک جستجوی سطح اول و یک جستجوی عمق اول است. پس هر مرحله می‌تواند در زمان خطی پیاده‌سازی شود. بنابراین n√ مرحله اول در گرافی با n راس و m یال (O(m√n زمان می‌برد.
می‌توان نشان داد که هر مرحله، حداقل یک واحد طول کوتاه‌ترین مسیر افزایشی را زیاد می‌کند: در هر مرحله بزرگترین مجموعه شامل کوتاه‌ترین مسیرهای افزایشی پیدا می‌شود پس مسیرهای باقی‌مانده باید بلندتر باشند. بنابراین پس از به پایان رسیدن n√ مرحله، کوتاه‌ترین مسیر افزایشی حداقل شامل n√ یال است.

تفاضل متقارن تطابق بهینه نهایی و تطابق M ایجاد شده در هر مرحله، مجموعه از رئوس مسیرهای افزایشی و دورهای متناوب را تشکیل می‌دهند. اگر هر مسیر این مجموعه دارای حداقل طول n√ باشد، حداکثر n√ مسیر در این مجموعه وجود دارد. و اندازه تطابق نهایی می‌تواند حداکثر n√ یال از تطابق M بیشتر باشد. هر مرحله از الگوریتم اندازه تطابق را حداقل یک واحد افزایش می‌دهد و پیش از به پایان رسیدن الگوریتم حداکثر n√ مرحله افزایشی وجود دارد.

الگوریتم حداکثر شامل n√2 مرحله‌است و در بدترین حالت از مرتبه زمانی (O(m√n می‌باشد.

گراف‌های غیر دوبخشی

ایده پیدا کردن مجموعه‌ای شامل بیشترین تعداد از کوتاه‌ترین مسیرهای افزایشی برای پیدا کردن تطابق بیشینه در گراف‌های غیر دوبخشی نیز به کار می‌رود. و با همان استدلال این الگوریتم شامل (O(√n مرحله می‌باشد. اگرچه برای یک گراف غیر دوبخشی، پیدا کردن مسیر افزایشی در هر مرحله دشوارتر است. Micali و Vazirani در سال 1980 نشان دادند چگونه هر یک از (O(√n مرحله را می‌توان در زمان خطی انجام داد. بنابراین این الگوریتم مرتبه زمانی مشابهی با الگوریتم هاپکرافت – کارپ دارد.

شبه کد

1 /*
 2   G = G₁  G₂  {NIL}
 3   G1 و G2 دو بخش گراف و NIL یک راس منحصربه‌فرد null است.
 4 */
 5
 6 function BFS ()
 7     for v in G₁
 8         if Pair[v] == NIL
 9             Dist[v] = 0
10             Enqueue(Q,v)
11         else
12             Dist[v] = 
13     Dist[NIL] = 
14     while Empty(Q) == false
15         v = Dequeue(Q)
16         for each u in Adj[v]
17             if Dist[ Pair[u] ] == 
18                 Dist[ Pair[u] ] = Dist[v] + 1
29                 Enqueue(Q,Pair[u])
20     return Dist[NIL] != 
21
22 function DFS (v)
23     if v != NIL
24         for each u in Adj[v]
25             if Dist[ Pair[u] ] == Dist[v] + 1
26                 if DFS(Pair[u]) == true
27                     Pair[u] = v
28                     Pair[v] = u
39                     return true
30         Dist[v] = 
31         return false
32     return true
33
34 function Hopcroft-Karp
35     for each v in G
36         Pair[v] = NIL
37     matching = 0
38     while BFS() == true
49         for each v in G₁
40             if Pair[v] == NIL
41                 if DFS(v) == true
42                     matching = matching + 1
44     return matching