1. 程式人生 > >2017華為軟體精英挑戰賽思路分析

2017華為軟體精英挑戰賽思路分析

宣告:這篇部落格僅用於(zhang)交(fang)流(wen)學(liang)習,讓大家更快的熟悉賽題,不會涉及到具體的演算法細節,所以不會影響到前排同學的排名,請不用擔心。

題目大意

有一個無向網路,網路的每條路徑有一個頻寬容量限制和單位頻寬的花費,網路中有一些消費節點,每個消費節點有一個容量需求,現在讓你在網路中佈置一些伺服器給消費節點提供頻寬,每個伺服器有固定的費用,讓你設計一種伺服器的佈置方案使得費用盡量少並輸出伺服器給消費節點提供頻寬的路徑

賽題分析

這道題是一道NP-hard問題,可以歸為優化選址一類的問題中去。

對於確定伺服器的位置這道題就是一個經典的多源多匯費用流問題了,多於多源多匯的費用流問題可以參考我的另一篇部落格:

POJ 2516 Minimum Cost(費用流 建圖)
這裡寫圖片描述
這裡簡單說一下思路:建立一個超級源點(不是圖中的點,自己虛擬的)連線到所有的伺服器,再建一個超級匯點連線到所有消費節點,這樣就變成了一個單源點單匯點的費用流問題,而費用流的求解可以用SPFA、dinic演算法、單純性演算法等,但是做為一個經典的演算法,我認為SPFA就差不多足夠了(其實是比較懶只會這一個演算法)。

由於題目要求還要輸出路徑,所以在費用流求完之後需要再進行一次深廣搜找路徑。

而對於這道題主要就是伺服器位置的確定了。主流的解決思路有遺傳演算法、模擬退火、粒子群等。

  • 模擬退火類似於爬山,大體思路是選取一個初始狀態,從這個狀態開始走,每次去找一個臨近地狀態,如果比當前的解好就走它,比當前的差有一定的概率會走它,在模擬退火裡面這個概率是用溫度作為一個影響因子來表示的,溫度越小,走差解的可能性越小。隨著迭代次數溫度逐漸降低最終收斂到一個區域性最優值。
  • 而遺傳演算法則是隨機選一些狀態作為初始的個體構成一個群體,每一次迭代都將這個群體中解較優的個體進行叫交叉互換和變異之後形成新的解。但是使用遺傳演算法需要我們認同一個假設:兩個較優解通過交叉互換變異之後也得到較優解的可能性是比較大的。
  • 粒子群可以看成是讓一群粒子在整個搜尋空間搜尋,這樣可以比較好的避免陷入區域性最優,但同時由於粒子數很多使得迭代一次所花費的時間也相對較多。

    以上幾個演算法本質上都是啟發式搜尋,目的都是高效地找到較優的解,各有各的好處,效果還是要具體實驗之後才能知道

    這些啟發式搜尋的效果和引數有很大關係,演算法設計好了之後的調參工作也是很重要的,引數調不好最後都退化成了xjbs(話說這次比賽xjbs演算法又火了一把233)

比賽心得

我認為華為軟體精英挑戰賽是一個很鍛鍊學生能力的比賽,不論是對程式設計能力、查閱文獻能力還是實驗能力都是很大的鍛鍊。

去年止步於區域前64,希望今年能衝進32!

晒一下目前排名(現在小資料的測試僅做娛樂使用,實際還是要等到大資料出來之後排名才有參考價值):
這裡寫圖片描述
3/25排名更新(經過了不斷的優化之後還是有驚無險地保住了前3):
這裡寫圖片描述
初賽榜單
這裡寫圖片描述
最後推薦兩個複雜網路分析工具:
gephi
igraph
小資料看起來是這樣的:
這裡寫圖片描述
這裡寫圖片描述
然而資料大了之後就變這樣了:
這裡寫圖片描述