کوتاه‌ترین مسیر با منبع واحد: الگوریتم‌های بلمن-فورد و دیجکسترا

یافتن کوتاه‌ترین مسیرها در یک گراف وزن‌دار پیچیده‌تر از حالت بدون‌وزن حل‌شده توسط جستجوی سطح‌اول است، به‌ویژه وقتی وزن‌های یال منفی ممکن باشند. این راهنمای جامع تکنیک relaxation زیربنای همه الگوریتم‌های کوتاه‌ترین‌مسیر، الگوریتم بلمن-فورد که وزن‌های منفی را مدیریت می‌کند و چرخه‌های منفی را تشخیص می‌دهد، و الگوریتم کارآمدتر دیجکسترا برای گراف‌های بدون وزن‌های منفی را پوشش می‌دهد.

الگوریتم کوتاه‌ترین مسیرالگوریتم بلمن-فوردالگوریتم دیجکسترا

~6 دقیقه مطالعه · آخرین به‌روزرسانی ۱۶ شهریور ۱۴۰۵

چرا کوتاه‌ترین مسیرهای وزن‌دار به تکنیک‌های جدید نیاز دارند

جستجوی سطح‌اول، که پیش‌تر در این مجموعه بحث شد، کوتاه‌ترین مسیرها را با شمردن یال‌ها پیدا می‌کند، که وقتی هر یال همان وزن ضمنی ۱ را داشته باشد کاملاً کار می‌کند. وقتی یال‌ها وزن‌های متفاوتی دارند، که نشان‌دهنده فاصله‌ها، هزینه‌ها، یا زمان‌هاست، یک رویکرد متفاوت نیاز است، و امکان وزن‌های یال منفی پیچیدگی‌های واقعی معرفی می‌کند که BFS هرگز مجبور به در نظر گرفتن آن‌ها نبود.

تکنیک اصلی: Relaxation

هر الگوریتم کوتاه‌ترین‌مسیر در این مقاله روی همان عملیات بنیادین، Relaxation، ساخته می‌شود: برای یک یال (u, v) با وزن w، بررسی کن آیا عبور از u مسیر کوتاه‌تری به v نسبت به بهترین مسیر شناخته‌شده فعلی ارائه می‌دهد، و اگر چنین است، فاصله ثبت‌شده و اسلاف v را به‌روزرسانی کن.

RELAX(u, v, w):
  اگر v.d > u.d + w(u, v):
      v.d = u.d + w(u, v)
      v.p = u

هر رأس با d = infinity شروع می‌شود (به‌جز منبع، که با ۰ شروع می‌شود)، و الگوریتم‌ها عمدتاً در ترتیبی که relaxation را در سراسر یال‌های گراف اعمال می‌کنند متفاوت‌اند.

الگوریتم بلمن-فورد: مدیریت وزن‌های منفی

Bellman-Ford الگوریتم عمومی‌تری است، که حتی وقتی وزن‌های یال منفی باشند به‌درستی کار می‌کند، و می‌تواند به‌طور اضافی وجود یک Negative-Weight Cycle (چرخه با وزن منفی) دسترس‌پذیر از منبع را تشخیص دهد — وضعیتی که در آن کوتاه‌ترین مسیرها حتی به‌خوبی تعریف‌شده نیستند، چون می‌توان به‌طور نامحدود دور چرخه منفی چرخید تا مسیر را به‌طور دلخواه کوتاه کرد.

BELLMAN-FORD(G, w, s):
  INITIALIZE-SINGLE-SOURCE(G, s)
  برای i = 1 تا |G.V| - 1:
      برای هر یال (u, v) در G.E:
          RELAX(u, v, w)
  برای هر یال (u, v) در G.E:
      اگر v.d > u.d + w(u, v):
          FALSE را برگردان      // چرخه با وزن منفی تشخیص داده شد
  TRUE را برگردان

الگوریتم صرفاً هر یال در گراف را، تکرارشده |V| - 1 بار، relax می‌کند. این تعداد تکرار دلخواه نیست: یک کوتاه‌ترین مسیر در یک گراف با V رأس می‌تواند حداکثر V-1 یال داشته باشد (با فرض عدم وجود چرخه‌های منفی، چون مسیری که دوبار از یک رأس بازدید کند نمی‌تواند کوتاه‌ترین باشد)، پس پس از V-1 دور relax‌کردن هر یال، هر کوتاه‌ترین مسیری تضمین می‌شود کاملاً منتشر شده باشد، صرف‌نظر از اینکه یال‌ها در چه ترتیبی در نظر گرفته شده باشند.

تشخیص چرخه‌های منفی

حلقه نهایی بررسی می‌کند آیا هر یالی همچنان می‌تواند پس از V-1 دور relax شود. اگر چنین باشد، این یعنی برخی مسیر همچنان پس از بیشتر از یال‌هایی که هر کوتاه‌ترین‌مسیر غیرچرخه‌ای احتمالاً به آن‌ها نیاز داشت در حال بهبود است، که فقط ممکن است اگر یک چرخه با وزن منفی در جایی دسترس‌پذیر از منبع وجود داشته باشد.

از آنجا که الگوریتم V-1 دور اجرا می‌کند، هرکدام هر یال را بررسی می‌کنند، بلمن-فورد در زمان O(VE) اجرا می‌شود — به‌طور محسوسی کندتر از الگوریتم‌هایی که در ادامه می‌آیند، اما هروقت وزن‌های منفی ممکن باشند ضروری است.

الگوریتم دیجکسترا: سریع‌تر، اما بدون مجوز وزن‌های منفی

وقتی همه وزن‌های یال تضمین‌شده غیرمنفی باشند، Dijkstra's Algorithm (الگوریتم دیجکسترا) یک راه‌حل به‌طور قابل‌توجه سریع‌تر با پردازش رأس‌ها به یک ترتیب حریصانه خاص، با استفاده از ساختار صف اولویت که پیش‌تر در این مجموعه درباره هیپ‌ها بحث شد، ارائه می‌دهد.

DIJKSTRA(G, w, s):
  INITIALIZE-SINGLE-SOURCE(G, s)
  S = مجموعه خالی          // رأس‌هایی که فاصله نهایی‌شان تعیین شده
  Q = صف اولویت حاوی همه رأس‌ها، کلیددهی‌شده با .d
  تا زمانی که Q خالی نباشد:
      u = EXTRACT-MIN(Q)
      S = S ∪ {u}
      برای هر v در Adj[u]:
          RELAX(u, v, w)  // این ممکن است DECREASE-KEY را روی v در Q اعمال کند

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

چرا وزن‌های غیرمنفی برای درستی ضروری‌اند

درستی دیجکسترا به یک ادعای حریصانه متکی است: وقتی یک رأس از صف اولویت استخراج شود (به S اضافه شود)، مقدار فاصله‌اش تضمین می‌شود کوتاه‌ترین فاصله واقعی‌اش باشد و هرگز نیاز به به‌روزرسانی دوباره نخواهد داشت. این ادعا به‌طور حیاتی به وزن‌های غیرمنفی بستگی دارد: اگر یک یال منفی وجود داشت، یک مسیر از میان یک رأس هنوز-نه-در S می‌توانست بالقوه همچنان یک مسیر کوتاه‌تر به یک رأس از‌قبل-نهایی‌شده تولید کند، که فرض حریصانه را کاملاً نقض می‌کند. این دقیقاً چرایی این است که الگوریتم دیجکسترا نتایج نادرست تولید می‌کند اگر وزن‌های یال منفی به آن داده شود، بدون هیچ هشداری که چیزی اشتباه رفته است.

تحلیل زمان اجرا

با استفاده از یک هیپ دودویی برای صف اولویت:
V فراخوانی EXTRACT-MIN، هرکدام هزینه O(log V)
E فراخوانی DECREASE-KEY (از طریق relaxation)، هرکدام هزینه O(log V)

مجموع: O((V + E) log V)

با استفاده از یک هیپ فیبوناچی (که پیش‌تر در این مجموعه
درباره درخت‌های پوشای کمینه ذکر شد):
DECREASE-KEY هزینه O(1) مستهلک به‌جای O(log V) دارد

مجموع: O(V log V + E)

نوع هیپ فیبوناچی از نظر مجانبی برای گراف‌های چگال سریع‌تر است، هرچند نسخه هیپ دودویی برای پیاده‌سازی ساده‌تر است و اغلب در عمل به‌دلیل فاکتورهای ثابت کوچک‌تر سریع‌تر است.

مقایسه دو الگوریتم

بلمن-فورد:
  - وزن‌های یال منفی را به‌درستی مدیریت می‌کند
  - چرخه‌های وزن-منفی را تشخیص می‌دهد
  - زمان اجرا: O(VE) — کندتر

الگوریتم دیجکسترا:
  - نیازمند همه وزن‌های یال غیرمنفی است
  - نمی‌تواند چرخه‌های منفی را تشخیص یا مدیریت کند
  - زمان اجرا: O((V+E) log V) یا O(V log V + E) — سریع‌تر

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

چرا کوتاه‌ترین مسیرهای منبع واحد در بسیاری حوزه‌ها اهمیت دارند

این الگوریتم‌ها زیربنای سیستم‌های ناوبری GPS که مسیرهای رانندگی را محاسبه می‌کنند، پروتکل‌های مسیریابی شبکه که تعیین می‌کنند بسته‌های داده چگونه در سراسر اینترنت سفر می‌کنند، و بی‌شمار

نوشته و پژوهش‌شده توسط دکتر شاهین صیامی

مقالات مرتبط

الگوریتم‌های نظریه اعداد: GCD، توان‌رسانی پیمانه‌ای، و RSA

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

ادامه

اصول هندسه محاسباتی: جهت، تقاطع پاره‌خط، و پوسته محدب

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

ادامه

الگوریتم‌های تطبیق رشته: جستجوی ساده، Rabin-Karp، و فراتر از آن

جستجو برای یک الگو درون یک متن بزرگ‌تر یکی از رایج‌ترین عملیات‌ها در محاسبات است، از ویرایشگرهای متن تا تحلیل توالی DNA. این راهنمای جامع الگوریتم تطبیق رشته ساده و بدترین‌حالت درجه‌دومش را پوشش می‌دهد، سپس استفاده ماهرانه الگوریتم Rabin-Karp از هشینگ برای دستیابی به کارایی سریع حالت‌میانگین را توضیح می‌دهد، شامل نحوه مدیریت درست برخوردهای هش.

ادامه

الگوریتم‌های تقریبی: نزدیک‌شدن اثبات‌پذیر به بهینه برای مسائل سخت

وقتی یک مسئله NP-complete اثبات شود، یک راه‌حل کارآمد دقیق بعید است وجود داشته باشد، اما این به معنای رهاکردن کامل مسئله نیست. این راهنمای جامع الگوریتم‌های تقریبی را توضیح می‌دهد، که تضمین بهینه‌بودن را در ازای تضمین کارایی معامله می‌کنند، و مسائل پوشش رأس و فروشنده دوره‌گرد را به‌عنوان مثال‌های کلاسیک با نسبت‌های تقریبی اثبات‌پذیر پوشش می‌دهد.

ادامه

NP-Completeness توضیح داده شده: P، NP، و چرا برخی مسائل در برابر راه‌حل‌های کارآمد مقاومت می‌کنند

برخی مسائل برای دهه‌ها در برابر هر تلاشی برای یک الگوریتم کارآمد مقاومت کرده‌اند، با این حال هیچ‌کس اثبات نکرده یک راه‌حل کارآمد غیرممکن است. این راهنمای جامع کلاس‌های P و NP، مفهوم تقلیل‌های زمان-چندجمله‌ای مورد استفاده برای مقایسه سختی مسئله، و چگونگی اینکه اثبات NP-complete بودن یک مسئله شواهد قوی، هرچند نه اثبات، فراهم می‌کند که هیچ الگوریتم کارآمدی وجود ندارد را توضیح می‌دهد.

ادامه

جریان بیشینه: فورد-فالکرسون و قضیه برش-کمینه/جریان-بیشینه

مسائل جریان بیشینه بیشترین توان عملیاتی ممکن از میان یک شبکه با اتصالات محدود-به-ظرفیت را مدل‌سازی می‌کنند، از لوله‌های آب تا شبکه‌های داده. این راهنمای جامع شبکه‌های جریان را معرفی می‌کند، روش فورد-فالکرسون برای یافتن جریان بیشینه با استفاده از مسیرهای تقویتی را مرور می‌کند، و قضیه ظریف برش-کمینه/جریان-بیشینه که دو مسئله به‌ظاهر متفاوت را به یکی متصل می‌کند را توضیح می‌دهد.

ادامه