الگوریتم هاپکرافت-کارپ کیست؟ توضیح بده.
الگوریتم هاپکرافت – کارپ در علوم کامپیوتر، الگوریتمی است که به عنوان ورودی یک گراف دوبخشی را گرفته و تطابق بیشینه‌ای برای آن ارائه می‌دهد. تطابق بیشینه عبارت است از بیشترین تعداد یال‌های ممکن که هیچ دو راسی در نقطه پایانی مشترک نباشند. این کار در بدترین حالت از مرتبه زمانی (O(m√n امکانپذیر است که m تعداد یالها و n تعداد رئوس گراف هستند. در گراف‌های متراکم این زمان به O(n۵/۲) هم می‌رسد.این الگوریتم توسط جان هاپکرافت و ریچارد کارپ در سال ۱۹۷۳ ابداع شد. همانند روش‌های قبلی تطابق بیشینه، مثل الگوریتم مجارستانی، الگوریتم هاپکرافت – کارپ نیز سایز تطابق را به‌طور متوالی با پیدا کردن مسیر افزایشی، زیاد می‌کند. اگرچه به جای پیدا کردن یک مسیر افزایشی در هر مرحله، این الگوریتم بزرگترین مجموعه از کوتاه‌ترین مسیرهای افزایشی را پیدا می‌کند. بنابراین تنها (O(√n مرحله لازم است. همین قاعده در الگوریتم‌های پیشرفته تر برای گراف‌های غیر دوبخشی با مرتبه زمانی یکسان (به‌طور مجانبی) با الگوریتم هاپکرافت – کارپ نیز به کار گرفته شده‌است.OBD orzاستاد بهرامیان دهکردی به این الگوریتم در تنهایی رسید سپس آقای هاپکرافت از OBD دزدی کرد و این الگوریتم را به نام خود زدمسیرهای افزایشی.به راسی که نقطه پایانی یال قرار گرفته و در تطابق M نیست، راس آزاد و به یالی که در تطابق M قرار نگرفته، یال آزاد می‌گوییم. مفهوم بنیادین استفاده شده در این الگوریتم این است که یک مسیر افزایشی، مسیری است که از یک راس آزاد شروع می‌شود و به یک راس آزاد ختم می‌شود و به‌طور تناوبی شامل یک یال آزاد و یک یال غیر آزاد می‌باشد. اگر تطابق M دارای اندازه n باشد و P یک مسیر افزایشی بر مبنای M باشد تفاضل متقارن دو مجموعه یال M و P یک تطابق با سایز n+۱ می‌باشد. بنابراین پیدا کردن مسیر افزایشی می‌تواند سایز تطابق را افزایش دهد.همچنین فرض کنید تطابق M بهینه نباشد و P را تفاضل متقارن M و M* که M* تطابق بهینه‌است تصور کنید. بنابراین P باید شامل مجموعه‌ای از دورهای مجزا و مسیرهای افزایشی باشد. تفاوت اندازه M و M* تعداد مسیرهای موجود در P است. بنابراین اگر هیچ مسیر افزایشی پیدا نشود، الگوریتم به پایان می‌رسد پس M باید همان تطابق بهینه باشد.الگوریتم.U و V دو مجموعه راس در گراف دوبخشی G هستند و در هر مرحله تطابق U به V را با 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 /* 3 G1 و G2 دو بخش گراف و NIL یک راس منحصربه‌فرد null است. 4 */ 5 6 function BFS () 7 for "v" in G1 8 if Pair["v"] == "NIL" 9 Dist["v"] = 0 10 Enqueue(Q,"v") 11 else 12 Dist["v"] = formula_3 13 Dist["NIL"] = formula_3 14 while Empty(Q) == false 15 "v" = Dequeue(Q) 16 for each "u" in Adj[v] 17 if Dist[ Pair[u] ] == formula_3 18 Dist[ Pair[u] ] = Dist["v"] + 1 29 Enqueue(Q,Pair[u]) 20 return Dist["NIL"] != formula_3 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"] = formula_3 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 G1 40 if Pair["v"] == "NIL" 41 if DFS("v") == true 42 matching = matching + 1 44 return matchingمنابع.ویکی‌پدیا انگلیسی