【发布时间】:2011-10-21 10:50:00
【问题描述】:
我有 400 个球,其中 100 个是红色的,40 个是黄色的,50 个是绿色的,60 个是蓝色的,70 个是紫色的,80 个是黑色的。 (相同颜色的球是相同的)
我需要一个高效的洗牌算法,这样洗牌后,球在一个列表中,并且
任何连续的 3 个球的颜色都不相同。例如,我不能有“红、红、红、黄……”
而且,所有排列都“均等地”发生。 (好吧,如果效率与公正性的权衡足够好,我不介意效率高于公正性)。
我尝试改编Fisher-Yates-Knuth,但结果并不理想。
为什么 Fisher-Yates 不够好?由于 FY 采用蒙特卡洛逆变换。并且输出分布对相同颜色的球的处理方式不同,即它会根据我的需要产生有偏差的结果。
而且,幼稚的想法是从整个空间中过滤/回溯所有不良排列。当限制非常强时,例如,如果我们只有 300 个球,其中 100 个是红色的,那么在获得适当的排列之前会出现太多的回溯/失败。
所以,最终,我希望能够遍历所有好的排列。但是,由于有效排列的数量太多,我只能随机抽取其中一些。
【问题讨论】:
-
您是如何尝试适应 Fisher-Yates-Knuth 的,结果如何不“理想”?
-
我认为用一个幼稚的解决方案你最终会回溯以确保你的规则成立。想象一下,如果您还剩下三个球可以选择,并且三个球的颜色相同;那么你可以用一个简单的线性算法,不能保证没有三个连续的颜色是一种颜色。
-
@joey:我之前尝试过使用回溯,但是当输入限制太强时,算法会花费大量时间回溯,即大量失败和重试
-
@colinfang 澄清问题:您是否尝试实际生成 400 个项目的特定“随机播放”(恰好与无三合一约束匹配),或者您是否尝试提出三个球的随机组合,其中特定组合的概率与“连续随机选择三个球,就好像它们来自有效的 [实际] 洗牌一样”。
标签: c# combinations