最近看到一篇新闻: 英超再现恐怖食物链!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算法来计算:
|
|
运行可以得到它的强连通分量:
|
|
可以看到,这个强连通分量包含所有的20个队伍,说明第14轮结束后英超最长的食物链已经形成。
但是这个结果并没有将这个食物链返回,这个结果只是表明这20个队伍形成了食物链。
因为本人对相关的算法不熟悉,了解的读者回答下面的问题,或者提供自己的代码:
- Tarjan算法和Gabow算法不能将这个拓扑关系计算出来,而Kosaraju算法可以?
- 因为数据量不大,可以直接通过 DFS 算法进行搜索?
西甲的最大食物链是否形成了,答案是否定的,因为皇马前14轮还未输球。有兴趣的读者可以计算一下目前西甲的最大的食物链包括哪些球队。