AlgoVerse

شمارنده‌ی دودویی (تحلیل سرشکن)

یک شمارنده‌ی دودویی را هشت بار یکی زیاد می‌کند؛ یک افزایش ممکن است بیت‌های زیادی را عوض کند، ولی میانگین کمتر از ۲ است.

شمارنده‌ای دودویی با k بیت داریم و آن را بارها یکی زیاد می‌کنیم. یک افزایش بیت‌های ۱ انتهایی را صفر می‌کند (رقم نقلی) و اولین ۰ را یک. در بدترین حالت یک افزایش هر k بیت را عوض می‌کند. پس n افزایش حداکثر n·k تغییر؟

ادامه‌ی توضیح ↓
ورودی:
n=6خروجی PDF

از ۰ تا ۸: روی هم ۱۵ تغییر بیت برای ۸ افزایش، کمتر از ۲ برای هر افزایش.

  1. def binary_counter(bits):
  2. flips = 0
  3. for n in range(1, 9):
  4. i = 0
  5. while i < len(bits):
  6. if bits[i] == 0:
  7. break
  8. bits[i] = 0
  9. flips = flips + 1
  10. i = i + 1
  11. if i < len(bits):
  12. bits[i] = 1
  13. flips = flips + 1
  14. return flips

ناوردا: بیت‌ها همیشه عدد شمارنده را در مبنای ۲ نشان می‌دهند، با کم‌ارزش‌ترین بیت در خانه‌ی ۰.

شروع اجرا

000102030405

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

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

bits list

000000

Call stack

  1. binary_counter()خط 1
گام ۱ از ۱۰۳
خط سیاه = increment · خط نارنجی = گام کلیدیincrement: 0/8 · check: 0/15 · set: 0/8 · reset: 0/7
    توضیح

    مسئله

    شمارنده‌ای دودویی با k بیت داریم و آن را بارها یکی زیاد می‌کنیم. یک افزایش بیت‌های ۱ انتهایی را صفر می‌کند (رقم نقلی) و اولین ۰ را یک. در بدترین حالت یک افزایش هر k بیت را عوض می‌کند. پس n افزایش حداکثر n·k تغییر؟

    تحلیل سرشکن

    نه. بیت ۰ در هر افزایش عوض می‌شود، بیت ۱ هر دو افزایش یک بار، بیت ۲ هر چهار افزایش یک بار، و همین‌طور. پس روی هم:

    n + n/2 + n/4 + … < 2n

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

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

    • بیت ۰ (کم‌ارزش‌ترین) در سمت چپ تصویر است.
    • با سطح جزئیات «هر دور حلقه» افزایش‌ها را یکی‌یکی ببین و شمار reset و set را با ۲ × ۸ = ۱۶ مقایسه کن.