回溯算法:生成满足行列和约束的所有二进制矩阵
寻找高效回溯算法生成所有满足行列和约束的二进制矩阵
这是一个问题的后续问询。原问题目标是生成满足行和、列和约束的随机二进制矩阵,而我需要获取所有符合要求的矩阵,而非单个随机实例。我认为这类约束问题可通过回溯算法解决,但自行实现的版本效率极低,尤其是在约束向量较长或需填充大量1时。希望能学习更高效、优雅的回溯解决方案,感谢!
我编写了以下代码,用于搜索所有满足行列和约束的矩阵:
f <- function(rsum, csum) { # size of desired output matrix nr <- length(rsum) nc <- length(csum) if (sum(rsum)!=sum(csum)) { stop("Sum of rsum and csum are NOT equal!") } else { N <- sum(rsum) } # recursion function that searches all possible matrices under rsum/csum constraints helper <- function(k) { if (k == 1) { mat <- matrix(0,nr,nc) return(lapply(1:(nr*nc+1-N),replace, x = mat, values = 1)) } lst <- Recall(k - 1) res <- c() for (m in lst) { l <- c(m) zs <- which(l == 0) zs <- zs[zs >= max(which(l == 1))] for (z in zs) { ll <- matrix(replace(l, z, 1),nr,nc) if (all(c(rowSums(ll) <= rsum,colSums(ll) <= csum)) && (!list(ll) %in% res)) { res <- c(res, list(ll)) } } } res } # run helper, return a list of all possible matrices helper(N) }
运行以下示例:
rsum <- c(3, 2, 2, 1) csum <- c(2, 2, 2, 2) output <- f(rsum, csum)
可得到包含48个矩阵的列表(示例部分矩阵如下):
> out [[1]] [,1] [,2] [,3] [,4] [1,] 1 1 1 0 [2,] 1 1 0 0 [3,] 0 0 1 1 [4,] 0 0 0 1 [[2]] [,1] [,2] [,3] [,4] [1,] 1 1 0 1 [2,] 1 1 0 0 [3,] 0 0 1 1 [4,] 0 0 1 0 ...(其余矩阵省略)
内容的提问来源于stack exchange,提问作者ThomasIsCoding
相关产品推荐
相关产品推荐

