الگوریتم فلوید–وارشال
کوتاهترین مسیر بین همهی جفت گرهها با برنامهریزی پویا: گرهها یکییکی بهعنوان ایستگاه میانی مجاز میشوند.
میخواهیم کوتاهترین فاصلهی همهی جفتها را داشته باشیم. Floyd–Warshall یک برنامهریزی پویای ساده است:
ادامهی توضیح ↓- زمان:
O(V³) - حافظه:
O(V²) - CLRS، بخش ۲۳.۲
- هوروویتز–ساهنی، فصل ۵
پنج گره با دو یال منفی و بدون دور منفی؛ اعداد کنار گرهها فاصله از گرهی ۱ هستند.
INF = float("inf")def floyd_warshall(graph, src):dist = {u: {v: INF for v in graph} for u in graph}for u in graph:dist[u][u] = 0for v, w in graph[u]:dist[u][v] = min(dist[u][v], w)from_src = dist[src]for k in graph:row_k = dist[k]for i in graph:if dist[i][k] == INF:continuefor j in graph:if dist[i][k] + row_k[j] < dist[i][j]:dist[i][j] = dist[i][k] + row_k[j]for v in graph:if dist[v][v] < 0:return Nonereturn dist
شروع اجرا
- گرهی جاری
(k) - درخت کوتاهترین مسیر تا اینجا
- یالِ در حال بررسی
متغیرهای محلی
src'1'
نارنجی = در همین گام عوض شد
graph dict
- '1': [('2', 3), ('3', 8), ('5', -4)]
- '2': [('4', 1), ('5', 7)]
- '3': [('2', 4)]
- '4': [('1', 2), ('3', -5)]
- '5': [('4', 6)]
Call stack
- floyd_warshall()خط 4
گام ۱ از ۳۴۸
رشد تعداد عملیات با اندازهی ورودی
میانگین ۵ گراف تصادفی برای هر n (با seed ثابت). نشانگر توخالی = ورودی فعلی.
- comparisons
- ورودی فعلی (n=5)
نمایش به شکل جدول
| n | comparisons |
|---|---|
| 4 | 39.2 |
| 8 | 244.8 |
| 12 | 583.2 |
توضیح
ایده
میخواهیم کوتاهترین فاصلهی همهی جفتها را داشته باشیم. Floyd–Warshall یک برنامهریزی پویای ساده است:
dist[i][j] در دور k = کوتاهترین مسیر از i به j که ایستگاههای میانیاش فقط از گرههای اول تا k باشند.
در دور k برای هر جفت میپرسیم: آیا رفتن از راه k بهتر است؟
dist[i][j] = min(dist[i][j], dist[i][k] + dist[k][j])
نکتهها
- با یال منفی کار میکند. اگر در پایان
dist[v][v] < 0شود،vروی یک دور منفی است. - سه حلقهی تودرتو:
O(V³)؛ کد بسیار کوتاه است و برای گرافهای کوچک و پر از یال مناسب است. kباید بیرونیترین حلقه باشد؛ اگر جای حلقهها عوض شود، جواب غلط میشود.
در trace به چه چیزی نگاه کنی
- عدد کنار هر گره فاصله از گرهی اول است (یک ردیف ماتریس)؛ کل ماتریس
distدر پنل حافظه است. - گرهی برجسته
kاست، یعنی ایستگاه میانی این دور.