注:本文作者也沒太搞懂k-center演算法
因為存在np-hard問題,沒有演算法能在多項式時間找出最優解。
在設計演算法的時候要考慮三個問題:1.最優解 2.快速 3.全部情況
如果三個都考慮,可能沒法在多項式時間內完成,所以就考慮2和3,在多項式的時間內找到乙個解,這個解可能不是最優解,但也不會太壞。
這就是近似演算法
常見例子有:裝箱問題(bin packing)、揹包問題(the knapsack problem)、紋理拼接問題(texture packing)
有一堆點(n),你要找到k個中心的位置,每個中心形成乙個半徑為r的圓,這些圓能覆蓋所有的點。
定義dist(x,y)和 dist(x,c)x, y是點, c是點的集合。
dist(x, y):兩個點間的距離
dist(x, c):點x到c集合中所有點的距離的最小值,在本問題裡就是裡最近中心的距離
在這個問題裡,把點實體化為老年人的房子(house->h),中心實體化為老年人活動中心(center->c)
問題就轉化為求出所有的dist(h.i, c),然後取其最大值作為r,這樣每個老年人都最多走r距離找到乙個活動中心。
為了讓老年人少走點路,k-center問題就需要找出讓r最小的k個中心位置。
這個問題裡我們用c*和r*表示最佳的情況。
亟待解決!
第一反應是因為k個點的位置組合太多了,遍歷會很慢。但很多非近似演算法不需要考慮所有情況,只需要考慮某些情況(比如最優情況,greedy)
問題轉化為:為什麼其他演算法思想沒法在多項式時間解決這個問題
下面第乙個貪婪演算法可能能幫助理解。
先建造乙個老年活動中心,讓老年人們都有地方去且r最小,然後再建第二第三個,縮小r的值。
但問題是建造了中心後拆起來不方便,就有可能出現特別糟糕的情況,讓這個中心不如廢棄。
舉例:兩個城市集資建立乙個老年活動中心,當然會建在兩個城市間。但後來老年人們覺得還是太遠了,於是讓兒女眾籌出了可以再建兩個中心的錢,在各自城市建立了新的兩個中心。第乙個中心就沒用了。(k = 3)r大幅度縮短,從高速路變成了城市街道的距離。
如果只眾籌出了乙個中心的錢,那還有乙個城市的老年人要跑和以前一樣遠的距離(半條高速路長),r還是沒變。(k = 2),顯然多等一段時間在兩個城市各建乙個才是最優情況。
!!!!!!發現理解有點不太對,思考中。請不要看下去了
這個演算法是預先設定乙個r值,然後看看這個r值能不能解決問題。
如何看能否解決問題?
隨便選乙個老年人a把他家作為活動中心,那些離a距離在2r內的老年人就可以不用去別的中心了。然後在從剩下的老年人中重複這個操作,直到沒有老年人了為止。
如果最後選出了k以內的老年人,r就是乙個可行解。
如果選的比k多,說明r肯定比最優解r*要小。
//偽**
centers greedy-2r ( sites s[ ], int n, int k, double r )
/* end-while */
if ( |c| ≤ k ) return c;
else error(no set
of k centers with covering radius at most r);
}
近似演算法 貪心演算法與近似演算法
1.1 教室排程問題 假設有如下課程表,你希望將盡可能多的課程安排在某間教室上。你沒法讓這些課都在這間教室上,因為有些課的上課時間有衝突。你希望在這間教室上盡可能多的課。如何選出盡可能多且時間不衝突的課程呢?這個問題好像很難,不是嗎?實際上,演算法可能簡單得讓你大吃一驚。具體做法如下。1 選出結束最...
裝箱問題近似演算法概述
問題描述 一維經典裝箱問題可描述如下 s s1,s2,sn 其中0 si 1,稱之為第i個物體的體積 或重量 1 i n,現有n個容積 或載重量 為1 的箱子,要求如何設法將s1,s2,sn放入盡可能少的箱中。裝箱問題是np問題,即在多項式時間內無法精確求解,一般採用近似演算法,即啟發式演算法,這樣...
近似演算法作業
近似演算法作業 題目 證明g中的最大團size為 等價於 g m中最大團size為m 證明 充分性 若g中最大團size為 根據g m的構造過程,g m中至少有存在乙個size為m 的團。首先g m中的最大團不可能小於m 如果小於小於m 則說明,構成g m最大團,每個g貢獻了少於 的結點,這種情況是...