【发布时间】:2012-08-01 18:56:17
【问题描述】:
我一直在阅读 Game Coding Complete(第 4 版),但我在理解“Grab Bag of Useful Stuff”中的“Pseudo-Random Traversal of a Set”路径时遇到了一些问题" 第 3 章中的部分。
您有没有想过 CD 播放器上的“随机”按钮是如何工作的?它会随机播放您 CD 上的每首歌曲,而不会将同一首歌曲播放两次。这是一个非常有用的解决方案,可以确保游戏中的玩家在有机会再次看到相同的特征之前看到最广泛的特征,例如对象、效果或角色。
在此描述之后,它继续讨论我尝试在 Java 中实现但无法成功复制的 C++ 实现。它还简要描述了它的工作原理,但我也不明白。
我找到了this StackOverflow 对类似问题的回答,但不幸的是,答案中的示例链接已失效,我也不理解维基百科的文章,尽管关于它的功能的描述似乎描述了我我正在寻找。
明确地说,我不是寻找一种随机重新排序收藏的方法。我正在寻找一种在重复之前从集合中随机选择一个元素的方法。
有人可以解释这种行为是如何工作的并提供一个 Java 示例吗?谢谢!
[编辑]我认为在此处摘录实现可能很有用,以帮助解释我在说什么。
这是它的工作原理。通过选择三个大于零的随机值来计算跳过值。这些值成为二次的系数,域值 (x) 被设置为集合的序数值:
Skip = RandomA * (members * members) + (RandomB * members) + RandomC
有了这个跳过值,您可以使用这段代码以伪随机顺序遍历整个集合一次:
nextMember += skip;
nextMember %= prime;
skip 的值远大于集合中的成员数,以至于所选值似乎是随机跳过的。当然,这段代码在 while 循环中,用于捕获所选值大于您的设置但仍小于质数的情况。
【问题讨论】:
-
因此您希望项目以随机顺序排列,而不是重新排序。请问为什么?
-
我试图理解书中的例子。此外,如果我正确理解了发生的情况,则 N 越大,对 N 个对象的集合进行洗牌的成本就会越高。
-
@Baz 假设您的数据是一个具有有意义顺序但其成员没有自然顺序的列表(从迭代器的角度来看),您不想丢失该顺序提供随机播放模式。
-
Collections.shuffle()以线性时间运行。您无法通过随机选择获得较低的运行时间,因为每个对象都必须仅选择一次。如果您不想丢失原始订单,请尝试 user1515834 的答案。 -
嗯,我不知道 'Collections.shuffle()' 在线性时间内运行。但是,我只是关心理解书中的示例是如何工作的,这就是为什么我提到我不对重新排序集合感兴趣。