我有一个玩家之间的决斗列表。数据由2个用户ID组成,其中第一个是获胜者。
如何构建此列表的图表以找到最佳玩家?
此外,我如何决定最佳意味着什么? 也许玩家应该根据被击败的对手的数量和那些对手的等级(递归)进行排名。 我以前尝试使用PageRank算法来做这件事,但它并没有以良好的方式解释损失(即等级应该从损失中减少)。
例如:
1 won against 3
1 won against 4
1 won against 5
2 won against 1
这个列表应该把2放在顶部,因为它击败了1。
这提出了一个问题 - 应该要求对那些排名靠前的人进行决斗。 那些没有超过一定等级的球员的人应该被告知这样做,以便进入最佳名单。
答案 0 :(得分:1)
将玩家X击败玩家Y作为关系,使得存在顶点X和Y,并且存在从Y到X的边。
然后,在处理完所有游戏信息后,您可以在图表上运行DFS,在某个阵列A中记录您无法从中移动更深的节点。 由于您没有指定给定的图形是树,考虑到边缘是有向的,无法保证从任何节点开始的DFS会收敛到单个根,因此您需要保留某种类型的节点列表击败其他节点。
完成初始遍历后,反转所有边,并为林中的每棵树运行DFS,这是您的图形,每个树的根是A中的元素。当您遍历以A [i]为根的树时,在每个节点中记录它相对于根节点A [i]。
所在的深度接下来,根据您对 top 玩家的定义,您可以遍历A中的根,然后尽可能深入到该定义允许的范围内,挑选您遇到的每个元素。如果您需要的最终列表实际上应该对A中不同根的后代节点进行排序,您可以使用深度作为比较标准对列表中的最终结构进行排序。除了我提到的最终排序,因为到目前为止我们所做的都是DFS,这种方法是 O(V + E),V是顶点数,E是边数。如果考虑到不同树中元素的排序,那么你的总体复杂度为 O((V + E)+ VlogV)。
如果你愿意牺牲更多的性能,那么你可以将A中的根连接到全局根R(即将节点R添加到图形和边缘从R到每个A [i])并运行Dijkstra's算法,首先访问深度较小的节点,并基本上将每个被访问节点附加到列表中,直到您认为列表足够大,基于您对顶级玩家的定义。
请注意,如果您在图表中有周期,则无论您是使用DFS还是Dijkstra进行最终遍历,此解决方案都不起作用。然而,通过使用具有正权重的边缘,它可以适用于具有多个匹配的玩家。从X到Y的边缘,权重k将表示X击败Y的次数,在使用DFS遍历期间更新节点深度时将考虑到这一点。