AlgoVerse

الگوریتم کروسکال

یال‌ها را از سبک به سنگین مرور می‌کند و هر یالی را که دور نمی‌سازد به درخت پوشای کمینه اضافه می‌کند.

درخت پوشای کمینه (MST) زیرمجموعه‌ای از یال‌های یک گراف همبند و بی‌جهت است که همه‌ی گره‌ها را به هم وصل می‌کند، دور ندارد و جمع وزن‌هایش کمترین مقدار ممکن است.

ادامه‌ی توضیح ↓
ورودی:
V=9 · E=14 · src=Aخروجی PDF

گراف نه‌گره‌ای با ۱۴ یال؛ درخت پوشای کمینه ۸ یال و وزن کل ۳۷ دارد.

  1. def kruskal(graph, src):
  2. # Kruskal does not need a start node; src is ignored.
  3. parent = {v: v for v in graph}
  4. edges = sorted((w, u, v) for u in graph for v, w in graph[u] if u < v)
  5. mst = []
  6. for w, u, v in edges:
  7. ru = find(parent, u)
  8. rv = find(parent, v)
  9. if ru == rv:
  10. continue
  11. parent[ru] = rv
  12. mst.append((u, v, w))
  13. return mst
  14. def find(parent, x):
  15. while parent[x] != x:
  16. x = parent[x]
  17. return x

ناوردا: یال‌های mst همیشه زیرمجموعه‌ای از یک درخت پوشای کمینه‌اند و دور ندارند.

شروع اجرا

48118247149102617ABCDEFGHI
  • گره‌ی جاری
  • درخت پوشای کمینه تا اینجا
  • یالِ در حال بررسی

متغیرهای محلی

src'A'

نارنجی = در همین گام عوض شد

graph dict
  • 'A': [('B', 4), ('H', 8)]
  • 'B': [('A', 4), ('H', 11), ('C', 8)]
  • 'C': [('B', 8), ('I', 2), ('F', 4), ('D', 7)]
  • 'D': [('C', 7), ('F', 14), ('E', 9)]
  • 'E': [('D', 9), ('F', 10)]
  • 'F': [('C', 4), ('D', 14), ('E', 10), ('G', 2)]
  • 'G': [('F', 2), ('I', 6), ('H', 1)]
  • 'H': [('A', 8), ('B', 11), ('G', 1), ('I', 7)]
  • 'I': [('C', 2), ('G', 6), ('H', 7)]

Call stack

  1. kruskal()خط 1
گام ۱ از ۲۲۲
خط سیاه = consider · خط نارنجی = گام کلیدیsort_edges: 0/1 · consider: 0/14 · check: 0/14 · union: 0/8 · reject: 0/6

    رشد تعداد عملیات با اندازه‌ی ورودی

    میانگین ۵ گراف تصادفی برای هر n (با seed ثابت). نشانگر توخالی = ورودی فعلی.

    • consider
    • union
    • ورودی فعلی (n=9)
    0204060481216202428n = تعداد گره‌هاconsiderunion
    نمایش به شکل جدول
    nconsiderunion
    45.23
    813.87
    1220.811
    162815
    2035.419
    2437.223
    2847.227
    توضیح

    ایده

    درخت پوشای کمینه (MST) زیرمجموعه‌ای از یال‌های یک گراف همبند و بی‌جهت است که همه‌ی گره‌ها را به هم وصل می‌کند، دور ندارد و جمع وزن‌هایش کمترین مقدار ممکن است.

    کروسکال یک الگوریتم حریصانه است: یال‌ها را از سبک به سنگین مرور می‌کند و هر یال را برمی‌دارد، مگر اینکه با یال‌های برداشته‌شده دور بسازد.

    تشخیص دور با Union–Find

    یال u — v وقتی دور می‌سازد که u و v از قبل به هم وصل باشند. برای فهمیدن این، هر گره در یک «مجموعه» است که با دیکشنری parent به شکل درخت نگه داشته می‌شود:

    • find(x) از x آن‌قدر در parent بالا می‌رود تا به ریشه‌ی مجموعه برسد.
    • اگر ریشه‌ی u و v یکی بود، یال رد می‌شود. وگرنه parent[ru] = rv دو مجموعه را یکی می‌کند و یال به mst اضافه می‌شود.

    هزینه

    مرتب کردن یال‌ها O(E log E) است و بخش بیشتر زمان را می‌گیرد. این پیاده‌سازی ساده‌ی find در بدترین حالت می‌تواند کند شود؛ نسخه‌ی کتاب‌ها با «فشرده‌سازی مسیر» و «اتحاد بر اساس رتبه» آن را تقریباً O(1) می‌کند.

    در trace به چه چیزی نگاه کنی

    • یال‌های آبی درخت پوشای کمینه‌ی ساخته‌شده تا اینجا هستند و یال نارنجی همانی است که بررسی می‌شود.
    • عدد کنار هر گره parent آن است: با دنبال کردن این عددها به ریشه‌ی مجموعه می‌رسی.
    • در ورودی «گراف خودش درخت است» هیچ یالی رد نمی‌شود؛ در «ناهمبند» به‌جای یک درخت، دو درخت (جنگل) ساخته می‌شود.