说我有一个矢量,
vec <- c(rep(1,4),rep(2,4),rep(3,4),rep(4,4),rep(5,4),rep(6,4),rep(7,4),rep(8,4),rep(9,4))
我安排了一个矩阵6x6。
mat <- matrix(vec,6,byrow=T)
[,1] [,2] [,3] [,4] [,5] [,6]
[1,] 1 1 1 1 2 2
[2,] 2 2 3 3 3 3
[3,] 4 4 4 4 5 5
[4,] 5 5 6 6 6 6
[5,] 7 7 7 7 8 8
[6,] 8 8 9 9 9 9
我希望将这些数字改组,使得它们对于每一行和每列都是唯一的。或者换句话说,任何行或列中都不得有重复数字。
矢量的长度,矢量的元素,矩阵的行数和列数都是固定的。唯一可以改变的方面是数字的位置。
我如何计算解决这个问题?
以下是一个可能的正确结果(手动完成)。请注意,没有行或列有任何重复的数字。
res <- matrix(c(3,1,2,5,7,8,6,8,5,2,9,4,8,6,7,4,3,5,2,9,3,1,6,7,1,4,9,7,5,6,4,2,1,9,8,3),nrow=6,byrow=T)
[,1] [,2] [,3] [,4] [,5] [,6]
[1,] 3 1 2 5 7 8
[2,] 6 8 5 2 9 4
[3,] 8 6 7 4 3 5
[4,] 2 9 3 1 6 7
[5,] 1 4 9 7 5 6
[6,] 4 2 1 9 8 3
table(res)
res
1 2 3 4 5 6 7 8 9
4 4 4 4 4 4 4 4 4
答案 0 :(得分:1)
首先,有一种更好的方法来获取矢量。这将减少打字并使您的代码更清晰:
vec <- rep(1:8, each=4)
mat <- matrix(vec, ncol=6, byrow=T)
接下来,请注意您要按行排序元素的唯一排序。也就是说,您需要元素的permutations。 N
元素的唯一排列数为N!
。我们可以在R
中计算出这个数字:
factorial(length(unique(vec)))
# [1] 40320
这比您需要的数字排序更多。 (看起来你只想要6.)假设你想绘制一些随机排序,让我们从可能的40320中抽取6个数字:
set.seed(3931) # this makes the example exactly reproducible
rows <- sample.int(40320, 6)
rows
# [1] 36601 24136 5713 23405 25328 32973
从这里开始,为了获得实际的排列,我们将使用R
中的permute库。由于排列总数很大,我们必须将maxperm
参数设置为大于其默认值(9999
,我收集):
library(permute)
out <- allPerms(unique(vec), control=how(maxperm=41000))[rows,]
out
# [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8]
# [1,] 8 2 7 1 3 4 6 5
# [2,] 5 7 4 1 6 8 2 3
# [3,] 2 1 8 6 3 4 7 5
# [4,] 5 6 4 1 2 8 7 3
# [5,] 6 1 3 2 5 7 4 8
# [6,] 7 4 6 5 8 2 3 1
我对误读这个问题表示歉意。 N
元素的排列数量仅为r
时使用N!/r!
。这是一个简单的计算:
factorial(length(unique(vec))) / factorial(length(unique(vec))-6)
# [1] 20160
我不清楚如何让allPerms()
使用少于所有元素。这是一个简单的解决方案:
library(permute)
out <- allPerms(unique(vec), control=how(maxperm=41000))[rows,1:6]
out
# [,1] [,2] [,3] [,4] [,5] [,6]
# [1,] 8 2 7 1 3 4
# [2,] 5 7 4 1 6 8
# [3,] 2 1 8 6 3 4
# [4,] 5 6 4 1 2 8
# [5,] 6 1 3 2 5 7
# [6,] 7 4 6 5 8 2