br-mtc(budgeted rooted maximum tree cover) 問題是帶權值有根的最大樹覆蓋問題。輸入為乙個無向圖,乙個權值b,乙個根節點r,輸出為一棵包含根節點r,邊的權值之和不超過權值b的覆蓋最多頂點的樹。
首先我們可以考慮到,權值b的大小應該是有限的,一般不會超過這張圖最小生成樹的耗費,否則,可以直接輸出最小生成樹。
在經過了之前幾篇**的學習之後,我們意識到進度有些緩慢,而且時間有限,因此開始了我們這個問題演算法的研究。
首先,因為這個問題是個np難問題,我們是採用了暴力搜尋的方式獲取最優解用於比較。
然後在討論的時候,在思考區域性搜尋和prim的時候,想到了乙個基礎的演算法框架。
演算法過程如下
以每個點i為根節點,使用prim演算法,將得到邊加入e_i,當邊的權值之和大於b的時候停止。這個時候,可以獲得對於每個節點的簇。
以i為源點,根節點r為目的點,獲取一條從i到r的最短路徑。儲存到e_ir中。現在就有兩個集合e_i和e_ir,比較集合e_i和e_ir,首先保留重複的邊,對於出現在e_ir中但是沒有出現在e_i中的邊,用e_i中的去掉了重複邊之後權值最大的邊來代替。將e_ir中的非重複邊的權值求和,然後用e_i中的權值較大的邊來代替。
1.需要代替的邊的權值》e_i中可以被代替的邊的權值,那麼,這個時候說明在預算b的限制下,點i和根節點r無法形成通路,設i『為i和r的連通路徑的上乙個節點,那麼,從點i開始刪邊,也就是刪掉邊ii』,看是否能夠加入通路的邊。一直往上刪。
2.需要代替的邊的權值<=e_i中可以被代替的邊的權值。這樣,首先是可以形成i到r的聯通路徑。同時可能會還包含了一些聯通路徑之外的點。
這樣就形成了一條包含節點r的樹,這棵樹未必包含源點i,但是是在源點i的附近進行了區域性搜尋的。i和i附近的點形成的搜尋重合的可能性很大。
形成的解不是最優解。
綠色邊是最短路徑,紅色邊是缺失邊,藍色邊是簇的邊。
這是當天晚上的演算法框架。因為是凌晨想出來的,討論到了兩點。
第二天,我們重新捋了一遍之後,發現,先prim再找最短路徑再補邊的方式很累贅。可以直接先採取求根節點r到任意乙個點的i的最短路徑,然後權值不足以找最短路徑的話,就捨棄這個點,如果足夠,就在點i的附近以剩餘的權值使用prim演算法。
後面我們發現,這其實是斯坦納樹的一種特殊情況。以r為根的prim相當於require節點(也就是必須經過的節點)為1個點的情況。而我們後來提出的演算法,是斯坦納樹中require節點為2的情況,也就是根節點r和節點i是必經的節點。斯坦納樹問題也是乙個np難問題,但是在這種特殊情況下,是可以用kruskal+prim演算法在多項式時間內解決的。
演算法的進一步優化。在計算根節點r到頂點i的最短路徑的時候,可以保留中間經過的節點,當得到最短路徑的時候,我們也得到了一部分的聯通路徑的點,以這部分的點來做prim,會比以點i來做prim更優一點。
**目前還有一些問題,內部的邏輯在出現一些特殊情況的時候會出現bug,不過也得到了一些圖。還在繼續修改中。
這是目前可以得到的結果。
下面這個鏈結是我們組最終的解決方案,供參考。
創新實訓團隊記錄
子集和問題的完全多項式近似模式
1.問題定義 輸入 有限正整數集合s 和正整數t 輸出 s的某個子集s 使其元素之和最大且不超過t。2.指數時間演算法 為了求解問題的優化解,我們採用列舉法求s得所有子集和。列舉方法的基本思想是,依次對i 0,1,n 1,利用的所有子集和構造的所有子集和,最終得到s的所有子集和。已知li 表示進行到...
多項式時間演算法
定義 若存在乙個常數c,使得對於所有n 0,都有 f n c g n 則稱函式f n 是o g n 時間複雜度是o p n 的演算法稱為多項式時間演算法,這裡p n 是關於n的多項式。不能夠這樣限制時間複雜度的演算法被稱為指數時間演算法。例如 時間複雜度為o nlog n o n 3 的演算法都是多...
多項式時間 Polynomial time
什麼是時間複雜度?時間複雜度並不是表示乙個程式解決問題需要花多少時間,而是當程式所處理的問題規模擴大後,程式需要的時間長度對應增長得有多快。也就是說,對於某乙個程式,其處理某乙個特定資料的效率不能衡量該程式的好壞,而應該看當這個資料的規模變大到數百倍後,程式執行時間是否還是一樣,或者也跟著慢了數百倍...