الگوریتم فلوید-وارشال

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

در علوم کامپیوتر الگوریتم فلوید-وارشال (به انگلیسی: Floyd–Warshall algorithm) یک الگوریتم تحلیل گراف برای پیدا کردن کوتاهترین مسیر در یک گراف جهت دار و وزن دار می‌باشد. با یکبار اجرای این الگوریتم کوتاه‌ترین مسیر بین همهٔ جفت راس‌ها پیدا خواهد شد. الگوریتم فلوید-وارشال به نام استفن وارشال[۱] و روبرت فلوید[۲] نامگذاری شده‌است. این الگوریتم یک مثال از برنامه‌نویسی پویا می‌باشد. در این الگوریتم، ابتدا ماتریس مجاورت برای نقاط گراف نوشته شده و در مرحلهٔ بعد با استفاده از یک راس واسطه، کوتاه‌ترین فاصله بین نقاط را محاسبه کرده و ماتریس را با مقادیر جدید بازنویسی می‌کند. پس از آن دو نقطه به عنوان واسطه انتخاب شده و ماتریس جدید به دست می‌آید. با تکرار این روند الگوریتم به پایان رسیده و در نهایت ماتریسی ایجاد شده که کوتاه‌ترین مسیر بین تمامی نقاط را محاسبه کرده‌است. بدیهی است که کوتاه‌ترین مسیر بین مبدأ و مقصد را می‌توان به راحتی از ماتریس تشکیل شده استخراج نمود.

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

الگوریتم وارشال همهٔ مسیرهای ممکن در یک گراف، بین هر جفت از راس هارا مقایسه می‌کند. این الگوریتم قادر است این کار را تنها با مقایسه انجام دهد. این ملاحظه قابل توجهی می‌باشد که در یک گراف یال وجود داشته باشد وهر ترکیبی از یالها چک شده باشد. یک گراف با راس‌های که i از ۱ تا N می‌باشد را در نظر بگیرید. علاوه بر این یک تابع به نام (shortestPath(i,j،k را در نظر بگیرید که کوتاهترین مسیر ممکن از i تا j را با استفاده از راس‌های ۱ تا k که به عنوان راسهای میانی در امتداد مسیر می‌باشند را برمی‌گرداند.

هم اکنون این تابع داده شده‌است. هدف ما پیدا کردن کوتاهترین مسیر از هر i تا هر j تنها با استفاده از راسهای ۱ تا 1+k می‌باشد. دو کاندیدا برای این مسیر وجود دارد:

۱- کوتاهترین مسیری که فقط از راس‌های موجود در مجموعه ی(k,........ ,1) استفاده می‌کند.

۲- تعدادی مسیر که از i تا 1+k و سپس از 1+k تا j می‌روند وجود دارد که این مسیر بهتر می‌باشد.

ما می‌دانیم که بهترین مسیر از i تا j که فقط از راس‌های بین ۱ تا k+1 استفاده می‌کند توسط (ShortestPath(i,j،k تعریف شده‌است و واضح است که اگر یک مسیر بهتر از i تا1+k و از 1+k تا j وجود داشته باشد بنابراین طول مسیر بین i,j از الحاق کوتاهترین مسیر از i تا 1+k و کوتاهترین مسیر از 1+k تا j بدست می‌آید؛ بنابراین تابع (ShortestPath(i,j،k را در در فرمول بازگشتی زیر ارائه می‌دهیم:

این رابطه قلب الگوریتم وارشال می‌باشد این الگوریتم در اولین محاسبه (ShortestPath(i,j،۱ را برای همهٔ جفت‌های (i ,j) پیدا می‌کند و سپس از این برای پیدا کردن (Shortestpath(i,j،۲ برای همهٔ جفت‌های (i ,j) استفاده می‌شود و این روال تا زمانی که k=N شود ادامه می‌یابد و ما می‌توانیم کوتاهترین مسیر بین جفت‌های (i,j) رابا استفاده از راس‌های میانی پیدا کنیم.

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

Algorithm : Floyd – Warshal

Input : weighted graph G(V,E)

Output : w[u][v] // representing minimum path from u to v

begin :

  1. for all vertices such as u and v do :
  2. if u and v are adjacent then
  3. w[u][ v] = E(u, v) weight
  4. else
  5. w[u][ v]= ∞
  6. for k = 1 to n do:
  7. for all vertices such as u do
  8. for all vertices such as v do
  9. if w[u][ v] > w[u][ k] + w[k][ v] then
  10. w[u][ v]= w[u][ k]+w[k][ v]

end

تحلیل[ویرایش]

برای پیدا کردن همه تا (یک است اگر بین i,j راسی بزرگتر از k نباشد در غیر این صورت صفر می‌باشد) از به بیت عملیات نیاز داریم. برای اینکه ما با شروع می‌کنیم و n ماتریس صفر و یک

، ، ،

را محاسبه می‌کنیم. در نتیجه جمع بیت عملیات‌هایی که استفاده کردیم برابر با می‌باشد؛ بنابراین پیچیدگی الگوریتم از (Θ(n^3 باشد.

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

الگوریتم وارشال برای حل مسایل زیر می‌تواند استفاده شود.

  1. کوتاهترین مسیرها در گراف‌های جهت دار
  2. بستار متعدی گراف‌های جهت دار
  3. در فرمول عمومی الگوریتم وارشال گراف بی وزن می‌باشد و توسط یک ماتریس مجاورت نمایش داده شده‌است.
  4. وارون سازی یک ماتریس حقیقی
  5. تست کردن اینکه آیا یک گراف بی جهت، دو قسمتی می‌باشد یا خیر.
  6. محاسبه سریع شبکه‌های راه‌یاب

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

پیاده‌سازی این الگوریتم در زبان‌های برنامه‌نویسی مختلفی وجود دارد.

  1. برای پرل در کتابخانه Graph
  2. برای جاوااسکریپت در کتابخانه Cytoscape
  3. برای سی پلاس‌پلاس در کتابخانه boost::graph
  4. برای سی شارپ در کتابخانه QuickGraph
  5. برای جاوا در کتابخانه Apache Commons Graph

۶- برای متلب در بسته Matlab_bgl

۷- برای پایتون در کتابخانه SciPy یا کتابخانه NetworkX

۸- برای R در کتابخانه e1071

پانویس[ویرایش]

  1. Stephen Warshall
  2. Robert Floyd

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