AlgoVerse

انتخاب فعالیت‌ها

بیشترین تعداد فعالیت بدون هم‌پوشانی را انتخاب می‌کند: همیشه فعالیتی که زودتر تمام می‌شود، اگر با قبلی تداخل نداشته باشد.

چند فعالیت (مثلاً کلاس‌ها در یک سالن) با زمان شروع s و پایان f داریم و می‌خواهیم بیشترین تعداد را بدون هم‌پوشانی انتخاب کنیم.

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

یازده فعالیت؛ چهار تا انتخاب می‌شوند: ۱ تا ۴، ۵ تا ۷، ۸ تا ۱۱ و ۱۲ تا ۱۶.

  1. def activity_selection(activities):
  2. # Each activity is [start, finish); take them in order of finishing time.
  3. acts = sorted(activities, key=lambda a: a[1])
  4. chosen = []
  5. free_from = 0
  6. for start, finish in acts:
  7. if start >= free_from:
  8. chosen.append([start, finish])
  9. free_from = finish
  10. return len(chosen)

ناوردا: فعالیت‌های انتخاب‌شده با هم تداخل ندارند و دست‌کم به اندازه‌ی هر جواب بهینه‌ای فعالیت تا زمان free_from دارند.

شروع اجرا

free_from—

acts

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

chosen

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

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

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

activities list

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

Call stack

  1. activity_selection()خط 1
گام ۱ از ۳۶
خط سیاه = check · خط نارنجی = گام کلیدیby_finish: 0/1 · check: 0/11 · choose: 0/4
    توضیح

    ایده

    چند فعالیت (مثلاً کلاس‌ها در یک سالن) با زمان شروع s و پایان f داریم و می‌خواهیم بیشترین تعداد را بدون هم‌پوشانی انتخاب کنیم.

    انتخاب حریصانه: فعالیت‌ها را بر اساس زمان پایان مرتب کن و هر فعالیتی را که بعد از آخرین فعالیت انتخاب‌شده شروع می‌شود بردار.

    چرا درست است؟

    فعالیتی که زودتر از همه تمام می‌شود، بیشترین زمان را برای بقیه باقی می‌گذارد. اگر یک جواب بهینه با آن شروع نشود، می‌شود اولین فعالیتش را با این یکی عوض کرد و هنوز تداخلی پیش نمی‌آید؛ پس انتخاب حریصانه همیشه در یک جواب بهینه هست.

    انتخاب بر اساس زودترین شروع یا کوتاه‌ترین مدت همیشه درست کار نمی‌کند (ورودی «طولانی‌ترین اول» را ببین).

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

    • جدول acts فعالیت‌های مرتب‌شده و جدول chosen انتخاب‌هاست؛ free_from لحظه‌ای است که سالن آزاد می‌شود.