AlgoVerse

کلاس‌های هم‌ارزی

از فهرستی از جفت‌های i ≡ j، کلاس‌های هم‌ارزی را پیدا می‌کند: هر جفت را در لیست هر دو عضو می‌گذارد و بعد با یک پشته همه‌ی اعضای یک کلاس را جمع می‌کند؛ O(n + m).

یک رابطه‌ی هم‌ارزی بازتابی، تقارنی و ترایا است، پس از چند جفت i ≡ j می‌شود همه‌ی اعضای هم‌ارز را نتیجه گرفت. الگوریتم هوروویتز دو مرحله دارد:

ادامه‌ی توضیح ↓
ورودی:
pairs 9×2خروجی PDF

۱۲ شیء و ۹ جفت؛ سه کلاس به دست می‌آید: {۰، ۴، ۱۱، ۲، ۷}، {۱، ۳، ۵} و {۶، ۱۰، ۸، ۹}.

  1. def equivalence(pairs):
  2. # Objects are 0..n-1; each row of pairs says i ≡ j.
  3. n = 0
  4. for i, j in pairs:
  5. n = max(n, i + 1, j + 1)
  6. seq = [[] for _ in range(n)]
  7. rows = [[x, seq[x], "·"] for x in range(n)] # for the picture: object, partners, class
  8. for i, j in pairs:
  9. seq[i].append(j)
  10. seq[j].append(i)
  11. out = [False] * n
  12. classes = []
  13. for i in range(n):
  14. if out[i]:
  15. continue
  16. out[i] = True
  17. cls = [i]
  18. rows[i][2] = len(classes)
  19. stack = [i]
  20. while stack:
  21. x = stack.pop()
  22. for y in seq[x]:
  23. if not out[y]:
  24. out[y] = True
  25. cls.append(y)
  26. rows[y][2] = len(classes)
  27. stack.append(y)
  28. classes.append(cls)
  29. return classes

ناوردا: هر شیئی که out آن درست است دقیقاً در یک کلاس است؛ همه‌ی شریک‌های اعضای کلاس فعلی یا در کلاس‌اند یا در پشته.

شروع اجرا

stack—
cls—
classes—

جدول هنوز خالی است.

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

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

pairs list

[0, 4][3, 1][6, 10][8, 9][7, 4][6, 8][3, 5][2, 11][11, 0]

Call stack

  1. equivalence()خط 1
گام ۱ از ۲۱۴
خط سیاه = pair, new_class · خط نارنجی = گام کلیدیpair: 0/9 · new_class: 0/3 · add: 0/9 · class_done: 0/3
    توضیح

    ایده

    یک رابطه‌ی هم‌ارزی بازتابی، تقارنی و ترایا است، پس از چند جفت i ≡ j می‌شود همه‌ی اعضای هم‌ارز را نتیجه گرفت. الگوریتم هوروویتز دو مرحله دارد:

    1. خواندن جفت‌ها: برای هر جفت، j را در لیست i و i را در لیست j می‌گذارد (تقارن).
    2. ساختن کلاس‌ها: از اولین شیئی که هنوز در کلاسی نیست شروع می‌کند، آن را در پشته می‌گذارد، و هر بار یک عضو را برمی‌دارد و همه‌ی شریک‌های تازه‌اش را به کلاس اضافه و در پشته می‌گذارد (ترایایی).

    این همان پیدا کردن مؤلفه‌های همبند یک گراف با DFS است.

    هزینه

    با n شیء و m جفت، هر جفت دو بار در لیست‌ها می‌آید و هر کدام یک بار بررسی می‌شود: O(n + m).

    ورودی

    هر سطر یک جفت [i, j] است. تعداد شیءها از بزرگ‌ترین عدد به دست می‌آید.