AlgoVerse

ضرب ماتریس‌های خلوت

هر سطر را فقط با جمله‌های ناصفرش نگه می‌دارد و فقط ضرب‌های ناصفر را انجام می‌دهد؛ برای ماتریس‌های خلوت خیلی کمتر از n³ ضرب.

در ماتریس خلوت بیشتر ضرب‌های A[i][k]·B[k][j] صفرند و انجامشان بی‌فایده است. اگر هر سطر را فقط با جمله‌های ناصفرش نگه داریم:

ادامه‌ی توضیح ↓
ورودی:
A 4×4 · B 4×4خروجی PDF

دو ماتریس ۴×۴ که بیشتر خانه‌هایشان صفر است؛ به‌جای ۶۴ ضرب فقط ۵ ضرب لازم است.

  1. def sparse_multiply(A, B):
  2. if len(A[0]) != len(B):
  3. return None
  4. # Row lists: for each row, only its non-zero (column, value) pairs.
  5. a_rows = [[(j, v) for j, v in enumerate(row) if v != 0] for row in A]
  6. b_rows = [[(j, v) for j, v in enumerate(row) if v != 0] for row in B]
  7. C = []
  8. products = 0
  9. for i in range(len(A)):
  10. acc = {}
  11. for k, a in a_rows[i]:
  12. for j, b in b_rows[k]:
  13. acc[j] = acc.get(j, 0) + a * b
  14. products = products + 1
  15. C.append(sorted((j, v) for j, v in acc.items() if v != 0))
  16. return products

ناوردا: هر ضرب انجام‌شده دو جمله‌ی ناصفر را ضرب می‌کند و A[i][k]·B[k][j] فقط به خانه‌ی (i, j) حاصل اضافه می‌شود.

شروع اجرا

products—

a_rows

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

b_rows

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

C

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

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

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

A list

[1, 0, 0, 2][0, 0, 3, 0][0, 0, 0, 0][4, 0, 0, 0]

B list

[0, 5, 0, 0][0, 0, 0, 0][6, 0, 0, 7][0, 0, 8, 0]

Call stack

  1. sparse_multiply()خط 1
گام ۱ از ۴۷
خط سیاه = row_done · خط نارنجی = گام کلیدیrow_lists: 0/1 · product: 0/5 · row_done: 0/4
    توضیح

    ایده

    در ماتریس خلوت بیشتر ضرب‌های A[i][k]·B[k][j] صفرند و انجامشان بی‌فایده است. اگر هر سطر را فقط با جمله‌های ناصفرش نگه داریم:

    • برای سطر i از A، هر جمله‌ی ناصفر A[i][k] را در جمله‌های ناصفر سطر k از B ضرب کن و در acc[j] جمع کن.
    • acc سطر i حاصل است؛ صفرها کنار گذاشته می‌شوند.

    هزینه

    تعداد ضرب‌ها دقیقاً تعداد جفت‌های ناصفر (A[i][k], B[k][j]) است، که برای ماتریس‌های خلوت خیلی کمتر از n³ است. کتاب هوروویتز همین کار را روی سه‌تایی‌ها و با ترانهاده‌ی B انجام می‌دهد؛ ایده یکی است.

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

    • جدول‌های a_rows و b_rows فهرست جمله‌های ناصفر هر سطرند و C حاصل به همان شکل. products تعداد ضرب‌های انجام‌شده است.