固定值不在列和行上重复
Fixed values not repeated over column and row
我想在 R 中创建一个矩阵,其中包含一定数量的变量(例如 1 到 10)。这些变量应该随机分配给行和列,但不应在任何一个中重复(因此数字 1 应该在第 1 行中一次,在第 1 列中一次)!
例如:
1,2,3,4,5,6,7,8,9,10
2,3,4,5,6,7,8,9,10,1
3,4,5,6,7,8,9,10,1,2
4,5,6,7,8,9,10,1,2,3
5,6,7,8,9,10,1,2,3,4
6,7,8,9,10,1,2,3,4,5
7,8,9,10,1,2,3,4,5,6
8,9,10,1,2,3,4,5,6,7
9,10,1,2,3,4,5,6,7,8
10,1,2,3,4,5,6,7,8,9
当然,在那个例子中,数字是递增的,我希望它们是随机的。我尝试了简单的矩阵需求,但我不知道该怎么做。谁能帮忙?提前致谢!
这看起来几乎就像生成一个 Sudoku
网格。下面的代码运行速度非常快,但可以进行一些小的 R
优化:
backtrack = function(n = 10){
x = matrix(NA, ncol = n, nrow = n)
cells = list()
k = 1
for (i in 1:n){
for (j in 1:n){
cells[[k]] = sample(1:n)
k = k + 1
}
}
i = 0
while (i < n*n){
candidates = cells[[i + 1]]
idx = sample(1:length(candidates), 1)
val = candidates[idx]
if (length(candidates) == 0){
cells[[i + 1]] = sample(1:n)
i = i - 1
x[as.integer(i/n) + 1, i %% n + 1] = NA
}
else {
rr = as.integer(i/n) + 1
cc = i %% n + 1
if ((val %in% x[rr, ]) || (val %in% x[, cc])){
candidates = candidates[-idx]
cells[[i + 1]] = candidates
}
else{
x[as.integer(i/n) + 1, i %% n + 1] = val
candidates = candidates[-idx]
cells[[i + 1]] = candidates
i = i + 1
}
}
}
x
}
测试:
set.seed(1) # Please change this
x = backtrack(10)
print(x)
[,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
[1,] 8 10 4 6 9 7 1 2 3 5
[2,] 5 6 9 8 1 10 4 3 2 7
[3,] 10 7 1 2 8 9 5 4 6 3
[4,] 3 9 8 10 6 5 7 1 4 2
[5,] 9 1 6 4 7 3 2 5 10 8
[6,] 1 4 10 3 2 6 8 7 5 9
[7,] 2 8 5 9 10 1 3 6 7 4
[8,] 6 5 2 7 3 4 10 9 8 1
[9,] 4 3 7 1 5 2 6 8 9 10
[10,] 7 2 3 5 4 8 9 10 1 6
any(apply(x, 1, function(r)any(duplicated(r)))) # FALSE
any(apply(x, 2, function(r)any(duplicated(r)))) # FALSE
除非我误解了问题,否则有一种更简单的方法可以创建这个打乱后的矩阵,无需任何循环或复杂的条件语句。
# number of rows and columns
n <- 10
# create ordered rows and columns
ordered.by.row <- matrix(1:n, n, n)
ordered.by.col <- matrix(1:n, n, n, byrow = T)
# offset the rows and columns relative to each other.
# no row or column has a repeated value, but the values are still ordered
offset <- (ordered.by.row + ordered.by.col) %% n + 1
# shuffle the columns, then shuffle the rows, this produces a randomized matrix
# 'shuffle.row' is the final, randomized matrix
set.seed(1222) # change this to change randomization
shuffle.col <- offset[,sample(1:n, n, replace = F)]
shuffle.row <- shuffle.col[sample(1:n, n, replace = F), ]
# verify solution
any(apply(shuffle.row, 1, function(r)any(duplicated(r)))) # FALSE
any(apply(shuffle.row, 2, function(r)any(duplicated(r)))) # FALSE
[,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
[1,] 1 10 6 9 2 8 3 5 7 4
[2,] 3 2 8 1 4 10 5 7 9 6
[3,] 7 6 2 5 8 4 9 1 3 10
[4,] 9 8 4 7 10 6 1 3 5 2
[5,] 10 9 5 8 1 7 2 4 6 3
[6,] 2 1 7 10 3 9 4 6 8 5
[7,] 8 7 3 6 9 5 10 2 4 1
[8,] 6 5 1 4 7 3 8 10 2 9
[9,] 5 4 10 3 6 2 7 9 1 8
[10,] 4 3 9 2 5 1 6 8 10 7
我想在 R 中创建一个矩阵,其中包含一定数量的变量(例如 1 到 10)。这些变量应该随机分配给行和列,但不应在任何一个中重复(因此数字 1 应该在第 1 行中一次,在第 1 列中一次)!
例如:
1,2,3,4,5,6,7,8,9,10
2,3,4,5,6,7,8,9,10,1
3,4,5,6,7,8,9,10,1,2
4,5,6,7,8,9,10,1,2,3
5,6,7,8,9,10,1,2,3,4
6,7,8,9,10,1,2,3,4,5
7,8,9,10,1,2,3,4,5,6
8,9,10,1,2,3,4,5,6,7
9,10,1,2,3,4,5,6,7,8
10,1,2,3,4,5,6,7,8,9
当然,在那个例子中,数字是递增的,我希望它们是随机的。我尝试了简单的矩阵需求,但我不知道该怎么做。谁能帮忙?提前致谢!
这看起来几乎就像生成一个 Sudoku
网格。下面的代码运行速度非常快,但可以进行一些小的 R
优化:
backtrack = function(n = 10){
x = matrix(NA, ncol = n, nrow = n)
cells = list()
k = 1
for (i in 1:n){
for (j in 1:n){
cells[[k]] = sample(1:n)
k = k + 1
}
}
i = 0
while (i < n*n){
candidates = cells[[i + 1]]
idx = sample(1:length(candidates), 1)
val = candidates[idx]
if (length(candidates) == 0){
cells[[i + 1]] = sample(1:n)
i = i - 1
x[as.integer(i/n) + 1, i %% n + 1] = NA
}
else {
rr = as.integer(i/n) + 1
cc = i %% n + 1
if ((val %in% x[rr, ]) || (val %in% x[, cc])){
candidates = candidates[-idx]
cells[[i + 1]] = candidates
}
else{
x[as.integer(i/n) + 1, i %% n + 1] = val
candidates = candidates[-idx]
cells[[i + 1]] = candidates
i = i + 1
}
}
}
x
}
测试:
set.seed(1) # Please change this
x = backtrack(10)
print(x)
[,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
[1,] 8 10 4 6 9 7 1 2 3 5
[2,] 5 6 9 8 1 10 4 3 2 7
[3,] 10 7 1 2 8 9 5 4 6 3
[4,] 3 9 8 10 6 5 7 1 4 2
[5,] 9 1 6 4 7 3 2 5 10 8
[6,] 1 4 10 3 2 6 8 7 5 9
[7,] 2 8 5 9 10 1 3 6 7 4
[8,] 6 5 2 7 3 4 10 9 8 1
[9,] 4 3 7 1 5 2 6 8 9 10
[10,] 7 2 3 5 4 8 9 10 1 6
any(apply(x, 1, function(r)any(duplicated(r)))) # FALSE
any(apply(x, 2, function(r)any(duplicated(r)))) # FALSE
除非我误解了问题,否则有一种更简单的方法可以创建这个打乱后的矩阵,无需任何循环或复杂的条件语句。
# number of rows and columns
n <- 10
# create ordered rows and columns
ordered.by.row <- matrix(1:n, n, n)
ordered.by.col <- matrix(1:n, n, n, byrow = T)
# offset the rows and columns relative to each other.
# no row or column has a repeated value, but the values are still ordered
offset <- (ordered.by.row + ordered.by.col) %% n + 1
# shuffle the columns, then shuffle the rows, this produces a randomized matrix
# 'shuffle.row' is the final, randomized matrix
set.seed(1222) # change this to change randomization
shuffle.col <- offset[,sample(1:n, n, replace = F)]
shuffle.row <- shuffle.col[sample(1:n, n, replace = F), ]
# verify solution
any(apply(shuffle.row, 1, function(r)any(duplicated(r)))) # FALSE
any(apply(shuffle.row, 2, function(r)any(duplicated(r)))) # FALSE
[,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
[1,] 1 10 6 9 2 8 3 5 7 4
[2,] 3 2 8 1 4 10 5 7 9 6
[3,] 7 6 2 5 8 4 9 1 3 10
[4,] 9 8 4 7 10 6 1 3 5 2
[5,] 10 9 5 8 1 7 2 4 6 3
[6,] 2 1 7 10 3 9 4 6 8 5
[7,] 8 7 3 6 9 5 10 2 4 1
[8,] 6 5 1 4 7 3 8 10 2 9
[9,] 5 4 10 3 6 2 7 9 1 8
[10,] 4 3 9 2 5 1 6 8 10 7