قیدهای تفاضلی
دستگاهی از نامعادلههای x_j − x_i ≤ b را به گرافی تبدیل میکند و با بلمن–فورد حل میکند: فاصلههای کوتاهترین مسیر یک جواباند، و دور منفی یعنی دستگاه جواب ندارد.
دستگاهی از نامعادلهها به شکل x_j − x_i ≤ b داریم (مثلاً در زمانبندی: «کار j حداکثر b واحد بعد از کار i»). میخواهیم مقادیری برای x پیدا کنیم که همه برقرار باشند، یا بفهمیم ممکن نیست.
- زمان:
O(n · m) - حافظه:
O(n + m) - CLRS، بخش ۲۲.۴
هشت قید روی پنج متغیر (مثال CLRS)؛ یک جواب: x = (−۵، −۳، ۰، −۱، −۴).
def difference_constraints(C):# Each row [j, i, b] means x_j - x_i <= b: an edge i -> j of weight b. Vertex 0 is a source with 0-edges to all.n = 0for j, i, b in C:n = max(n, i, j)edges = []for v in range(1, n + 1):edges.append([0, v, 0])for j, i, b in C:edges.append([i, j, b])x = [0] + [float("inf")] * nfor rnd in range(1, n + 1):changed = Falsefor u, v, w in edges:if x[u] + w < x[v]:x[v] = x[u] + wchanged = Trueif not changed:breakfor u, v, w in edges:if x[u] + w < x[v]:return Nonesolution = x[1:]return solution
شروع اجرا
متغیرهای محلی
نارنجی = در همین گام عوض شد
C list
Call stack
- difference_constraints()خط 1
توضیح
مسئله
دستگاهی از نامعادلهها به شکل x_j − x_i ≤ b داریم (مثلاً در زمانبندی: «کار j حداکثر b واحد بعد از کار i»). میخواهیم مقادیری برای x پیدا کنیم که همه برقرار باشند، یا بفهمیم ممکن نیست.
تبدیل به کوتاهترین مسیر
هر قید x_j − x_i ≤ b یک یال i → j با وزن b است؛ این دقیقاً شرط کوتاهترین مسیر است: d(j) ≤ d(i) + w(i, j). یک رأس منبع 0 اضافه میکنیم که با وزن ۰ به همه وصل است. حالا:
- اگر گراف دور منفی ندارد،
x_i = δ(0, i)یک جواب است. - اگر دور منفی دارد، جمع قیدهای روی دور به
0 ≤ عدد منفیمیرسد: جوابی نیست.
بلمن–فورد هر دو را تشخیص میدهد: O(n·m).
نکته
اگر x جواب باشد، x + c هم جواب است؛ این الگوریتم جوابی میدهد که همهی x_i ≤ 0 و جمعشان بیشینه است.
ورودی
هر سطر [j, i, b] یعنی x_j − x_i ≤ b؛ متغیرها از ۱ شمارهگذاری شدهاند.