【问题标题】:Create matrix with entries unique to row and column R创建具有对行和列 R 唯一的条目的矩阵
【发布时间】:2018-11-08 22:58:44
【问题描述】:

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

有没有什么有效的方法可以在不创建所有 120C5 矩阵然后找到合适的矩阵的情况下做到这一点?

谢谢!

【问题讨论】:

  • sapply(1:5, function(i) (1:5 - i) %% 5 + 1)。 (这是一个简单的问题,但对于未来的问题,请付出一些努力。这不是免费的代码服务。如果这是家庭作业,我希望我得到一个“A”。)
  • 您好,抱歉,我需要找到所有可能的组合,而不仅仅是一个 - 抱歉没有说清楚。
  • 这是一个有趣的问题,我可能会搁置一段时间。但是,对于 SO 上的快速 Q/A 来说太多了,因此您可能无法得到回复。或者你可能,谁知道呢。但这将比大多数问题(我看到的)通常需要的更多努力。祝你好运。
  • 这样的矩阵被称为拉丁方阵。请参阅stackoverflow.com/a/49203589/1320535 了解如何生成随机数。生成所有这些确实并不简单,请参阅en.wikipedia.org/wiki/Latin_square#Algorithms
  • 我同意@r2evans。这是一个计算上有趣的问题。我强烈建议您自己先尝试一下。你可以在网上找到资源,甚至here on SO。展示解决问题的代码尝试,我可以保证你会得到更好的响应(你也会学到更多)。目前这读起来太像"gimme teh codez"

标签: r matrix


【解决方案1】:

正如我在上面的评论中所说,这种类型的矩阵称为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 

您还可以检查它们是否都是拉丁方格。

【讨论】:

  • 非常令人印象深刻,朱利叶斯!现在我可以关掉我的备用燃烧器了。 (我真的很喜欢list()[rep(...)] 而不是replicate(n,NULL,simplify=F),也...快得多。)
  • @r2evans,谢谢!现在你的评论让我想起了更好更快的东西:vector("list", n)。比 list()[rep(1, n)] 快大约 5 倍。
  • 我已经对前两个进行了基准测试(快 2 OOM),第三个是另一个更快的 OOM(其中n &lt;- gamma(6)*gamma(5))。我不知道为什么我总是忘记稳定的vector 函数...
猜你喜欢
  • 2023-04-04
  • 1970-01-01
  • 2019-05-04
  • 1970-01-01
  • 2021-01-08
  • 1970-01-01
  • 1970-01-01
  • 2010-11-19
  • 2012-09-17
相关资源
最近更新 更多