我想要尺寸为n * n的随机BUT唯一二进制矩阵。
例如,如果n = 5,则存在2 ^(5 * 5)= 33554432个唯一组合(矩阵),这是一个巨大的数字。我只需要1000.这是我目前的方法,但需要很多时间(我买不起,因为我需要在将来增加尺寸)。而且我觉得它是多余的,因为最后我只选择了全数中的1000个随机组合。还有其他方法来处理这个吗?这就是我目前正在做的事情:
我从n * n个变量的数据帧开始,第一行全1,第二行全0:
Length = 25
m <- as.data.frame(matrix(c(rep(0, connections), rep(1,
connections)),ncol=25, byrow = TRUE))
m看起来像这样:
#V1 V2 V3 V4 V5 V6 V7 V8 V9 V10 V11 V12 V13 V14 V15 V16 V17 V18 V19 V20 V21
#V22 V23 V24 V25
#1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
#0 0 0 0 0
#2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
#1 1 1 1 1
接下来,我使用expand.grid
获得所有独特的组合mFull = expand.grid(m) # This takes forever
然后我选择1000个随机行:
mRand = mFull[sample(1:nrow(mFull), 1000,)]
然后我将每一行转换为n * n矩阵,例如,第一行:
mRand[1,]
# V1 V2 V3 V4 V5 V6 V7 V8 V9 V10 V11 V12 V13 V14 V15 V16 V17 V18 V19 V20
#V21 V22 V23 V24 V25
#21788869 1 1 0 1 1 1 0 0 1 1 1 0 0 0 0 1 1 1 0
#0 1 1 0 1 0
将其转换为矩阵:
> matrix(mRand[1,], nrow = 5, byrow = TRUE)
[,1] [,2] [,3] [,4] [,5]
[1,] 1 1 0 1 1
[2,] 1 0 0 1 1
[3,] 1 0 0 0 0
[4,] 1 1 1 0 0
[5,] 1 1 0 1 0
是否有人建议采用更有效的解决方案?
答案 0 :(得分:0)
我建议您完全随机生成矩阵,并检查每个新矩阵是否已经创建。如果没有,丢弃它。
只要可能的矩阵数量远大于所需矩阵的数量,这种方法效果很好,否则可能会很慢。
示例代码:
randomMatrix <- function(n) matrix(as.numeric(runif(n^2) > 0.5), ncol = n) # generates random binary square matrix of size n x n
m <- 1000 # number of matrices needed
res <- vector("list", m) # stores the result
i <- 1 # index of next matrix
while (i <= m) {
cand <- randomMatrix(5)
## check if the candidate is distinct from all matrices in res
if (!any(sapply(res, function(x) identical(x, cand)))) {
res[[i]] <- cand
i <- i + 1
}
}
如果你真的遇到速度问题(我怀疑),你可以使用一些哈希来加速比较。例如,您可以存储每个矩阵的行和列总和,并且只有在总和重合时才测试相等性。
答案 1 :(得分:0)
只要可能的矩阵数适合整数,就可以将每个矩阵编码为整数的二进制表示。因此,如果您在没有替换的情况下对整数进行采样,然后将这些整数转换为二进制矩阵,那么您就完成了。
这里有几个功能:
binmat <- function(dec,n){
matrix(as.integer(intToBits(dec)[1:(n*n)]),n,n)
}
rbinmats <- function(n,m){
max = 2^(m*m)
stopifnot(max < .Machine$integer.max)
m_decimal = sample(max,n)-1
lapply(m_decimal, binmat, n=m)
}
binmat
的工作原理如下:
> binmat(123,3)
[,1] [,2] [,3]
[1,] 1 1 1
[2,] 1 1 0
[3,] 0 1 0
这只是123(001111011)的9位二进制表示,写成矩阵(向后)。
rbinmats
只是采样并创建此形式的随机矩阵:
> rbinmats(4,3)
[[1]]
[,1] [,2] [,3]
[1,] 1 0 1
[2,] 0 1 0
[3,] 0 1 0
[[2]]
[,1] [,2] [,3]
[1,] 0 0 0
[2,] 1 1 0
[3,] 1 1 1
[[3]]
[,1] [,2] [,3]
[1,] 1 1 1
[2,] 0 1 0
[3,] 0 1 0
[[4]]
[,1] [,2] [,3]
[1,] 1 0 0
[2,] 0 0 1
[3,] 1 0 1
这里它从0到(2 ^ 9)-1采样4个整数,没有替换,并对它们进行编码,因此它们将是唯一的。
5x5似乎是你可以用整数做的最大值,因为2 ^(5 * 5)小于max int,但是2 ^(6 * 6)isn&t; t。除非有64位数字的方法。