使用演算法檢測英超中的食物鏈

來源:互聯網
上載者:User
這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。

最近看到一篇新聞: 英超再現恐怖食物鏈!20強相生相剋 今年用了14輪,對於足球和英超感興趣的讀者一定瞭解,所謂食物鏈是指A隊勝過B隊,B隊勝過C隊,……,N隊也勝過A隊,截止到英超第14輪,根據所有的隊伍的勝負關係,一條最大的食物鏈已經形成,英超20隊都加入到這個食物鏈中,相生相剋。

我看到這篇新聞的時候,有一點點程式員的不由自主的想法,能否通過演算法檢查目前最大的食物鏈,以及能否將食物鏈羅列出來?這也算是演算法解決實際問題的一個很好的例子吧。

很自然的,可以通過圖來表示兩隊之間的已經比賽的關係,因為我們我們只考慮勝負關係,不考慮平局,所以可以使用有向圖來表示。食物鏈可以單純用勝或者負來表示,所以我們的有向圖中以勝表示兩個節點之間的關係。

當然,我對圖相關的演算法不是很熟悉,所以特地搜了一下相關的成熟的演算法。對於食物鏈這個求解,我們可以看成求解這個有向圖中是否存在一個環,這個環包含所有的20個節點(20個英超隊)。也就是求解這個圖中的強連通分量。

百度百科: 有向圖強連通分量:在有向圖G中,如果兩個頂點vi,vj間(vi>vj)有一條從vi到vj的有向路徑,同時還有一條從vj到vi的有向路徑,則稱兩個頂點強連通(strongly connected)。如果有向圖G的每兩個頂點都強連通,稱G是一個強連通圖。有向圖的極大強連通子圖,稱為強連通分量(strongly connected components)。

相關的演算法包括 Kosaraju、Tarjan、Gabow等, 感興趣的朋友可以搜搜相關的介紹。

我使用 http://github.com/looplab/tarjan 提供的tarjon演算法來計算:

1234567891011121314151617181920212223242526272829303132333435
package mainimport ("fmt""github.com/looplab/tarjan")func main() {graph := make(map[interface{}][]interface{})graph["切爾西"] = []interface{}{"曼城", "熱刺", "米德爾斯堡", "埃弗頓", "南安普頓", "曼聯", "萊切斯特城", "胡爾城", "伯恩利", "沃特福德", "西漢姆"}graph["阿森納"] = []interface{}{"西漢姆", "伯恩茅斯", "桑德蘭", "斯旺西", "伯恩利", "切爾西", "胡爾城", "南安普頓", "沃特福德"}graph["利物浦"] = []interface{}{"桑德蘭", "沃特福德", "水晶宮", "西布羅姆維奇", "斯旺西", "胡爾城", "切爾西", "萊切斯特城", "阿森納"}graph["曼城"] = []interface{}{"水晶宮", "伯恩利", "西布羅姆維奇", "斯旺西", "伯恩茅斯", "曼聯", "西漢姆", "斯托克城", "桑德蘭"}graph["熱刺"] = []interface{}{"斯旺西", "西漢姆", "曼城", "米德爾斯堡", "桑德蘭", "斯托克城", "水晶宮"}graph["曼聯"] = []interface{}{"斯旺西", "萊切斯特城", "胡爾城", "南安普頓", "伯恩茅斯"}graph["西布羅姆維奇"] = []interface{}{"沃特福德", "伯恩利", "萊切斯特城", "西漢姆", "伯恩茅斯", "水晶宮"}graph["埃弗頓"] = []interface{}{"西漢姆", "斯托克城", "西布羅姆維奇"}graph["斯托克城"] = []interface{}{"伯恩利", "沃特福德", "斯旺西", "胡爾城", "桑德蘭"}graph["伯恩茅斯"] = []interface{}{"利物浦", "斯托克城", "胡爾城", "埃弗頓", "西布羅姆維奇"}graph["沃特福德"] = []interface{}{"萊切斯特城", "胡爾城", "米德爾斯堡", "曼聯", "西漢姆"}graph["南安普頓"] = []interface{}{"埃弗頓", "伯恩利", "西漢姆", "斯旺西"}graph["米德爾斯堡"] = []interface{}{"胡爾城", "伯恩茅斯", "桑德蘭"}graph["水晶宮"] = []interface{}{"南安普頓", "桑德蘭", "斯托克城", "米德爾斯堡"}graph["埃弗頓"] = []interface{}{"西漢姆", "米德爾斯堡", "桑德蘭"}graph["伯恩利"] = []interface{}{"水晶宮", "埃弗頓", "沃特福德", "利物浦"}graph["萊切斯特城"] = []interface{}{"水晶宮", "伯恩利", "斯旺西"}graph["西漢姆"] = []interface{}{"桑德蘭", "水晶宮", "伯恩茅斯"}graph["桑德蘭"] = []interface{}{"萊切斯特城", "胡爾城", "伯恩茅斯"}graph["胡爾城"] = []interface{}{"南安普頓", "斯旺西", "萊切斯特城"}graph["斯旺西"] = []interface{}{"水晶宮", "伯恩利"}output := tarjan.Connections(graph)fmt.Printf("%d, %v\n", len(output[0]), output)}

運行可以得到它的強連通分量:

1
20, [[阿森納 熱刺 曼聯 曼城 切爾西 斯旺西 西布羅姆維奇 利物浦 伯恩茅斯 米德爾斯堡 沃特福德 伯恩利 斯托克城 水晶宮 萊切斯特城 桑德蘭 西漢姆 埃弗頓 南安普頓 胡爾城]]

可以看到,這個強連通分量包含所有的20個隊伍,說明第14輪結束後英超最長的食物鏈已經形成。

但是這個結果並沒有將這個食物鏈返回,這個結果只是表明這20個隊伍形成了食物鏈。

因為本人對相關的演算法不熟悉,瞭解的讀者回答下面的問題,或者提供自己的代碼:

  1. Tarjan演算法和Gabow演算法不能將這個拓撲關係計算出來,而Kosaraju演算法可以?
  2. 因為資料量不大,可以直接通過 DFS 演算法進行搜尋?

西甲的最大食物鏈是否形成了,答案是否定的,因為皇馬前14輪還未輸球。有興趣的讀者可以計算一下目前西甲的最大的食物鏈包括哪些球隊。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.