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

الگوریتم بلمن-فورد الگوریتم پیمایش گراف است که مسئله کوتاهترین مسیر از مبدا واحد را برای گراف‌های وزن‌داری که وزن یال‌ها ممکن است منفی باشد حل می‌کند.
الگوریتم دیکسترا مسئله مشابهی را در زمان اجرای کمتر حل می‌کند، اما در آن الگوریتم می‌بایست وزن یال‌ها اعداد نامنفی باشند. بنابراین در عمل الگوریتم بلمن-فورد فقط برای گراف‌هایی که یال با وزن منفی دارند استفاده می‌شود.
قبل از توضیح الگوریتم لازم به ذکر است که اگر گراف دوری با مجموع وزن منفی داشته باشد که از مبدا قابل دست‌یابی باشد، مسئله کوتاهترین مسیر جوابی نخواهد داشت، چراکه با پیمایش آن دور به هر تعداد بار دلخواه، مسیرهایی با وزن کمتر و کمتر حاصل خواهد شد.
چگونه کار می‌کند؟
ساختار اصلی الگوریتم بلمن-فورد مشابه الگوریتم دایکسترا است. اجرای الگوریتم 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 امین تکرار پیدا خواهد شد.
توجه کنید که در چنین درختی که مسیر شامل حلقه نداریم، حداکثر طول مسیر برابر با است. لذا الگوریتم مورد نظر بعد از اتمام جواب بهینه را بدست خواهد داد.
پیچیدگی زمانی
مشخص است که در مرحله، در هر مرحله عملیات بر روی یال‌ها انجام می‌شود. پس پیچیدگی زمانی الگوریتم بلمن-فورد خواهد بود.
کاربردها
مسیریابی (Routing)