差分約束系統
x1 - x2 <= 0
x1 - x5 <= -1
x2 - x5 <= 1
x3 - x1 <= 5
x4 - x1 <= 4
x4 - x3 <= -1
x5 - x3 <= -3
x5 - x4 <= -3
不等式組(1)
全都是兩個未知數的差小於等於某個常數(大於等於也可以,因為左右乘以-1就可以化成小於等於)。這樣的不等式組就稱作差分約束系統。
這個不等式組要麼無解,要麼就有無陣列解。因為如果有一組解的話,那麼對於任何乙個常數k,肯定也是一組解,因為任何兩個數同時加乙個數之後,它們的差是不變的,那麼這個差分約束系統中的所有不等式都不會被破壞。
差分約束系統的解法利用到了單源最短路徑問題中的三角形不等式。即對於任何一條邊u -> v,都有:
d(v) <= d(u) + w(u, v)
其中d(u)和d(v)是從源點分別到點u和點v的最短路徑的權值,w(u, v)是邊u -> v的權值。
顯然以上不等式就是d(v) - d(u) <= w(u, v)。這個形式正好和差分約束系統中的不等式形式相同。於是我們就可以把乙個差分約束系統轉化成一張圖,每個未知數xi對應圖中的乙個頂點vi,把所有不等式都化成圖中的一條邊。對於不等式xi - xj <= c,把它化成三角形不等式:xi <= xj + c,就可以化成邊vj -> vi,權值為c。最後,我們在這張圖上求一次單源最短路徑,這些三角形不等式就會全部都滿足了,因為它是最短路徑問題的基本性質嘛。
話說回來,所謂單源最短路徑,當然要有乙個源點,然後再求這個源點到其他所有點的最短路徑。那麼源點在哪呢?我們不妨自已造乙個。以上面的不等式組為例,我們就再新加乙個未知數x0。然後對原來的每個未知數都對x0隨便加乙個不等式(這個不等式當然也要和其它不等式形式相同,即兩個未知數的差小於等於某個常數)。我們索性就全都寫成xn - x0 <= 0,於是這個差分約束系統中就多出了下列不等式:
x1 - x0 <= 0
x2 - x0 <= 0
x3 - x0 <= 0
x4 - x0 <= 0
x5 - x0 <= 0
不等式組(2)
對於這5個不等式,也在圖中建出相應的邊。最後形成的圖如下:
圖1
圖中的每一條邊都代表差分約束系統中的乙個不等式。現在以v0為源點,求單源最短路徑。最終得到的v0到vn的最短路徑長度就是xn的乙個解啦。從圖1中可以看到,這組解是。當然把每個數都加上10也是一組解:。但是這組解只滿足不等式組(1),也就是原先的差分約束系統;而不滿足不等式組(2),也就是我們後來加上去的那些不等式。當然這是無關緊要的,因為x0本來就是個局外人,是我們後來加上去的,滿不滿足與x0有關的不等式我們並不在乎。
也有可能出現無解的情況,也就是從源點到某乙個頂點不存在最短路徑。也說是圖中存在負權的圈。這一點我就不展開了,請自已參看最短路徑問題的一些基本定理。
其實,對於圖1來說,它代表的一組解其實是,也就是說x0的值也在這組解當中。但是x0的值是無可爭議的,既然是以它作為源點求的最短路徑,那麼源點到它的最短路徑長度當然是0了。因此,實際上我們解的這個差分約束系統無形中又存在乙個條件:
x0 = 0
也就是說在不等式組(1)、(2)組成的差分約束系統的前提下,再把其中的乙個未知數的值定死。這樣的情況在實際問題中是很常見的。比如乙個問題表面上給出了一些不等式,但還隱藏著一些不等式,比如所有未知數都大於等於0或者都不能超過某個上限之類的。比如上面的不等式組(2)就規定了所有未知數都小於等於0。
對於這種有乙個未知數定死的差分約束系統,還有乙個有趣的性質,那就是通過最短路徑演算法求出來的一組解當中,所有未知數都達到最大值。下面我來粗略地證明一下,這個證明過程要結合bellman-ford演算法的過程來說明。
假設x0是定死的;x1到xn在滿足所有約束的情況下可以取到的最大值分別為m1、m2、……、mn(當然我們不知道它們的值是多少);解出的源點到每個點的最短路徑長度為d1、d2、……、dn。
基本的bellman-ford演算法是一開始初始化d1到dn都是無窮大。然後檢查所有的邊對應的三角形不等式,一但發現有不滿足三角形不等式的情況,則更新對應的d值。最後求出來的d1到dn就是源點到每個點的最短路徑長度。
如果我們一開始初始化d1、d2、……、dn的值分別為m1、m2、……、mn,則由於它們全都滿足三角形不等式(我們剛才已經假設m1到mn是一組合法的解),則bellman-ford演算法不會再更新任合d值,則最後得出的解就是m1、m2、……、mn。
好了,現在知道了,初始值無窮大時,算出來的是d1、d2、……、dn;初始值比較小的時候算出來的則是m1、m2、……、mn。大家用的是同樣的演算法,同樣的計算過程,總不可能初始值大的算出來的結果反而小吧。所以d1、d2、……、dn就是m1、m2、……、mn。
那麼如果在乙個未知數定死的情況下,要求其它所有未知數的最小值怎麼辦?只要反過來求最長路徑就可以了。最長路徑中的三角不等式與最短路徑中相反:
d(v) >= d(u) + w(u, v)
也就是d(v) - d(u) >= w(u, v)
所以建圖的時候要先把所有不等式化成大於等於號的。其它各種過程,包括證明為什麼解出的是最小值的證法,都完全類似。
最近幾天系統得學習了一些差分約束系統的原理,特此記錄如下:
所謂差分約束系統,是指一組不定方程(a,x,t,b),其中a的每行有乙個1,乙個-1,其餘為0,x為解向量,t為<=或》=組成的向量,b為約束向量。具體來說,就是每行都具有 xi-xj >=|<= bi 的形式。約束的目標是使得目標函式xt-xs最大或最小。
這是典型的線性規劃的個案,但是也可以轉化為圖論來做,利用最短路(或最長路)方法可以實現高效的解決方案。
下面通過poj上的部分例題來詳細解釋如下:
poj3159 candies
這是我接觸差分約束的第一題。設s[a]為kid a獲得的candies數,則每一行代表的約束是s[b]-s[a]<=c,目標函式是使得s=s[n]-s[1]最大。
利用差分約束的思想建圖,對於每一條約束,從a向b做一條長為c的邊,則從1到n的最短路即為所求。由於本題c皆為非負數,所以可以用dijkstra高效解決。
核心**(構圖):
void input()
}poj1364 king
注意到本題的約束是》和
xb -》 x>=b+1
然而需要注意的是,差分約束必須保證所有的不等式具有同樣的不等號才能正確執行!所以我們把所有符號轉為<=,然後構圖,做bellman_ford。
核心**(構圖):
bool input()
else }
return 1;
}poj1716 integer intervals
poj1201 intervals
後者是前者的進化版,所以我們以後者為例。
令s[i]為從0到i-1中數的個數,則以下為約束條件:
s[bi]-s[ai]>=ci
1>=s[i+1]-s[i]>=0
注意本題要求的是最小值,而按照》=號建圖後發現圖中有負環,怎麼辦呢?
其實很簡單,本題求的不是最短路,而是最長路!而bellman_ford依然可以承擔此項重任!
核心**(構圖):
void input()
for (i=st;i
px[m]=i;
py[m]=i+1;
pl[m]=0;
++m;
}for (i=ed;i>st;--i)
for (i=st;i<=ed;++i)
dps[i]=maxs;
dps[ed]=0;
}poj3169 layout
本題是求約束下的最大值,只要依<=建圖並求最短路即可!
核心**(構圖):
void input()
for (i=0;i
scanf("%d %d %d",&xx,&yy,&ll);
--xx;
--yy;
px[m]=yy;
py[m]=xx;
pl[m]=-ll;
++m;
}for (i=1;i
px[m]=i;
py[m]=i-1;
pl[m]=0;
++m;}}
poj1275 cashier employment
這是我很久以前就從黑書上見到的題目,但是因為當時自己才疏學淺,怎麼都寫不出來。現在搞懂了差分約束,發現其實不是那麼難的!
利用差分約束尋找可行解,在所有可行解中二分最優。
核心**(構圖):
void createmap(int sum)
for (i=1;i<25;++i)
px[m]=0;
py[m]=24;
pl[m]=sum;
++m;
for (j=1;j<25;++j)
}總論:
感謝各位大牛小牛們能耐心看到這裡,在此我準備用一些簡單的語句來總結差分約束系統的應用特性:
>=,求最小值,做最長路;
<=,求最大值,做最短路。
邊都是從後往前~~~
<=構圖。
有負環說明無解。
求不出最短路(為inf)為任意解。
>=構圖時類似。
以上為我的一點短見,希望各位大牛不吝批評指正!!!
差分約束系統
差分約束 若 s a s b k 建一條b到a 的長度為k的邊 若s a s b k 建一條b到a 的長度為 k的邊 是求最小值的最長路 是求最大值的最短路 注意到最短路演算法的鬆弛操作 if d j d i w i j d j d i w i j 這其中的三角形不等式 d j d i w i j ...
差分約束系統
差分約束系統 對於差分不等式,a b c 建一條 b 到 a 的權值為 c 的邊,求的是最短路,得到的是最大值 對於不等式 a b c 建一條 b 到 a 的權值為 c 的邊,求的是最長路,得到的是最小值 存在負環的話是無解 求不出最短路 dist 沒有得到更新 的話是任意解 第三 一種建圖方法 設...
差分約束系統
在乙個差分約束系統 system of difference constraints 中,線性規劃矩陣a的每一行包含乙個1和乙個 1,a的其他所有元素都為0。因此,由ax b給出的約束條件是m個差分約束集合,其中包含n個未知量,對應的線性規劃矩陣a為m行n列。每個約束條件為如下形式的簡單線性不等式 ...