الگوریتم بلمن–فورد

از ویکی‌پدیا، دانشنامهٔ آزاد
پرش به: ناوبری، جستجو

الگوریتم بلمن-فورد الگوریتم پیمایش گراف است که مسئلهٔ کوتاهترین مسیر از مبدأ واحد را برای گراف‌های وزن‌داری که وزن یال‌ها ممکن است منفی باشد حل می‌کند.

الگوریتم دَیکسترا مسئلهٔ مشابهی را در زمان اجرای کمتر حل می‌کند، اما در آن الگوریتم می‌بایست وزن یال‌ها اعداد نامنفی باشند. بنابراین در عمل الگوریتم بلمن-فورد فقط برای گراف‌هایی که یال با وزن منفی دارند استفاده می‌شود.

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

چگونه کار می‌کند؟[ویرایش]

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

اساس کار الگوریتم آزادسازی (Relaxation) همهٔ یال‌های گراف در هر مرحله‌است. آزادسازی یال به این معناست که اگر آنگاه قرار می‌دهیم . با این اوصاف اگر آزادسازی همهٔ یال‌ها را برای بار |V|ام هم تکرار کنیم و بعد از این مرحله هم دنبالهٔ تغییر کند، آنگاه می‌توان نتیجه گرفت که گراف دور منفی‌ای دارد که از مبدأ قابل دست‌یابی است. بنابراین الگوریتم بلمن-فورد توانایی تشخیص دور منفی را نیز دارد.

الگوریتم[ویرایش]

همانطور که گفته شد الگوریتم بلمن-فورد توانایی تشخیص دور منفی را نیز دارد. بنابر این الگوریتم را به گونه‌ای پیاده‌سازی می‌کنند که در صورت تشخیص دور منفی مثلاً مقدار بولی True برگرداند.

پیاده‌سازی[ویرایش]

یک پیاده‌سازی نوعی به این شرح است:

 1  Algorithm Bellman-Ford(G,s)
 2  Input : G=(V,E), s(the source vertex)
 3  Output : Sequence d and a boolean return value
 4  begin
 5      for all vertices w do
 6           = 
 8       = 0
 9      for i = 1 to |V|-1 do
10          for all edge (u,v) in E do
11              if  then
12                   = 
13      for all edge (u,v) in E do
14          if  then
15              return False
16      return True
17  end

اثبات درستی[ویرایش]

می توان درستی را با استفاده از استقرای ریاضی نشان داد.

لم. بعد از i بار تکرار حلقه:

  • اگر Distance(u) بی نهایت نباشد، برابر است با فاصله ی مسیری از s به u.
  • اگر مسیری از s به u با حداکثر i یال وجود داشته باشد آنگاه Distance(u) حداکثر i یال دارد و طول کوتاه ترین مسیر ازs به u است .

اثبات. ابتدا حالت پایه استقرا را در نظر بگیریم که در آن i=0. در این حالت source.distance = 0 که درست است. به ازای تمامی گره های غیر از مبناu داریم u.distance = infinity که درست است؛ چون که هیچ مسیری از مبنا به این گره ها با طول مسیر صفر وجود ندارد.

ابتدا قسمت اول را اثبات می کنیم. با فرض استقرا فرض کنیم u.distance طول مسیری از مبنا به u باشد. در اینصورت u.distance + uv.weight طول مسیری از مبنا به v است.

برای قسمت دوم، طول کوتاه ترین مسیر از مبنا به u با حداکثر تعداد i یال را در نظر بگیریم. فرض کنیم v گرهی قبل از u در طول این مسیر باشد، در اینصورت کوتاه ترین مسیر به v با تعداد i-1 یال است. بنابه فرض استقرا بعد از i-1 تکرار حلقه، کوتاه ترین مسیر تا v حداکثر به طول همین مسیر است(با i-1 یال). در اینصورت چون در i-امین تکرار حلقه uv.weight + v.distance با u.distance مقایسه می شود حتماً کوتاه ترین مسیر با تعداد i یال در i امین تکرار پیدا خواهد شد.

توجه کنید که در چنین درختی که مسیر شامل حلقه نداریم، حداکثر طول مسیر بابر با |V|-1 است. لذا الگوریتم مورد نظر بعد از اتمام جواب بهینه را بدست خواهد داد.

پیچیدگی زمانی[ویرایش]

مشخص است که در 1-|V| مرحله، در هر مرحله |E| عملیات بر روی یال‌ها انجام می‌شود. پس (|O(|V|×|E پیچیدگی زمانی الگوریتم بلمن-فورد خواهد بود.

کاربردها[ویرایش]

پیوند به بیرون[ویرایش]

منابع[ویرایش]