我想要生成一个随机的偶合表,其边缘值都是相等的。
最简单的例子是有一个表:
3 3 3 | 9
3 3 3 | 9
3 3 3 | 9
_ _ _
9 9 9 所以sum(r_i) = sum(c_j) =9。我想找到符合这个标准的所有应急表,然后能够分析这组表的一些特性。
有没有一种在R中生成这些表的“简单”方法?
发布于 2014-11-10 20:10:17
你的问题不完全准确。生成随机应变表很容易。找到符合这些标准的所有应急表可能会更困难,因为表的概率是高度不均匀的,并且需要一个非常大的样本来确保所有这些表都有。(有人给出了基于partitions包的确定性枚举的解决方案,但似乎删除了他们的答案.)r2dtable包(核心包)中的stats示例随机表:
只生成一个示例(结果作为列表返回):
set.seed(101)
r2dtable(n=1,r=c(9,9,9),c=c(9,9,9))[[1]]
## [,1] [,2] [,3]
## [1,] 4 3 2
## [2,] 2 4 3
## [3,] 3 2 4你的例子有多大可能?
set.seed(102)
tList <- r2dtable(n=50000,r=c(9,9,9),c=c(9,9,9))将结果转换为字符串以便于比较:
vals <- sapply(tList,function(x) paste(c(x),collapse=""))一共有多少个?
length(unique(vals)) ## 1018Update:一个大得多的示例(n=500000)给出了1276个唯一表。从对称性的角度看,这似乎更有道理,但可能不是完全的--基于对数频率分布,我可能还没有捕捉到更长的尾巴。
事实上,有:这个网页给出了一种计算表数的方法;对于等于9的所有边距,有1540号。
测井频率分布:
plot(log10(rev(sort(table(vals)))),type="l")

最常见的表格:
head(rev(sort(table(vals))))
## vals
## 333333333 342324333 333324342 333342324 423333243 234333432
## 996 626 626 605 596 592(为了获得额外的信用,我应该尝试瓦解对称的情况。)
人人平等的可能性:
mean(vals=="333333333") ## 0.1992确定性方法(我希望所有者将恢复这种方法)从compositions()包开始,它列举了将整数N划分为n组件的所有方法:compositions(9,3)给出了总和为9的所有非负整数集,它代表了应急矩阵中所有可能的行/列。
我仍然在考虑如何使用这些原材料并将它们合并到枚举表:必须至少有1276个表,所以这不仅仅是单个组合的所有排列(这只会给出3!*55=330)。
这是一个开始,但实际上行不通:
library("partitions")
cc <- compositions(9,3)
too.many <- combn(split(cc,col(cc)),3,
FUN=function(x) do.call(cbind,x),
simplify=FALSE) ## 26235
ok <- sapply(too.many,function(x) all(rowSums(x)==9))只有252,好吗?也许我们需要允许这些结果的所有排列(这将允许252*6 = 1512,一个合理的结果.)?
发布于 2014-11-10 19:00:17
这可能是对这个问题的疯狂回答,也是一个疯狂的(也是不完整的)答案。但是,这与你想要的结果有关,而且也是sudoku。所以这很有趣。
library("sudokuAlt")
g <- matrix(as.numeric(makeGame(3,0)), nrow = 9)
colSums(g)
# [1] 45 45 45 45 45 45 45 45 45
rowSums(g)
# [1] 45 45 45 45 45 45 45 45 45基本上,sudoku拼图是你所要寻找的东西的一个具体例子。这还添加了一个约束,即每一行和每列不仅具有相同的边框,而且具有完全相同的元素组合。这个包只实现了9x9、16x16或25x25的谜题,但是您可以查看源代码,看看它们是如何生成谜题的,并且可能会在那里构建一个更通用的解决方案。
https://stackoverflow.com/questions/26849393
复制相似问题