接上文:http://blog.csdn.net/jj12345jj198999/article/details/6622344
一個O(nlogn)的演算法【標題4】
這裡的關鍵思想是加強歸納假設。由於要排序我們在合并步驟需要花費O(nlogn)的時間。儘管我們知道如何直接解決這個問題,但是它耗時太長。我們能夠做到在解決排序問題的同時解決最近對問題嗎?換句話說,我們想加強歸納假設把排序作為最近對問題的一部分包含進來從而得到一個更好的解法。
歸納假設:給定平面上一個少於n個點的集合,我們知道如何去尋找它們之間的最近距離也知道如何按照y座標排序後輸出該集合。
我們已經知道如果知道如何排序那該怎樣去尋找最小距離。因此,唯一需要做的事情是如果我們知道兩個含有n/2的子集排序次序那該如何對整個集合進行排序。換句話說,我們需要把兩個有序的子集合并成一個有序的集合。合并可以線上性的時間內完成(見例【1】)。因此,遞迴關係變成如下:
T(n)=2T(n/2)+O(n), T(2)=1,
這也意味著T(n)=O(nlogn)。該演算法和上一個演算法唯一的區別是按照y座標排序時不必每次都從頭開始進行。當我們執行時使用加強的歸納假設來進行排序。下面給出的是改進後的演算法。該演算法是由Shamo和Hoey(見[15])提出來的。
最近對演算法 {一個改進的版本}
{p1,p2...pn:平面上的點}
begin
按照x座標組點進行排序
{該排序只有在開始時執行一次}
把該集合劃分為兩個相等的部分;
遞迴的執行下面的步驟
計算每個部分中最小的距離;
按照y座標組每個部分的點進行排序;
把兩個有序的列表合并成一個有序列表;
{請注意我們必須在排除點之前合并,我們需要為下一階段的遞迴提供有序的全集}
把d賦值為兩個最小距離中的最小者;
排除出分割線d距離範圍外的點
按照y座標組剩下的點進行排序
按照y順序掃描這些點並計算每個點和它的五個鄰居之間的距離{事實上,4個就夠了}
if 這些距離中有小於d的 then
更新d值
end;
更強的歸納法【標題2】
更強的歸納法(有時也被稱為結構化歸納法)的思想在於不僅僅使用定理對於n-1(或者其他小於n的值)成立的假設,也使用定理對所有k(1≤k<n)成立的更強假設。把這種技巧轉換到演算法設計中需要維持一個含有所有小問題解法的資料結構。因此,該技巧通常引起更多的空間佔用。我們給出一個使用這種技巧的例子。
背包問題【Q8】【標題3】
背包問題是一個很重要的最佳化問題。它也有很多不同的變種,但這裡我們只討論其中的一種變種。
問題:這裡有n個不同大小的物品。第i個物品有一個整型的大小ki。問題是找到一個物品的子集使得該集合的大小總和正好為K,或者我們確定不存在這樣的子集。換句話說,給我們一個大小為K的背包我們想把它裝滿物品。我們把這個問題表示為P(n,K),第一個參數表示物品的數目,第二個參數表示背包的大小。我們假設大小是固定的。我們用P(j,k)(j≤n且k≤K)表示有j個物品和大小為k的背包問題。為了簡化,我們僅關心問題的結論,也就是決定是否存在這樣的一個解答。在後面我們給出如何去尋找到一個解答。
我們首先從最直接的歸納法開始。
歸納假設:我們知道如何去解決P(n-1,K)的問題。