基本上,您要的是一个“半随机”事件生成器,该生成器生成具有以下属性的事件:
预先指定每个事件发生的平均速率。
同一事件连续发生两次的可能性要比随机发生的可能性小。
这些事件不是完全可预测的。
一种方法是首先实现一个满足目标1和2 的非随机事件生成器,然后添加一些随机性以满足目标3。
对于非随机事件生成器,我们可以使用简单的抖动算法。具体而言,令p 1,p 2,...,p n为事件1到n的相对似然性,令s = p 1 + p 2 + ... + p n为权重之和。然后,我们可以使用以下算法生成一个非随机的,最大均匀分布的事件序列:
最初,让e 1 = e 2 = ... = e n = 0。
要生成一个事件,每增加Ë 我由p 我,和输出事件ķ针对é ķ是最大的(破领带任何你想要的)。
递减Ë ķ通过小号,并从步骤2重复。
例如,给定三个事件A,B和C,且p A = 5,p B = 4和p C = 1,此算法将生成类似于以下输出序列的内容:
A B A B C A B A B A A B A B C A B A B A A B A B C A B A B A
请注意,这30个事件的序列如何精确地包含15个As,12 B和3C。它的分布不是很理想-可以连续出现两次连续出现两个As的情况,这是可以避免的-但它接近了。
现在,要为该序列添加随机性,您可以使用几种(不一定是互斥的)选项:
您可以按照菲利普的意见,并保持的“甲板” ñ即将举行的活动,对于一些适当大小的数ñ。每次您需要生成事件时,都从平台中选择一个随机事件,然后将其替换为上面的抖动算法输出的下一个事件。
将其应用于上面的示例(N = 3)将产生例如:
A B A B C A B B A B A B C A A A A B B A B A C A B A B A B A
而N = 10会产生更多随机现象:
A A B A C A A B B B A A A A A A C B A B A A B A C A C B B B
请注意,由于改组,常见事件A和B如何以更多的运行结束,而罕见的C事件仍然间隔良好。
您可以将一些随机性直接注入到抖动算法中。例如,代替在步骤2中将e i增加p i,可以将其增加p i ×random(0,2),其中random(a,b)是a和b之间的均匀分布的随机数;这将产生如下输出:
A B B C A B A A B A A B A B A A B A A A B C A B A B A C A B
或者您可以将e i增加p i + random(− c,c),这将产生(对于c = 0.1× s):
B A A B C A B A B A B A B A C A B A B A B A A B C A B A B A
或者,对于c = 0.5× s:
B A B A B A C A B A B A A C B C A A B C B A B B A B A B C A
请注意,与乘法事件相比,加性方案对罕见事件C的影响比对公共事件A和B的影响要大得多;这可能是或可能不希望的。当然,您还可以使用这些方案的某种组合,或者对增量进行任何其他调整,只要它保留e i的平均增量等于p i的属性即可。
或者,您有时可以通过将选定的事件k替换为随机事件k(根据原始权重p i选择)来扰动抖动算法的输出。只要您在步骤3中也使用与在步骤2中输出相同的k,则抖动处理仍将趋于使随机波动趋于均匀。
例如,这是一些示例输出,随机选择每个事件的可能性为10%:
B A C A B A B A C B A A B B A B A B A B C B A B A B C A B A
这是一个示例,每个输出有50%的机会是随机的:
C B A B A C A B B B A A B A A A A A B B A C C A B B A B B C
你还可以考虑喂纯粹随机和抖动事件的搅和成甲板/混合池,如上所述,或者通过选择随机抖动算法ķ随机,由作为称重ë 我秒(处理负权重为零)。
附言 以下是一些完全随机的事件序列,具有相同的平均速率,以进行比较:
A C A A C A B B A A A A B B C B A B B A B A B A A A A A A A
B C B A B C B A A B C A B A B C B A B A A A A B B B B B B B
C A A B A A B B C B B B A B A B A A B A A B A B A C A A B A
切线:由于评论中存在一些争论,即对于基于甲板的解决方案是否有必要在甲板重新装满之前让其清空,我决定对几种甲板填充策略进行图形比较:
生成半随机硬币翻转的几种策略的图解(平均头与尾的比例为50:50)。横轴是翻转次数,纵轴是与期望比率的累计距离,以(头-尾)/ 2 =头-翻转/ 2来衡量。
图中的红线和绿线显示了两种非基于甲板的算法进行比较:
- 红线,确定性抖动:偶数结果始终为正面,奇数结果始终为反面。
- 绿线,独立的随机翻转:每个结果都是独立随机选择的,正面有50%的机会是正面,背面有50%的机会。
其他三行(蓝色,紫色和青色)显示了三种基于套牌的策略的结果,每种策略都是使用40张牌组成的套牌实施的,最初由20张“正面”牌和20张“尾部”牌填充:
- 蓝线,空时填满:随机抽牌,直到牌组为空,然后用20张“正面”卡和20张“尾部”卡重新装满卡组。
- 紫色线,半空时填满:随机抽牌,直到牌组剩下20张牌;然后用10张“正面”卡和10张“尾部”卡加满卡座。
- 青色线条,连续填充:随机抽牌;偶数平局将立即替换为“正面”卡,奇数平局将替换为“尾部”卡。
当然,上面的图只是一个随机过程的单个实现,但是它具有一定的代表性。尤其是,您可以看到所有基于卡片组的过程都具有有限的偏差,并且与红色(确定性)线相当接近,而纯随机的绿色线最终会消失。
(实际上,蓝线,紫线和青色线偏离零的偏差严格受牌组大小限制:蓝线的偏离距离永远不会超过10步,紫色线只能偏离零距离15步。 ,而青色线最多可以从零开始漂移20步。当然,实际上,任何一条线实际上都不可能达到其极限,因为如果它们走得太远,它们很可能会趋近于零。关闭。)
乍一看,不同的基于套牌的策略之间没有明显的区别(尽管平均而言,蓝线与红线保持一定距离,而青色线与红线保持一定距离),但仔细检查蓝线确实揭示了一种独特的确定性模式:每40画一次(用虚线的灰色垂直线标记),蓝线恰好与红线零交汇。紫色和青色线不受严格限制,并且可以随时远离零。
对于所有基于平台的策略,即保持它们的变化为界的重要特点是,虽然卡的事实,从抽取的随机甲板,甲板被重新填充确定性。如果用于填充卡组的卡牌本身是随机选择的,那么所有基于卡组的策略将与纯随机选择(绿线)无法区分。