如何创建受约束的随机实验方案?
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 = 10
和 T >= 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) 告诉您如何随机生成拉丁方。我没看过这个,但也许你可以使用其中的一些想法。
我正在尝试在 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 = 10
和 T >= 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) 告诉您如何随机生成拉丁方。我没看过这个,但也许你可以使用其中的一些想法。