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),其中n2而且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缺陷棋盤, n2而且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(記為AB)若且唯若 ax> bx 且 ay > by。
給定一個由二維平面點所構成的集合S,點A之秩(rank)定義
為集合S中有多少個點被A所支配。
E.G.: BA, CA, DC, EA
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,n1
Output: 集合S中所有點的秩(rank)
步驟1: 若n=1,則回傳S中唯一一個點的秩為0並結束。
步驟2: 找出所有點的X軸中位數(median)畫出垂直於X軸
的直線L,將S中的點分為二個集合SL與SR。
步驟3: 遞迴地使用二維求秩演算法分別求出SL與SR中所
有點的秩。
步驟4: 根據Y軸值排序所有在S(S=SLSR)中的點,依序
掃描所有點且求出每一個在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,n1
Output: 集合S中所有點的秩(rank)
步驟1: 若n=1,則回傳S中唯一一個點的秩為0並結束。
步驟2: 找出所有點的X軸中位數(median)畫出垂直於X軸的直線L,
將S中的點分為二個集合SL與SR。
步驟3: 遞迴地使用二維求秩演算法分別求出SL與SR中所有點的秩。
步驟4: 根據Y軸值排序所有在S(S=SLSR)中的點,依序掃描所有點
且求出每一個在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(記為AB)若且唯若 ax> bx 且 ax > by。
如果一個點不被任何其他點所支配,我們就稱此點不被支配
(non-dominated),或稱此點為極大點(maxima)。
極大點不只一個。
50
二維極大點問題

給定一個由n個二維平面點所構成的集合S,求
出S中的極大點(maxima)。

可以用窮舉(exhaustive)演算法,比較所有的可能
成對點,其時間複雜度為O(n2)。
51
二維極大點演算法







Algorithm 二維極大點演算法
Input: n個二維平面點所構成的集合S,n1
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,n1
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,n1
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,n2
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,n2
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 - ( )p1
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: 若n2,則直接找出圓。
步 驟 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 }
1i 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