演算法
Input:
Output:
d[t] = 0; d[x] = INF, for x != t; // 陣列d[x]儲存節點x到節點t的最小距離
for i = k-1 to 1 do // 由第k-1階到第1階
for every node x in P_i do
for every edge (x, y) in E do
if (d[x] > w[x,y] + d[y]) do
d[x] = w[x,y] + d[y]
next[x] = y // 代表在最短路徑中節點x的下節點為y
path[1] = s; path[k] = t; // path[j]表示路徑中第j階的節點
for j = 2 to k-1 do
path[j] = next[path[j-1]];
return path[s], d[s]
Input:
Output:
MATRIX_CHAIN_ORDER(p)
n = length[p]–1 // 矩陣數
for i = 1 to n
m[i,i] = 0
for l = 2 to n // level 2 to n
for i = 1 to n–l+1
j = i+l–1
m[i,j] = INF
for k = i to j–1
q = m[i,k] + m[k+1,j] + p[i-1]*p[k]*p[j]
if q < m[i,j]
m[i,j] = q
s[i,j] = k
return m[1,n], s
Example:
p = [30, 35, 15, 5, 10, 20, 25]
PRINT_OPTIMAL_PARENS(s, i, j)
if i == j
print "A_i"
else
print "("
PRINT_OPTIMAL_PARENS(s, i, s[i,j])
PRINT_OPTIMAL_PARENS(s, s[i,j]+1, j)
print ")"
// 邊界條件
for i = 0 to m
c[i,0] = i * Cost1
for j = 0 to n
c[0,j] = j * Cost2
// 遞迴關係
if a_i == b_j
c[i,j] = c[i-1,j-1]
else
c[i,j] = min(c[i-1,j] + Cost1,
c[i,j-1] + Cost2,
c[i-1,j-1]+ Cost3 )
// 答案
return c[m,n]
Input:
Output:
OPTIMAL_BST(p,q,n)
for i = 1 to n+1
e[i,i–1] = q[i-1]
w[i,i–1] = q[i-1]
for l = 1 to n // level 1 to n
for i = 1 to n–l+1
j = i+l–1
e[i, j] = INF
w[i, j] = w[i, j–1] + p[j] + q[j] // 第i~j項機率總和
for r = i to j
t = e[i,r–1] + e[r+1,j] + w[i,j]
if t < e[i,j]
e[i,j] = t
root[i,j] = r
return e[1,n], root
Example:
p = [0.15, 0.10, 0.05, 0.10, 0.20]
q = [0.05, 0.10, 0.05, 0.05, 0.05, 0.10]
設定起始節點p為解答空間樹的root,並建立一個只包含p的queue。
檢查queue的第一個元素是否為目標節點。若是,則輸出目標節點所對應的解答並停止。
移除queue的第一個節點,將其未被拜訪過的子節點一一加入queue。
若queue為空,則回報無解答並停止。否則,跳至步驟2。
設定起始節點p為解答空間樹的root,並建立一個只包含p的stack。
檢查stack的頂端元素是否為目標節點。若是,則輸出目標節點所對應的解答並停止。
移除stack的頂端節點。將其未被拜訪過的子節點一一加入stack。
若stack為空,則回報無解答並停止。否則,跳至步驟2。
設定起始節點p為解答空間樹的root,並建立一個只包含p的stack。
檢查stack的頂端元素是否為目標節點。若是,則輸出目標節點所對應的解答並停止。
移除stack的頂端節點。將其未被拜訪過的子節點[由評估函數所算的優先度低的先加入]stack。
若stack為空,則回報無解答並停止。否則,跳至步驟2。
設定起始節點p為解答空間樹的root,並建立一個只包含p的heap。
檢查heap中優先度最高的元素是否為目標節點。若是,則輸出目標節點所對應的解答並停止。
移除heap優先度最高的節點。將其未被拜訪過的子節點[由評估函數所算的優先度]加入heap中。
若heap為空,則回報無解答並停止。否則,跳至步驟2。
PutQueen(i,n) // 以放有i個皇后,總共要放n個皇后
j = 0 // j代表行(column)編號, j = 0 to n-1
while j < n
if i列j行可放置皇后棋子
q[i] = j // 編號為i的皇后放在第i列第j行上
if i == n-1 // n個皇后棋子均已放置妥當
return q
else
PutQueen(i+1,n)
j++
return Failure
圖解,讓你看看什麼是回朔ㄏㄏ,根本就只是stack退回去啊= =
FORD_FULKERSON(G,s,t)
for each edge (u,v) in E of G
f[u,v] = 0
f[v,u] = 0
while there exists a path p from s to t in the residual network G_f
c_f(p) = min(c_f[u,v]: (u,v) in p) // 流量最小邊的值
for each edge (u,v) in p
f[u,v] = f[u,v] + c_f(p)
f[v,u] = f[v,u] - c_f(p)
c[u,v] = c[u,v] - c_f(p)
c[v,u] = c[v,u] + c_f(p)
Ford-Fulkerson演算法 圖解
Edmons-Karp演算法
= Ford-Fulkerson演算法 + BFS
多起點終點 => 單起點&終點
Min_Cost_Max_Flow(G)
先不看成本參數找出最大流f
加入成本參數計算f的成本c
while true
計算G_f
用Bellman-Ford在G_f上找負成本循環
if 無負成本循環
return f, c
else
在循環中環繞以減低總成本直到循環中的一個邊的容量用盡為止
解 最大權重完美二分匹配
二分匹配(Bipartite Matching)
用匈牙利演算法解決最大化問題,先將各個元素換成以最大元素減去其本身。
接著套用標準的匈牙利演算法:
藉由列的減法變轉陣列:每一列皆減去該列中的最小元素。
計算覆蓋元素0的最少直線數。如果直線數與陣列的大小相同,跳到步驟6。
藉由行的減法變轉陣列:每一行皆減去該行中的最小元素。
計算覆蓋元素0的最少直線數。如果直線數與陣列的大小相同,跳到步驟6。
找出未被覆蓋的元素中最小者,將所有未覆蓋元素中減去此元素值,並增加這個元素值到被兩條直線覆蓋的元素中,回到步驟4。
只從元素0去找出極大二分配對,並套用此配對到原始陣列中以找出最小成本。
Success
:演算法成功結束Failure
:演算法不成功結束Choice(S)
:從集合S裡任意地選出一個元素,Choice(S)
是一個非確定性敘述,但它一定會挑中一個可以讓演算法成功結束的元素(除非這種元素不存在)。