我正在尝试在 Matlab 中构建一个协议,以在框架内随机化实验试验订单,但无法创建有效的算法来做到这一点。
问题
我想管理T
试验次数([t1, t2, t3…]
每个都有不同的参数),并重复这些R
运行[r1, r2, r3…]
。每次运行都将由完全相同的试验组成,但每次运行的顺序是随机的。此外,随机化受到限制,以说明在给定运行中更早或更晚的影响。在所有运行中,每次试验必须在运行的早期、中期和后期发生相同的次数。为此,每次运行都被分成G
组[g1, g2, g3…]
。我想制作一个算法,该算法将生成一组R
随机运行,受到约束,以使每个试验出现在任何运行时间t
的每组中。N=R/G
例子
T = 9
试验[t1, t2,…, t9]
将重复R = 6
运行[r1, r2, …, r6]
。将使用多个组G = 3
、[g1, g2, g3]
、 。下面显示了一组 6 次运行的示例。(|
字符分隔组。组内的顺序无关紧要,因为组内的试验顺序将在以后随机化。组在构建运行之外没有任何意义。一旦构建运行,它将被视为一个有凝聚力的单元。)
s1 s2 s3 s4 s5 s6 s7 s8 s9
r1 = [t1 t2 t3 | t4 t5 t6 | t7 t8 t9]
r2 = [t3 t4 t7 | t2 t6 t8 | t1 t5 t9]
r3 = [t5 t8 t9 | t1 t2 t7 | t3 t4 t6]
r4 = [t2 t4 t6 | t3 t5 t9 | t1 t7 t8]
r5 = [t5 t6 t9 | t1 t7 t8 | t2 t3 t4]
r6 = [t1 t7 t8 | t3 t4 t9 | t2 t5 t6]
请注意,每个试验每次运行(行)出现一次,每组出现一次N = R/G = 6/3 = 2
(“|”分隔列)。每个单独的列都是一个 slot [s1, s2, …, s9]
,每个列包含每次运行的不同试验。我的算法实现需要R = 10
, 和T >= 320
.
我的尝试
我尝试了 3 种不同的算法,所有这些算法都失败了,要么完全失败(使用T = 20
,小),要么它们不能很好地扩展(需要很长时间T = 320
)。我发现G
using G = max(gcd(d(R), T))
,其中gcd
是两个参数之间的“最大公约数”,并且d
是“除数”函数,它列出了输入的所有除数(不包括输入本身)。我的算法的简要说明:
1.为每次运行创建一个随机试用订单作为原型(每次运行相同的随机原型)。对于每次运行,通过每个插槽并在随机选择的不同插槽中切换试验与试验(假设两个试验都允许占用各自的新插槽,因为任何给定试验可以出现在同一位置的最大次数)组,N
)。因为随机化最终会导致不存在任何开关的情况,所以每当这种情况发生时,算法都会重新启动,直到找到最终解决方案。这T = 20
通常在 10 秒内有效,但很快就会变得棘手。
2.对于每个试验,通过每次运行并随机选择该试验仍然需要并且仍然允许加入的组(该组未满员,并且少于N
同一试验在该组中结束一直运行到这个)。这个算法也会导致没有选项存在的情况,所以卡住的时候也会重启。该算法需要很长时间才能收敛。
3.对于每次运行,将每个试验分配到一个组,首先分配具有最少分配组数的试验。这个算法也卡住了,也需要很长时间。
如果您愿意,我可以为这些实现提供 Matlab 代码。
理想情况下,我想要一个确定性算法来找到每个唯一的组组合(尽管我不知道存在多少),并且我会选择一个随机分组来每次使用。任何有关此问题的帮助将不胜感激。