الگوریتم یافتن کوتاه‌ترین مسیر سریع‌تر

**الگوریتم یافتن کوتاهترین مسیر سریع تر (SPFA)** را می‌توان روشی برای بهبود الگوریتم بلمن-فورد معرفی کرد که با استفاده از آن کوتاهترین مسیر تک منبع در یک گراف وزندار و جهت‌دار بدست می‌آید. تحقیقات قبلی بر این باورند که این الگوریتم به خوبی روی گراف خلوت تصادفی کار می‌کند یا به صورت دقیقتر، برای گراف‌هایی که یال‌های وزن-منفی دارند پرکاربرد است. با این حال، بدترین حالت پیچیدگی در SPFA همانند الگوریتم بلمن-فورد دارای نقص است که برای جبران الگوریتم Dijkstra برای گراف‌های با وزن لبه‌های غیر منفی ترجیح داده می‌شود. الگوریتم SPFA برای اولین بار توسط ادوارد اف مور در سال ۱۹۵۹ معرفی شد و به چاپ رسید که خود باعث کلیت بخشیدن به الگوریتم جستجوی اول سطح شد. مشابه همان الگوریتم در سال ۱۹۹۴ توسط فندینگ دوان کشف شد.

## الگوریتم
در حالت کلی و در یک گراف وزن دار و جهت دار G=(V,E) با رأس s به عنوان منبع، الگوریتم SPFA کوتاه‌ترین مسیر را از رأس sبه هر رأس دیگر موجود در گراف vپیدا می‌کند. برای هر رأس گراف طول کوتاه‌ترین مسیر از  s به vدر d(v)ذخیره می‌شود. ایده اصلی SPFA در واقع همانند الگوریتم بلمن-فورد است که به عنوان یک راه حل برای حداقل کردن فاصله هر رأس از منبع استفاده می‌شود. بهبودی که SPFA نسبت به سایر روش‌ها ارائه می‌دهد باعث شده‌است که به جای امتحان کردن تصادفی تمام رأس‌ها، در SPFA تمامی رأس‌های با حداقل فاصله نسبت به منبع با روشی منظم و سریع یافته شوند.

در زیر شبه کد از الگوریتم SPFA نشان داده شده‌است. ادر این الگوریتم Q سری اول رأس‌های داوطلب ورودی، و w(u,v)وزن یال (u,v)است.
بندانگشتی| مثال تصویری از SPFA برای درک عمیق‌تر بر اساس فاصله اقلیدسی که در آن خطوط قرمز کوتاه‌ترین مسیر را مشخص می‌کند. خطوط آبی نشان می‌دهد که در آن شرط کوتاه‌ترین مسیر صادق است: یعنی اتصال <math>v</math>به <math>u</math> با یک گره مسیری کوتاه‌تر از فاصله بین <math>v</math> تا منبع را فراهم می‌کند .

  **procedure** Shortest-Path-Faster-Algorithm(*G*, *s*)
   1    **for** each vertex *v* ≠ *s* in *V*(*G*)
   2        d(*v*) := ∞
   3    d(*s*) := 0
   4    push *s* into *Q*
   5    **while** *Q* is not empty **do**
   6        *u* := poll *Q*
   7        **for each** edge (*u*, *v*) in *E*(*G*) **do**
   8            **if** d(*u*) + w(*u*, *v*) 
الگوریتم همچنین می‌تواند برای یک گراف بدون جهت به کار گرفته شود که در این حالت هر یک از یال‌های بدون جهت با دو یال جهت‌دار با جهت‌های معکوس جایگزین می‌شود.

## مدت اجرا
در بدترین حالت یا غیربهینه‌ترین زمان اجرا، الگوریتم عملکردی مشابه الگوریتم استاندارد بلمن-فورد ارائه می‌دهد.

## روش‌های بهینه‌سازی
عملکرد الگوریتم به شدت وابسته به ترتیبی است که رأس‌های داوطلب ورودی توسط نظم تعیین می‌شود که در آن رأی‌های داوطلب برای استراحت دیگر رأس‌ها استفاده می‌شود. در واقع، اگر Qیک صف اولویت دار باشد، سپس الگوریتم بسیار مشابه Dijkstra است. با این حال، از آنجا که صف اولویت دار در اینجا استفاده نمی‌شود، دو روش دیگر را می‌توان برای بهبود کیفیت صف بکار برد که به نوبه خود عملکرد را در حالت کلی بهبود می‌دهد (اما نه عملکرد بدترین حالت عملکرد را). هر دو روش نظم و ترتیب المان‌های حاضر در  Q به نحوی تغییر می‌دهد که رأس‌های نزدیک به منبع ابتدا پردازش می‌شوند؛ بنابراین، هنگام اجرای این تکنیک‌ها Q با یک لیست نرمال دو طرفه یا یک صف دوطرفه است و سیاست FIFO (خروج به ترتیب ورود) در مورد آن صادق نیست.

**اولین برچسب کوچک (** **SLF)** (اولین بار توسط Dimitri Bertsekas مطرح شد، Vol 23، ۱۹۹۳، pp. 703-709). تغییری که این روش در الگوریتم ایجاد می‌کند را می‌توان با تغییر در خط ۱۱ بیان کرد. در خط ۱۱، به جای تلاش و تأکید بر انتقال همیشگی راس v به پایان صف، از شبه کد ریز برای این تکنیک استفاده می‌شود (پس از انتقال راس v به پایان صف در خط ۱۱):

 **procedure** Small-Label-First(G, Q)
     **if** d(back(Q)) 
**تکنیک بزرگ برچسب (LLL)** (اولین بار توسط Bertsekas, Guerriero و Musmanno مطرح شد). در این روش، بعد از خط ۱۱ صف به روزرسانی شده به طوری که عنصر اول کوچکتر از میانگین بوده و هر عنصر بزرگتر از میانگین به انتهای صف منتقل می‌شود. شبه کد زیر توصیف مناسبی از این تکنیک ارائه می‌دهد:

 **procedure** Large-Label-Last(G, Q)
     x := average of d(v) for all v in Q
     **while** d(front(Q)) > x
         u := pop front of Q
         push u to back of Q


## منابع

رده:الگوریتم‌های گراف