4x4 矩阵函数的网格生成

Grid Generating for 4x4 Matrix Function

我有一个列总和和行总和的向量,我需要确定构成这些行总和和列总和的先验矩阵。浏览完之前的问题后,我发现过去的这一页让我在这方面有了一个良好的开端--

https://codegolf.stackexchange.com/questions/150012/enumerate-all-possible-grids-of-integers-with-constraints

但是,我的目标与上面提供的代码略有不同,因为我有一个 4x3 矩阵而不是 3x3 矩阵。我试图将 r 函数修改为 4x4 函数——我想我可以在我的总和中添加一个 0,这将使其易于扩展。该函数看起来像这样--

grid_gen4 <- function(S){
  for(m in unique(combn(rep(0:max(S),16),16,matrix,F,4,4)))if(all(c(rowSums(m),colSums(m))==S))print(m)
}

您可以在上面的 link 页面上看到优先功能。

每当我运行我的第一个向量

这个函数
c(12,2,3,3,5,4,11,0)

我收到一个错误--

Error in vector("list", count) : vector size cannot be NA
In addition: Warning message:
In combn(rep(0:max(S), 16), 16, matrix, F, 4, 4) :
  NAs introduced by coercion to integer range

关于如何解决这个问题有什么建议吗?

此外,之前 link 运行 中的代码,但它有点慢,因为我需要在数百个向量上执行此操作。我也很好奇有没有人有什么建议可以让它更快?

这是 partitions 包的一种方法:

您不需要添加额外的 0。

library(partitions)
findMatrix <- function(target){
cols <- lapply(target[1:3],function(x)compositions(x,4))
grid <- expand.grid(lapply(cols,function(x)seq(ncol(x))))
good <- apply(grid,1,function(x){
  all(rowSums(cbind(cols[[1]][,x[1]],cols[[2]][,x[2]],cols[[3]][,x[3]])) == target[4:7])
  })  
apply(grid[good,],1, function(x)list(cbind(cols[[1]][,x[1]],cols[[2]][,x[2]],cols[[3]][,x[3]])))
}

findMatrix(c(12,2,3,3,5,4,11))
#list()

没有满足这些条件的矩阵。

这里有一个工作向量的例子:

findMatrix(c(1,1,0,0,1,1,0))
#$`7`
#$`7`[[1]]
#     [,1] [,2] [,3]
#[1,]    0    0    0
#[2,]    0    1    0
#[3,]    1    0    0
#[4,]    0    0    0
#
#
#$`10`
#$`10`[[1]]
#     [,1] [,2] [,3]
#[1,]    0    0    0
#[2,]    1    0    0
#[3,]    0    1    0
#[4,]    0    0    0

要了解其工作原理,请考虑以下内容:

compositions(4,4)                                                                        
#[1,] 4 3 2 1 0 3 2 1 0 2 1 0 1 0 0 3 2 1 0 2 1 0 1 0 0 2 1 0 1 0 0 1 0 0 0
#[2,] 0 1 2 3 4 0 1 2 3 0 1 2 0 1 0 0 1 2 3 0 1 2 0 1 0 0 1 2 0 1 0 0 1 0 0
#[3,] 0 0 0 0 0 1 1 1 1 2 2 2 3 3 4 0 0 0 0 1 1 1 2 2 3 0 0 0 1 1 2 0 0 1 0
#[4,] 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 3 3 3 4

一旦我们枚举了加起来等于给定数字的所有可能列,我们就可以使用 expand.grid 遍历所有可能的列组合,看看它们是否有 rowSums 等于我们的约束.