Transcript Alg2 (Org)
分治演算法
與
刪尋演算法
各個擊破與化整為零
2.1 分治演算法基本概念
2
分治解題策略
分治(divide and conquer)演算法使用分治解題策略解決問
題。分治是很好的解題策略,可以很有效率的解決問題,
又稱為分割再征服策略或各個擊破策略。一般而言,分治
演算法具有三個階段:
分割階段:如果問題規模很小,就直接解決此問題;否
則 , 將 原 本 的 問 題 分 割 (divide) 成 2 個 或 多 個 子 問 題
(subproblem)。
克服階段:用相同的演算法遞迴地(recirsively)解決或克
服(conquer)所有的子問題。
合併階段:合併(merge)所有子問題的解答成為原本問題
的解答。
3
使用分治解題策略的演算法
合併排序演算法
快速排序演算法
缺陷棋盤填滿演算法
二維求秩演算法
二維極大點演算法
最近二維點對演算法
4
2.2 合併排序演算法
5
合併排序演算法
在本單元中,我們介紹使用分治解題策略的合併排序(merge sort) 演
算法。
合併排序演算法由現代電腦之父,內儲程式(stored program)電腦架
構發明之人之一的紐曼博士, 在西元1945 年發明。
約 翰 · 馮 · 紐 曼 ( John von
Neumann,1903年12月28日
-1957年2月8日),出生於
匈牙利的美國籍猶太人數學家,
現代電腦創始人之一。他在電
腦科學、經濟、物理學中的量
子力學及幾乎所有數學領域都
作過重大貢獻。(圖及說明摘
自維基百科)
6
合併排序演算法(續)
假設我們要使用合併排序演算法來將陣列A 中的n
個元素或資料(索引為0,...,n−1) 依照其值以由小
而大的次序排列
分割: 若陣列A 只有一個元素,代表陣列已排序完成;
否則將陣列分割成兩個大小相等的子陣列。
克服: 遞迴地排序兩個子陣列。
合併: 最後合併兩個已完成排序的子陣列,即可完成原
來陣列的排序。
合併排序演算法如Algorithm 6 (MergeSort)所示,
而在此演算法中另外使用到如Algorithm 7所示的
Merge演算法以合併二個子陣列。
7
合併排序演算法(續)
8
合併排序演算法(續)
9
合併排序演算法(續)
我們以下頁圖中的實例來看合併排序演算法的運
作過程:
假設有一個陣列具有8 個元素85、24、63、50、
17、31、96、50’,索引(index) 為0,...,7,其中
50 與50’二個元素的值都是50,但是為了區別起
見,我們將之標示為50 與50’。
10
合併排序演算法(續)
11
合併排序演算法(續)
在整個合併排序演算法的執行過程中,50 與50’
的相對位置一直保持不變,因此如同氣泡排序與
插入排序演算法一樣,合併排序演算法也是一個
穩定(stable) 排序演算法。
合併排序演算法需要額外的與原來陣列大小相同
的記憶體空間來輔助排序的進行,因此合併排序
演算法不是就地(in place) 演算法,它的空間複雜
度為O(n),n 為需要排序陣列的元素個數。
12
合併排序演算法(續)
以下我們分析合併排序演算法的時間複雜度。
假設合併排序演算法將一個具有n 個元素的陣列排序完畢
的時間複雜度為T(n),則我們可以得到以下的式子:
T(n)=2T(n/2)+n
這是因為合併排序演算法直接將陣列分割為二個大小相同
或幾乎相同的陣列(大小為或約為原來陣列大小1/2) ,並分
別遞迴地以相同的演算法將二個子陣列加以排序(因此有
2T(n/2) 項目),最後,再使用n 次比較操作將二個子陣列
合併。
13
合併排序演算法(續)
我們遞迴地將T(n)=2T(n/2)+n中的n取代為n/2,
n/4, ...,則我們可以得到:
T(n) = 2T(n/2) + n = 2(2T(n/4)+(n/2)) + n = 4T(n/4) + n + n
= 4(2T(n/8)+(n/4)) + 2n= 8T(n/8) + 3n = .... = 2k T(n/2k) + kn
當陣列只有一個元素時,合併排序演算法不會再
進行遞迴呼叫,會直接回轉(return),因此我們可
得T(1) = 1。
14
合併排序演算法(續)
假設n = 2k,則k = log2 n。請注意,未來若我們不
特別指定log函數的基底,則代表基底為2。
代入k = log n,我們可得:
T(n) = n log n + 2k = n log n + n = O(n log n)
對所有的狀況(最佳、最差與平均狀況) 而言,合
併排序演算法的時間複雜度都是O(n log n)。
15
2.3 快速排序演算法
16
快速排序演算法
以下我們首先介紹快速排序(quick sort)演算法。此演算法由獲得計算機
領域最高榮譽圖靈獎(Turing Award)的Hoare博士於1962年發表。
如其名稱所示,此排序演算法的排序速度相當快,因此使用相當廣泛。
查 爾 斯 · 安 東 尼 · 理 察 · 霍 爾 爵 士 (Charles
Antony Richard Hoare,縮寫為 C. A. R.
Hoare,1934年1月11日- ),生於斯里蘭卡
可倫坡,英國計算機科學家,圖靈獎得主。他
設計了可快速進行排序程序的快速排序(quick
sort)演算法,提出可驗證程式正確性的霍爾
邏輯(Hoare logic) 、以及提出可訂定並時程
序(concurrent process)的交互作用(如哲學
家用餐問題(dining philosophers problem)的
交 談 循 序 程 續 (CSP, Communicating
Sequential Processes)架構 。 (圖及說明摘
自維基百科)
17
快速排序演算法(續)
快速排序演算法使用分治解題策略,其做法如下所
述:
分割: 選一個元素p當作中樞(pivot)元素將陣列分割為2部
份:SP及LP,其中SP (smaller part)包含所有小於或等於
p的元素;而LP(larger part)則包含所有大於p的元素。
克服:完成陣列分割(partition)之後,快速排序演算法持續
遞迴地(recursively)進行SP部份與LP部份的元素排序。
合併: 最後再將SP、p及LP合併即可完成排序。
18
快速排序演算法(續)
Algorithm 8為快速排序演算法,此演算法使用二個
指標(「左指標」l 與「右指標」r) 將陣列中索引在
「左界」lb 及「右界」rb 範圍內的元素分割為二部
份。
19
快速排序演算法(續)
20
快速排序演算法(續)
以下我們舉實例來看快速排序演算法的運作過程。
假設有一個陣列具有8個元素85、24、63、50、17
、50'、96、58 ,索引(index)為0,...,7,其中50與
50’二個元素的值都是50,但是為了區別起見,我們
將之標示為50與50’。
下圖展示快速排序演算法第一次將陣列分割為二個
部份的過程。
21
快速排序演算法(續)
22
快速排序演算法(續)
在整個快速排序演算法的執行過程中,50與50’的相
對位置產生變化,因此快速排序演算法不是一個穩
定(stable)排序演算法。
快速排序演算法不需要額外的記憶體空間來輔助排
序的進行,因此快速排序演算法是就地(in place)演
算法,它的空間複雜度為O(1)。
23
快速排序演算法(續)
以下我們分析快速排序演算法的時間複雜度。
在最佳狀況下,快速排序演算法每次都將陣列分割為二個大小相同或幾乎相同
的子陣列(我們可以將分割後的二個子陣列都視為是原陣列的1/2大小) 。
假設利用快速排序演算法針對具有n 個元素的陣列(也就是說輸入規模為n) 進
行排序的時間複雜度為T(n),針對最佳狀況,我們可以得到以下的式子:
T(n)=n+2T(n/2)
這是因為當指標l 持續往右移,而同時指標r 持續往左移而交叉時(也就是說
l r 時),代表陣列分割完成。指標每次移動一個位置需要一次的數值比較操作
,因此要完成陣列分割需要執行n 次數值比較操作。而陣列分割完成之後,快
速排序演算法就利用遞迴的方式分別完成二個大小相同的(均為n/2) 子陣列排序
。
如合併排序演算法的分析一樣,我們可得 T(n)=O(n log n)
24
快速排序演算法(續)
以下我們分析快速排序演算法的最差狀況時間複雜度。
當陣列的n 個元素已經依由小而大的方式排列的情況下會產生最差狀況。
在此情況下,快速排序演算法首先在經過n 次數值比較操作之後,將陣列分
割為單一一個所有元素都比中樞元素小,具有n − 1 個元素的子陣列。
經過遞迴呼叫,快速排序演算法再利用n − 1 次數值比較操作將陣列分割為
單一一個所有元素都比新中樞元素小,具有n − 2 個元素的子陣列。
如此不斷遞迴執行,直到陣列分割出僅包含一個元素的子陣列為止。
同樣假設快速排序演算法的時間複雜度為T(n),針對最差狀況,我們可以得
到以下的式子:
T(n) = n + (n − 1) + (n − 2) + ... + 1
=n(n − 1)/2
= O(n2)
25
快速排序演算法(續)
26
快速排序演算法(續)
27
快速排序演算法(續)
n-1, n-2,…,1
28
快速排序演算法(續)
29
排序演算法比較
30
2.4
缺陷棋盤填滿演算法
31
缺陷棋盤填滿演算法說明
缺陷棋盤填滿演算法使用分治策略解決缺陷棋
盤填滿問題,使用三格骨牌填滿缺陷棋盤
以下我們先定義甚麼是棋盤、缺陷棋盤及三格
骨牌
然後我們定義缺陷棋盤填滿問題
最後我們介紹缺陷棋盤填滿演算法
32
棋盤的定義
一個棋盤是一個 n x n方格(grid),具有
n2個單格(cell),其中n2而且n是2的幂(a
power a 2)
2x2
4x4
8x8
33
缺陷棋盤的定義
缺陷棋盤是有一單格(cell)無法使用的棋盤。
X
X
2x2
X
4x4
8x8
34
三格骨牌的定義
三格骨牌(Triomino)為一L型骨牌,可填
滿一棋盤上的3個單格。
三格骨牌有4種方向。
35
缺陷棋盤填滿問題
放置(n2 - 1)/3 個三格骨牌在n x n缺陷棋
盤上,使得全部(n2 – 1)個非缺陷單格都
被填滿。
X
X
2x2
X
4x4
8x8
36
缺陷棋盤填滿演算法
Algorithm 缺陷棋盤填滿演算法
Input: n x n缺陷棋盤, n2而且n是2的幂
Output: 以三格骨牌填滿的n x n缺陷棋盤
步驟1: 若n=2,則旋轉一個三格骨牌直接填滿缺陷棋盤
,回傳此2 x 2缺陷棋盤並結束。
步驟2: 將缺陷棋盤分為3個(n/2) x (n/2)棋盤及1個(n/2)
x (n/2)缺陷棋盤,旋轉一個三格骨牌填滿3個棋盤中相鄰
的單格,可使3個棋盤成為缺陷棋盤,我們可得4個(n/2)
x (n/2)缺陷棋盤。
步驟3: 遞迴地使用缺陷棋盤填滿演算法以三格骨牌填滿
步驟2的4個(n/2) x (n/2)缺陷棋盤,回傳原始n x n缺陷
棋盤並結束。
37
缺陷棋盤填滿演算法實例
X
將8 x 8缺陷棋盤分割成4個更小的 4 x 4 棋盤。
其中1個為4 x 4缺陷棋盤,其他3個為一般 4 x 4 棋盤。
38
缺陷棋盤填滿演算法實例(續)
X
• 放置1個三格骨牌在3個4 x 4正常棋盤的相鄰單格,
讓他們也變成缺陷棋盤。
• 再以遞迴方式填滿4個缺陷4 x 4棋盤。
39
缺陷棋盤填滿演算法實例(續)
• 以遞迴方式填滿右上角之缺陷4 x 4棋盤。
X
• 以遞迴方式填滿左上角之缺陷4 x 4棋盤….。
40
2.5 二維求秩演算法
41
二維求秩演算法說明
二維求秩(2D rank finding)演算法使用分
治策略解決二維求秩問題
以下我們先定義支配(dominate)及
秩(rank)
然後我們定義二維求秩問題
最後我們介紹二維求秩演算法
42
支配及秩的定義
令A = (ax, ay), B = (bx, by)為二維XY平面上的點,則我們說A
支配(dominate)B(記為AB)若且唯若 ax> bx 且 ay > by。
給定一個由二維平面點所構成的集合S,點A之秩(rank)定義
為集合S中有多少個點被A所支配。
E.G.: BA, CA, DC, EA
E.G.: rank(A)=0, rank(B)=1,
rank(C)=1, rank(D)=2,
rank(E)=2
43
二維求秩問題
給定一個由n個二維平面點所構成的集合S,求
出S中所有點的秩。
可以用窮舉(exhaustive)演算法,比較所有的可能
成對點,時間複雜度為O(n2)。
44
二維求秩演算法
Algorithm 二維求秩演算法
Input: n個二維平面點所構成的集合S,n1
Output: 集合S中所有點的秩(rank)
步驟1: 若n=1,則回傳S中唯一一個點的秩為0並結束。
步驟2: 找出所有點的X軸中位數(median)畫出垂直於X軸
的直線L,將S中的點分為二個集合SL與SR。
步驟3: 遞迴地使用二維求秩演算法分別求出SL與SR中所
有點的秩。
步驟4: 根據Y軸值排序所有在S(S=SLSR)中的點,依序
掃描所有點且求出每一個在SR 的點i排在多少在SL的點的
後面(記為updatei),並將點i的秩加上updatei;最後回傳
S中所有點的秩並結束。
45
二維求秩演算法範例
假定給定平面上10個點,依其X軸中位數(median)畫出直
線L將之分為二個集合SL與SR。下圖顯示SR中所有點的秩
的更新。
46
二維求秩演算法時間複雜度分析
步驟時間複雜度:
步驟2: c1n log n (排序)
步驟4: c2n log n (排序)
Algorithm 二維求秩演算法
Input: n個二維平面點所構成的集合S,n1
Output: 集合S中所有點的秩(rank)
步驟1: 若n=1,則回傳S中唯一一個點的秩為0並結束。
步驟2: 找出所有點的X軸中位數(median)畫出垂直於X軸的直線L,
將S中的點分為二個集合SL與SR。
步驟3: 遞迴地使用二維求秩演算法分別求出SL與SR中所有點的秩。
步驟4: 根據Y軸值排序所有在S(S=SLSR)中的點,依序掃描所有點
且求出每一個在SR的點i排在多少在SL的點的後面(記為updatei),並
將點i的秩加上updatei;最後回傳S中所有點的秩並結束。
總時間複雜度:
T(n) = 2T(n/2) + c1n log n + c2n log n
= 2T(n/2) + cn log n
= 2(2T(n/4)+c(n/2) log (n/2))+ cn log n
= 4T(n/4) + cn log (n/2) + cn log n
= nT(1) + cn(log n + log (n/2)+ log (n/4) +…+ log 2)
nT(1) + cn (log n (log n+ log 2))/2 (其中T(1)=1)
= O(n log2n)
47
2.6 二維極大點演算法
48
二維極大點演算法說明
二維極大點(2D maxima finding)演算法
使用分治策略解決二維極大點問題
以下我們先定義支配(dominate)及
極大點(maxima)
然後我們定義二維極大點問題
最後我們介紹二維極大點演算法
49
支配及極大點的定義
令A = (ax, ay), B = (bx, by)為二維XY平面上的點,則我們說A
支配(dominate)B(記為AB)若且唯若 ax> bx 且 ax > by。
如果一個點不被任何其他點所支配,我們就稱此點不被支配
(non-dominated),或稱此點為極大點(maxima)。
極大點不只一個。
50
二維極大點問題
給定一個由n個二維平面點所構成的集合S,求
出S中的極大點(maxima)。
可以用窮舉(exhaustive)演算法,比較所有的可能
成對點,其時間複雜度為O(n2)。
51
二維極大點演算法
Algorithm 二維極大點演算法
Input: n個二維平面點所構成的集合S,n1
Output: 集合S中所有的極大點(maxima)
步驟1: 若n=1,則回傳S中唯一一個點為極大點並結束。
步驟2: 找出所有點的X軸中位數(median)畫出垂直於X軸的
直線L,將S中的點分為二個集合SL與SR。
步驟3: 遞迴地使用二維極大點演算法分別求出SL與SR中所
有的極大點。
步驟4: 在SR的極大點中找出最大的Y軸值y*。 對每個在SL
中的極大點,如果該點的Y軸值小於y*,則標示該點為不
是極大點。回傳SR中的極大點和SL中未被標示的極大點。 52
二維極大點演算法範例
假定給定平面上10個點,依其X軸中位數(median)畫出直線
L將之分為二個集合SL與SR。下圖顯示SL中極大點的更新。
53
二維極大點演算法時間複雜度分析
步驟時間複雜度:
步驟2: c1n log n (排序)
步驟4: c2n (依序檢查)
Algorithm 二維極大點演算法
Input: n個二維平面點所構成的集合S,n1
Output: 集合S中所有的極大點(maxima)
步驟1: 若n=1,則回傳S中唯一一個點為極大點並結束。
步驟2: 找出所有點的X軸中位數(median)畫出垂直於X軸的直線
L,將S中的點分為二個集合SL與SR。
步驟3: 遞迴地使用二維極大點演算法分別求出SL與SR中所有的
極大點。
步驟4: 在SR的極大點中找出最大的Y軸值y*。 對每個在SL中的
極大點,如果該點的Y軸值小於y*,則標示該點為不是極大點
。回傳SR中的極大點和SL中未被標示的極大點。
總時間複雜度:
T(n) = 2T(n/2) + c1n log n + c2n
= 2T(n/2) + cn log n
= 2(2T(n/4)+c(n/2) log (n/2))+ cn log n
= 4T(n/4) + cn log (n/2) + cn log n
= nT(1) + cn(log n + log (n/2)+ log (n/4) +…+ log 2)
= nT(1) + cn (log n (log n+ log 2))/2 (其中T(1)=1)
= O(n log2n)
54
二維極大點演算法時間複雜度分析(續)
步驟時間複雜度:
步驟2: c1n
(以刪尋演算法求中位數)
步驟4: c2n (依序檢查)
總時間複雜度:
T(n) = 2T(n/2) + c1n + c2n
= 2T(n/2) + cn
= 2(2T(n/4)+c(n/2))+ cn
= 4T(n/4) + cn + cn
= nT(1) + cn+cn+…+cn (其中總共log n個cn)
= nT(1) + cn log n (其中T(1)=1)
= O(n log n)
Algorithm 二維極大點演算法
Input: n個二維平面點所構成的集合S,n1
Output: 集合S中所有的極大點(maxima)
步驟1: 若n=1,則回傳S中唯一一個點為極大點並結束。
步驟2: 找出所有點的X軸中位數(median)畫出垂直於X軸的直線
L,將S中的點分為二個集合SL與SR。
步驟3: 遞迴地使用二維極大點演算法分別求出SL與SR中所有的
極大點。
步驟4: 在SR的極大點中找出最大的Y軸值y*。 對每個在SL中的
極大點,如果該點的Y軸值小於y*,則標示該點為不是極大點
。回傳SR中的極大點和SL中未被標示的極大點。
55
2.7 最近二維點對演算法
56
最近二維點對演算法說明
最近二維點對(closest pair of 2D points)
演算法使用分治策略解決最近二維點對
問題
以下我們先定義最近二維點對問題
然後我們介紹最近二維點對演算法
57
最近二維點對問題
給定n個二維平面點,找出其中距離最近的二個
點的距離。
可以用窮舉(exhaustive)演算法,比較所有的成對
點,其時間複雜度為O(n2)。
58
最近二維點對演算法
Algorithm 最近二維點對演算法
Input: n個二維平面點所構成的集合S,n2
Output: 集合S中距離最近的二個點的距離d
步驟1: 根據X軸值與Y軸值來事先排序S中的點。
步驟2: 若n=2,則回傳S中二點的距離d並結束。
步驟3: 找出所有點的X軸中位數(median)m畫出垂直於X軸
的直線L,將S中的點分為二個集合SL與SR。
步驟4: 遞迴地使用二維點對演算法分別求出SL與SR中最近
二維點對的距離dL與dR,且令 d = min(dL, dR)。
59
最近二維點對演算法(續)
步驟5: 將X軸值介於m-d與m+d的所
有點的Y軸值投射至直線L上。針對於
每個X軸值落在範圍介於m-d與m之間
的點p,以yp 記錄其Y軸值,並尋找所
有X軸值落在範圍介於m與m+d之間
,且Y軸值介於yP+d 與 yP-d之間的所
有點,若存在一點與p之距離為小於d
的d’,則令d=d’。回傳d並結束執行。
60
最近二維點對演算法執行說明
61
最近二維點對演算法時間複雜度分析
步驟時間複雜度:
步驟 1: c1n log n (事先排序)
步驟 2~5:
T’(n)=
2T’(n/2)+c2n,
1,
n>2
n=2
Algorithm 最近二維點對演算法
Input: n個二維平面點所構成的集合S,n2
Output: 集合S中距離最近的二個點的距離d
步驟1: 根據X軸值與Y軸值來事先排序S中的點。
步驟2: 若n=2,則回傳S中二點的距離d並結束。
步驟3: 找出所有點的X軸中位數(median)m畫出垂直於X
軸的直線L,將S中的點分為二個集合SL與SR。
步驟4: 遞迴地使用二維點對演算法分別求出SL與SR中最
近二維點對的距離dL與dR,且令 d = min(dL, dR)。
步驟5: 將X軸值介於m-d與m+d的所有點的Y軸值投射至
直線L上。針對於每個X軸值落在範圍介於m-d與m之間
的點p,以yp 記錄其Y軸值,並尋找所有X軸值落在範圍
介於m與m+d之間,且Y軸值介於yP+d 與 yP-d之間的所
有點,若存在一點與p之距離為小於d的d’,則令d=d’。
回傳d並結束執行。
T’(n) = c2n log n
總時間複雜度:
T(n) = c1n log n + c2n log n = O(n log n)
62
2.8 刪尋演算法基本概念
63
刪尋解題策略
刪尋(prune-and-search)解題策略使用多次迭代
(iteration)解決問題。
在每次迭代都刪除(prune)輸入資料的一部份(假
設為f部份, 0<f<1),而後採用相同的演算法遞迴
地(recursively)從剩餘資料中搜尋(search)出解答。
而經過幾次迭代後,輸入資料的規模將會小到足
以讓問題使用常數時間複雜度直接解決。
64
使用刪尋解題策略的演算法
二元搜尋演算法
選取與中位數演算法
限制的一圓心演算法
簡化的二變數線性規劃演算法
65
一般刪尋演算法時間複雜度
假設輸入規模為n,而刪尋演算法每次迭代
都刪除(prune)輸入資料的f 部份(0<f<1),
若在每次迭代執行所需的時間複雜度為
cnk=O(nk), k >0,則在最差狀況下刪尋演算
法的時間複雜度T(n)為:
T(n) = T((1-f ) n) + cnk
66
一般刪尋演算法時間複雜度(續)
迭代p次,假定(1-f)p+1n 1 (1-f)pn
等比級數公式
67
2.9 二元搜尋演算法
68
二元搜尋演算法
給定一個已依由小到大順序排列的數值陣列A
,假設我們要在索引 l 與 索引 r 之間找出目
標數值t的索引,則我們可以使用二元搜尋
(binary search)演算法採用刪尋策略來有效率
地進行這項工作。
69
二元搜尋演算法(續)
70
二元搜尋演算法範例
已排序好的陣列A: (搜尋 43)
索引: -1
0
1
2
3
4
5
6
數值:
2
8 11
27 38
43
52
(搜尋43)
迭代1
l
m
r
迭代2
l
m
r (傳回索引5)
(搜尋1)
迭代1
l
m
r
迭代2
l
m r
迭代3
l,r,m
迭代4 r
l (因r<l,故傳回索引-1代表t不在陣列中)
71
二元搜尋演算法
是刪尋還是分治演算法?
二元搜尋演算法可視為刪尋(prune-andsearch)演算法。在每一個迭代的比較之後
,會有一半的資料被刪除(prune away )。
二元搜尋演算法亦可視為分治(divide-andconquer)演算法。在每一次分割之後,一
個分割可能存在解答,另一個分割一定不
存在解答。
72
二元搜尋演算法時間複雜度分析
假設搜尋範圍內有n個元素,則時間複雜度T(n)為:
T(n/2)+1 , n>1
T(n)=
1
, n=1
T(n) = T(n/2)+1
= T(n/4)+1+1
:
=T(n/2k)+k*1
令n/2k=1 ,則n = 2k 且k=log n, 我們可得
T(n) = T(1)+k
= 1+k
= O(log n)
73
2.10 選取與中位數演算法
74
選取與中位數問題
給定一個擁有n個元素的集合S,選取問題
(selection problem)欲尋找S中第k小的元素。
給定一個擁有n個元素的集合S,中位數(median)
問題欲尋找S中第 n2 小的元素。
最直接的演算法:
步驟1: 將n個元素依由小而大排序
n
步驟2: 從排序好的元素中找出第k個或第 2 個元素
時間複雜度: O(n log n)
75
以刪尋策略解決選取問題
令S={a1, a2, …, an}
找出 p S, 用 p 將 S 分割成 3 個子集合 S1 , S2 , S3:
S ={ a | a < p , 1 i n}
1
i
i
S ={ a | a = p , 1 i n}
2
i
i
S ={ a | a > p , 1 i n}
3
i
i
若 |S1| > k ,代表第k小的元素在S1中,我們可刪除S2和S3。
否則,若 |S1| + |S2| > k,則 p 就是 S 中第 k 小的元素。
否則,代表第 k 小的元素是S3中第(k - |S1| - |S2|)小的元素,我
們可刪除S1和S2。
76
以刪尋策略解決選取問題(續)
Q: 如何選擇 p?
A: 中位數的中位數
How: 將n個元素分割成n/5個大小為5的子集合,找出每個子集合
的中位數,然後再找出這些中位數的中位數。
問題: 為什麼選擇子集合的大小為5?3可以嗎?4可以嗎?6可以嗎?
5
並,針
找直對
出接每
其將一
中其個
位元大
數素小
。由為
小
到的
大子
排集
列合
S中至少有1/4的元素小於或等於p (S1至少有1/4的元素)
p
再找出中位數的中位數p
S中至少有1/4的元素大於或等於p
(S3至少有1/4的元素)
77
刪尋選取演算法
Algorithm 刪尋選取演算法
Input: 一個有n個元素的集合S,以及整數k。
Output: 集合S內第k小的元素。
步驟1: 將S分割為n/5個大小為5的子集合。若
n不能被5整除的話則在最後一個子集合內增加
值為的元素,使其補滿5個元素。
步驟2: 直接排序每個子集合內的元素。
步驟3: 從每個子集合內找出中位數,再遞迴地
從找出的中位數中找出中位數(也就是找出所有
子集合中位數的中位數),令其為p。
78
刪尋選取演算法(續)
步驟4: 將S分成 S1, S2, S3三個子集合,每個子集合分
別包含小於、等於、大於p的元素。
步驟5: 若 |S1| k, 則捨棄 S2 與 S3 並且在下一次迭代
中從S1 內找出第k小的元素為輸出(令S=S1;跳回步驟
1);否則,若|S1| + |S2| k 則輸出p為S內第K小的元
素; 否則,令 k = k - |S1| - |S2|,在下一次的迭代中
從S3 找出第 k’ 小的元素為輸出(令S=S3;k=k’;跳回
步驟1) 。
79
刪尋選取演算法時間複雜度分析
一次的迭代至少可以刪除n/4個元素,剩餘的3n/4
個元素,可以在步驟5遞迴地處理。
步驟3以遞迴的方式找出n/5個中位數的中位數。
步驟時間複雜度:
步驟1:
步驟2:
步驟3:
步驟4:
步驟5:
O(n)
O(n)
T(n/5)
O(n)
T(3n/4)
總時間複雜度: T(n) = T(3n/4)+T(n/5)+cn
80
刪尋選取演算法時間複雜度分析(續)
令 T(n) = a0 + a1n + a2n2 + … , a1 0
T(3n/4) = a0 + (3/4)a1n + (9/16)a2n2 + …
T(n/5) = a0 + (1/5)a1n + (1/25)a2n2 + …
T(3n/4 + n/5) = T(19n/20) = a0 + (19/20)a1n + (361/400)a2n2 + …
T(3n/4) + T(n/5) a0 + T(19n/20)
T(n) c’n + T(19n/20)
c’n + (19/20)c’n +T((19/20)2n)
…
c’n + (19/20)c’n + (19/20)2c’n + … +(19/20)pc’n + T((19/20)p+1n) ,
(19/20)p+1n 1 (19/20)pn
19
1 - ( )p1
20 c' n c' ' 20 cn + c ’’ = O(n)
T(n) =
19
120
等比級數公式
81
2.11 限制的一圓心演算法
82
一圓心問題
一圓心問題(1-center problem):
給定n個平面點,找出一個最小可覆蓋此
n個點的圓。
83
一圓心問題(續)
基本暴力(brute force)法: 列出每一個可能的候
選圓並檢查其是否能夠覆蓋所有的點:
任取三點做圓: 時間複雜度O(n3)
任取二點為直徑做圓: 時間時間複雜度O(n2)
針對一個候選圓檢查是否能夠覆蓋所有的點: O(n)
總時間複雜度: O(n4)
84
限制的一圓心問題
限 制 的 一 圓 心 問 題 (constrained 1-center
problem):
給定n個平面點,找出一個最小可覆蓋此n個點
的圓,但是限制圓心r必須座落在y=c(例如y=0)
的直線上。
85
限制的一圓心演算法
Algorithm 限制的一圓心演算法
Input: n個平面點p1, p2, …, pn與直線y = c
Output: 圓心在y=c上可覆蓋p1, p2, …, pn的最小圓
步驟1: 若n2,則直接找出圓。
步 驟 2: 若 n 為 偶 數 , 則 形 成 n/2 個 點 對 (p1,
p2), …,(pn-1, pn);反之,若n為奇數,則形成n/2
個點對(p1, p2), …, (pn-2, pn-1), (pn, p1)。
步驟3: 對於每一點對(pi, pi+1),做出其中垂線Lij,
交於直線y=c,以找出一個在直線y=c上的等距點
qi,i+1,使得d(pi, qi,i+1)= d(pi+1, qi,i+1),其中d(p, q)
86
代表點p與點q的距離。
限制的一圓心演算法(續)
步驟4: 找出所有等距點的X座標值的中位數xm,令對應的等
距點為qm=(xm, c)。
步驟5: 以qm來評估最佳解圓心q*在y=c的位置: 計算每個pi
與點qm的距離,並令pj為距qm最遠的點。令qj表示pj 在直線
y=c上的投影點,若 qj 落在qm左側(右側),則最佳解圓心q*
亦必定會落在qm的左側(右側)。
步驟6: 若q*落在qm的左側,則針對每個X軸值大於xm的等距
點qi,i+1,刪除其對應點pi與pi+1中靠qm較近的點;反之,若q*
落在qm的右側,則針對每個X軸值小於xm的等距點qi,i+1,刪
除其對應點pi與pi+1中靠qm較近的點。
步驟7: 跳到步驟1繼續執行。
87
限制的一圓心演算法執行展示
Lij
pj
pi
pi+1
qi,i+1
q*
qm=(xm, c)
y=c
qj
步驟4: 找出所有等距點的X座標值的中位數xm,令對應的等
距點為qm=(xm, c)。
步驟5: 以qm來評估最佳解圓心q*在y=c的位置: 計算每個pi
與點qm的距離,並令pj為距qm最遠的點。令qj表示pj 在直線
y=c上的投影點,若 qj 落在qm左側(右側),則最佳解圓心q*
亦必定會落在qm的左側(右側)。
步驟6: 若q*落在qm的左側,則針對每個X軸值大於xm的等距
點qi,i+1 ,刪除其對應點pi 與pi+1 中靠qm 較近的點;反之,若q*
落在qm 的右側,則針對每個X軸值小於xm的等距點qi,i+1 ,刪
除其對應點pi與pi+1中靠qm較近的點。
88
限制的一圓心演算法時間複雜度分析
限制的一圓心演算法使用刪尋策略解決問題,
在每個迭代均刪除一部份輸入資料。由於每個
迭代均有n/4個等距點在qm的左方(或右方),
故演算法每次迭代均可刪除n/4個點。
由於步驟2-6的時間複雜度均為O(n),根據前
述「一般刪尋演算法時間複雜度」的說明,限
制的一圓心演算法的時間複雜度為
T(n)=T(3n/4)+cn=O(n)
89
2.12
簡化的二變數線性規劃演算法
90
線性規劃或線性最佳化問題
線性規劃(linear programming)或
線性最佳化(linear optimization)問題:
欲最大化或最小化目標函數: c1 x1 c2 x2 cd xd
限制條件(限制式)為: a11 x1 a12 x2 a1d xd b1
a21 x1 a22 x2 a2 d xd b2
an1 x1 an 2 x2 and xd bn
( x1 , x2 , , xd 0)
91
二變數線性規劃範例
最大化 3x1 8x2 x2
限制條件如下:
(1) x1
4
(2)
x2 3
(3) 5x1 - 2x2 24
(4) 2x1 3x2 46
(5) -4x1 + 3x2 16
(x1=5, x2=12)
(5)
(1)
可行解
區域
3x1 8x2 =111
(4)
(3)
(2)
3x1 8x2 =0
x1
92
線性規劃或線性最佳化(續)
線性規劃 (linear programming, LP)問題: 目標函數
(objective function)和限制條件(constraints)都是線性(
變數都是一次方)的最佳化(optimization)問題。是多項
式時間複雜度(polynomial time complexity)問題。
要求所有變數都限定為整數的線性規劃問題叫做整數
線性規劃 (integer linear programming, ILP)或整
數規劃(integer programming, IP)問題。是NP困難
(NP-hard)問題。
0/1 整數規劃(0/1 integer linear programming,
0/1 ILP)是整數線性規劃的特殊情況,要求所有的變
數都要是0或1。是NP困難(NP-hard)問題。
93
著名的線性規劃演算法
1947: 單 形 演 算 法 (simplex alg.): George Dantzig,
O(2n), n為限制式的個數
1975: 諾 貝 爾 經 濟 獎 : L. V. Kantorovich 和 T. C.
Koopmans (基於線性規劃的「資源最佳分配理論」)
1979: 橢球演算法(ellipsoid alg.): Leonid Khachiyan,
第一個最差狀況時間複雜度為多項式的線性規劃演算
法, O(n6L2 log L log log L), L為輸入的位元數。但是
這個演算法實際使用時效能並不好。
1984: 投 射 演 算 法 (projective alg.): N. Karmarkar,
O(n3.5L2 log L log log L)
以上資料參考維基百科: http://en.wikipedia.org/wiki/Linear_programming
94
簡化的二變數線性規劃問題
簡化的二變數線性規劃(simplified twovariable linear programming)問題:
給定n個限制條件,其中第i個限制條件為:
y kix + ti, i = 1, 2, …, n
(ki為斜率,ti為y截距)
欲最小化目標函數y
95
簡化的二變數線性規劃問題範例
給定n(n=6)個限制條件,
欲最小化目標函數y
可行解區域之邊界
(boundary)函數B(x):
B(x) = max {ki x ti }
1i n
最佳解(x*, y*):
y*=B(x*) = min
B(x)
- x
96
簡化的二變數線性規劃演算法
97
簡化的二變數線性規劃演算法說明
步驟2總共產生n/2對限制式
步驟4產生邊界函數值ym=B(xm)的限制式可能為一個、兩個
或兩個以上。但是不管有幾個限制式,在步驟5中,我們只要
找出限制式中最大的斜率smax與最小的斜率smin就可以判斷xm
與x*的關係
步驟6刪除n/4對限制式中的一個限制式,總計刪除n/4個
限制式
98
xm與x*的關係
假設xm是成對方
程式交點x座標中
位數, x*是最佳
解x座標
Q: x*<xm?
或
x*=xm?
或
x*>xm?
99
限制式刪除範例
y
B(x)
可行解區域
(x*, y*)
k5x+t5
x56
k1x+t1
k3x+t3
k4x+t4
k6x+t6 k2x+t2
x*
x
xm=x12 x34
如左圖,因為
x*>xm=x12 ,而且限制
式k5x + t5和k6x + t6交
點的x座標x56是小於xm
,因此我們可以刪除限
制式k5x + t5。
這是因為當x>x56時,
k5x + t5 < k6x + t6,這
代表當x=x*>xm時,k5x
+ t5不可能是boundary
function。
因此可以刪除條件式
k5x + t5(一對限制式中
的一個)
100
簡化的二變數線性規劃演算法
時間複雜度分析
因為在每個迭代中,總是有限制式配對中的一個限
制式會被刪除,因為總共有 n/2對限制式,因此
有n/4個限制式在每一次的迭代中被刪除。
時間複雜度:
T(n) = T(3n/4)+cn = O(n)
101
The End
102
等比級數
假設一個等比級數Sn的首項為a1,末項
為an,公比為r,則
Sn=a1(1-rn)/(1-r)=(a1-ran)/(1-r)
假設一個無窮等比級數S的首項為a1,
公比為r。若r<1,則
S=a1/(1-r)
103