并行/集群中图节点分组的有效算法

时间:2013-06-28 10:08:08

标签: algorithm graph

我正在考虑将玩家加入游戏的有效算法。由于将有大量的播放器,算法应该是异步的(即可扩展到集群中的任何数量的机器)。 有详细信息: 想象一下,有一个无向图(每个节点都是一个玩家)。玩家之间的每个边缘意味着玩家可以参与同一个游戏,如果没有边缘他们就不能参与。我需要实现按照以下标准对玩家进行分组的算法:

  • 每个玩家都有一个州:"等待游戏"或者"在游戏"。只有等待的玩家才能被归为游戏
  • 每个游戏都有最小和最大数量的玩家

我对实施的看法: 该图将通过NoSQL数据库(来自集群中的不同机器)进行存储和访问。还没有特定的架构(任何建议?)。此外,锁定对单个玩家的访问权限(也就是悲观锁定)不是一种选择,因为它可能会减慢试图访问/收集同一玩家的其他进程的潜在瓶颈。

我的问题是:有人实施过这样的算法吗?有什么建议吗?

PS:我已经有了创意,但首先想讨论/检查人们的建议。

谢谢!

EDIT1: 回应Thomas Jungblut: 使用游戏插槽是一个有趣的想法,但(一旦我理解正确)它可能在某些情况下不起作用。福克斯的例子:每场比赛应该有3名球员。新的6个玩家(让我们称之为A B C D E F,见exaple 1)按顺序逐个进入图形/队列:A,B,E,F,C,D。

example 1

结果只会创建一个游戏(A,B,C),加上2个带空插槽的游戏:(D)和(E,F)。但最佳应该是2场比赛:(A,C,D)和(B,E,F),对吧?

1 个答案:

答案 0 :(得分:3)

我怀疑您没有正确考虑业务要求。

与任意条件“最佳匹配”的短语对我来说是NP-complete。你不会为那些拥有大量数据集的人找到一个有效的精确解决方案,只是一个合理的近似值。

次优匹配的成本是多少?你不得不等待一段时间才能找人玩。不是真的有问题。

我会实现像这样简单的东西。有你正在设置的游戏队列。每个进来的人试图进入第一场比赛,第二场比赛失败,第三场失败,依此类推。如果找不到任何内容,则在队列末尾创建一个新游戏。游戏在达到最大尺寸时开始,或者在达到最小尺寸后达到固定时间。当游戏开始时,它将从队列的前面移除。

有了这个决定,为什么你认为会有一百万活跃的球员?

如果是因为你是一个有很大梦想的创业公司,我强烈建议你,你需要专注于尽可能高效地解决你已知的问题。在不太可能的成功事件中(严重的是,您是否看过统计数据?),您可以稍后进行扩展。而只有解决实际问题才能大幅度提高你从骇人听闻到穷人的成功几率。 (我并不是要令人沮丧。但是,创业梦的确是很难获得疯狂的回报。你采取的每一个行动都应该着眼于提高赔率。)

如果您是一家有充分理由相信自己能够获得这些数据的知名游戏公司,请继续阅读。

我不应该提到的显而易见的注意事项是,您需要以相对较快的语言实现性能关键位。例如,如果您正在编写Python,那么用Java,Go或C ++编写这将是一件好事。

接下来,第一件不会扩展的是玩家信息。所以分发它。这样做会减慢你的“适合游戏的玩家”检查。因此,添加每个游戏锁定,并异步分配该计算。限制在放弃和创建新游戏之前尝试进入游戏的难度。

下一个瓶颈是游戏匹配计算。因此,继续将“新游戏”分发给多台机器。现在玩家出现,获得要检查的游戏的中央列表,开始检查它们。为了避免瓶颈,玩家应该随机排序等待游戏列表。

净瓶颈是要求该列表。该列表主要是只读的,因此您只需使用Redis的复制实例。写入(对于新游戏和标记游戏开始)可以掌握,读取可以根据需要分布在尽可能多的机器上。玩家将点击Redis的随机副本,获取列表,随机排序。

如果你达到这个等级,我会感到震惊。如果你超过它,我会留下接下来的步骤,比如将Redis分割给你。

随机说明。这是一个很好的面试问题。 “设计这个简单的东西。让它缩放。让它更大规模。让它更大规模。”如果你真的在寻找一个了解分布式性能的人,这是一个很好的测试。 (但只有当面试官能从坏的答案中说出好的时候。)