如何创建受约束的随机实验方案?

How do I create a constrained, randomized experimental protocol?

我正在尝试在 Matlab 中构建协议以在框架内随机化实验试验顺序,但无法创建有效的算法来执行此操作。

问题

我想管理 T 次试验([t1, t2, t3…],每次都有不同的参数),并重复这些 R 运行s [r1, r2, r3…] .每个 运行 将由完全相同的试验组成,但每个 运行 的顺序是随机的。此外,随机化受到限制,以说明在给定 运行 中早晚出现的影响。在所有 运行 中,每个试验必须在 运行 的早期、中期和晚期发生相同次数。为此,每个 运行 被分成 G[g1, g2, g3…]。我想制作一个算法来生成一组 R 随机 运行s,约束使得每个试验 t 出现在任何 运行 [=19= 的每个组中] 次。

例子

T = 9 试验 [t1, t2,…, t9] 将重复 R = 6 运行 秒 [r1, r2, …, r6]。将使用多个组 G = 3[g1, g2, g3]。下面显示了一组 6 运行s 的示例。 (| 个字符分隔组。组内的顺序无关紧要,因为组内的试验顺序稍后将随机化。组在构建 [=74= 之外没有任何意义。一旦构建了 运行 , 它将被视为一个有凝聚力的单元。)

      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 次(“|”分隔列)。每个单独的列都是一个插槽 [s1, s2, …, s9],每个插槽都包含每个 运行 的不同试验。我的算法实现需要 R = 10T >= 320.

我的尝试

我尝试了 3 种不同的算法,但都失败了,要么完全失败(使用 T = 20,很小),要么无法很好地扩展(使用 T = 320 需要很长时间)。我使用 G = max(gcd(d(R), T)) 找到 G,其中 gcd 是两个参数之间的“最大公约数”,d 是“除数”函数,它列出了输入(不包括输入本身)。我的算法的简要说明:

1. 为每个 运行 创建一个随机试用订单作为原型(每个随机原型相同)。对于每个 运行,遍历每个槽并将那里的试验与随机选择的不同槽中的试验切换(前提是允许两个试验占用各自的新槽,给定任何给定试验可以占用的最大次数出现在同一组中,N)。因为随机化最终会导致不存在开关的情况,所以只要出现这种情况,算法就会重新启动,直到找到最终解决方案。这适用于 T = 20 通常不到 10 秒,但很快就会变得棘手。

2. 对于每个试验,通过每个 运行 并随机选择一个该试验仍然需要并且仍然允许加入的组(该组是那个 运行 没有满员,并且在这个 运行 之前的所有 运行 中,同一个试验中只有不到 N 个)。这个算法也会导致没有选择的情况,所以卡住的时候也是重启。这个算法需要很长时间才能收敛。

3. 对于每个 运行,将每个试验分配到一个组,首先分配分配组数最少的试验。这个算法也是卡死的,也是耗时很长

如果您愿意,我可以为这些实现提供 Matlab 代码。


理想情况下,我想要一个确定性算法来找到每个唯一的组组合(虽然我不知道有多少存在),并且我会 select 每次使用一个随机分组。任何对此问题的帮助将不胜感激。

对于参数 T=3N R=3,这是一种解决方案:

为第一行生成一个随机排列

第二行是第一行的移动,因此第一组中的试验现在位于第二组中,第二组中的试验现在位于第一组中,而之前的试验第三组现在在第一组。

第三行是第二行又顺移了。

所以这个模式是

[t1 t2 t3 | t4 t5 t6 | t7 t8 t9]

[t7 t8 t9 | t1 t2 t3 | t4 t5 t6]

[t4 t5 t6 | t7 t8 t9 | t1 t2 t3]

对于参数T=3N R=3M,我建议你把行分成三组,然后像上面那样生成每组三行。您当然可以在生成后随机排列行。

请注意,您对每组三行使用了不同的排列。例如,如果有 6 行,您最终可能会得到

123 456 789

789 123 456

456 789 123

148 256 379

379 148 256

256 379 148

对此的概括是对整数 N 使用大小为 3N 的 https://en.wikipedia.org/wiki/Latin_square。如果行中的元素数是 3N 的倍数,则将它们分成 3N 块并使用拉丁方来计算产生 3N 行。对于 N=1,这几乎是一样的,因为实际上只有一个第 3 边的拉丁方,但是对于 N=2,第 6 边有 9408 个真正不同的拉丁方,所以随机选择一个实际上是有意义的。另请注意,在同一篇文章中,ref(4) 告诉您如何随机生成拉丁方。我没看过这个,但也许你可以使用其中的一些想法。