使用行和列R唯一的条目创建矩阵

时间:2018-11-08 22:58:45

标签: r matrix

我需要找到R中每一行和每一列唯一的所有可能的整数1-5的5x5矩阵(想象一个数独)。

在没有创建所有120C5矩阵然后找到合适的矩阵的情况下,是否存在任何有效的方法?

谢谢!

1 个答案:

答案 0 :(得分:3)

正如我在上面的评论中所说,这种类型的矩阵称为Latin squares

首先,我们already know有56个所谓的缩小的拉丁方和161280个所有大小为5的拉丁方。缩小的拉丁方使得第一列和第一行都只有1 ,2、3、4、5(按此顺序)。给定那些缩小的拉丁方格,只要容易(只要大小不大于5)就可以生成所有拉丁方格:排列除第一个以外的所有行,并排列所有列。因此,正如预期的那样,161280 = 5!* 4!* 56。

通过限制第一行和第一列,可以生成4!* 3!* 2!= 288个矩阵,并检查其中56个是拉丁方。但是,我将跳过该列表,并从here中获取他们的列表。

首先,我们读取并重新排列数据

reduced <- read.table("http://users.cecs.anu.edu.au/~bdm/data/reduced5.txt", head = FALSE, colClasses = "character")
reduced <- lapply(1:nrow(reduced), function(r) matrix(as.numeric(unlist(strsplit(unlist(reduced[r, ]), ""))) + 1, 5))
length(reduced)
# [1] 56

现在让我们生成所有5个!和4! 1,2,3,4,5和1,2,3,4的排列。

library(combinat)
perms5 <- permn(1:5)
perms4 <- permn(1:4)

最后,我们遍历所有缩小的拉丁方格并以各种可能的方式对其进行置换

allLS <- sapply(reduced, function(m) {
  LS <- vector("list", gamma(6) * gamma(5))
  for(i in 1:gamma(5))
    for(j in 1:gamma(6))
      LS[[(i - 1) * gamma(6) + j]] <- m[perms4[[i]] + 1, perms5[[j]]]
  LS
})

只需几秒钟,我们便得到结果

length(allLS)
# [1] 161280

很容易验证它们是否都不同

table(table(sapply(allLS, paste0, collapse = "")))
#      1 
# 161280 

,您还可以检查它们是否均为拉丁方块。