我正在尝试在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]
次。将使用许多组|
, 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]
。下面显示了一组6次运行的示例。 (N = R/G = 6/3 = 2
个字符分开组。组内的顺序无关紧要,因为组内的试订单将在以后随机化。组在构建运行之外没有任何意义。一旦运行构建,它将被视为一个凝聚力单元。)
[s1, s2, …, s9]
请注意,每个试验每次运行(行)一次,每组R = 10
次(“|”分隔列)。每个列都是一个插槽T >= 320
,每个插槽包含每次运行的不同试用版。我的算法实现需要T = 20
和T = 320
。
我尝试了3种不同的算法,所有这些算法都完全失败了(使用G
,小)或者它们不能很好地扩展(使用G = max(gcd(d(R), T))
需要很长时间)。我发现gcd
使用d
,其中N
是两个参数之间的“最大公约数”,T = 20
是“除数”函数,它列出了所有除数输入(不包括输入本身)。我的算法的简要说明:
1。创建随机试订单作为每次运行的原型(每个运行的相同随机原型)。对于每次运行,通过每个插槽并在随机选择的不同插槽中切换那里的试验并进行试验(假设两个试验都允许占用各自的新插槽,考虑到任何给定试验可以出现在同一试验中的最大次数小组,N
)。因为随机化最终导致不存在切换的情况,所以在任何这种情况发生的情况下,重新启动算法直到找到最终解决方案。这适用于tmpdf <- data.frame(table(df2$street, df2$house))
names(tmpdf) <- c("street", "house", "member_count")
df1 <- merge(df1, tmpdf, by = c("street", "house"), all.x = TRUE)
通常不到10秒,但很快变得难以处理。
2。对于每次试用,请仔细检查每次试用并随机挑选一个此试用版仍然需要并且仍然可以加入的群组(该群组不适用于该次试用,并且比同一个试验中SELECT t.id
,t.name
,t.age
,t.modified
FROM (
SELECT id
,name
,age
,modified
,ROW_NUMBER() OVER (
PARTITION BY id ORDER BY unix_timestamp(modified,'yyyy-MM-dd hh:mm:ss') DESC
) AS ROW_NUMBER
FROM test
) t
WHERE t.ROW_NUMBER <= 1;
的所有试验都超过了这个试验中的unix_timestamp(modified,'yyyy-MM-dd hh:mm:ss')
。此算法还会导致无选择的情况,因此在卡住时也会重新启动。该算法需要很长时间才能收敛。
3. 对于每次运行,将每个试验分配到一个组,首先分配具有最少分配组数的试验。这个算法也会卡住,也需要很长时间。
如果您愿意,我可以为这些实现提供Matlab代码。
理想情况下,我想要一个确定性算法,找到每个唯一的组合(尽管我不知道有多少存在),我会选择每次使用的随机分组。任何有关此问题的帮助将不胜感激。
答案 0 :(得分:1)
对于参数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)告诉您如何随机生成Latin Squares。我没有看过这个,但也许你可以使用这个想法。