在 R 中生成随机排列
Generating a Random Permutation in R
我尝试使用 Sheldon M. Ross Simulation (2006, 4ed., Elsevier)
中的 R 实现一个示例,它想要生成一个随机排列,内容如下:
假设我们有兴趣生成数字 1,2,... ,n
的排列
这就是所有n!可能的顺序是同样可能的。
以下算法将通过
完成
- 首先随机选择数字 1,2,...,n 中的一个;
- 然后将该数字放在位置 n;
- 然后它随机选择剩余的 n-1 个数字中的一个并将该数字放在位置 n-1 ;
- 然后从剩下的n-2个数中随机选择一个放在n-2位;
- 等等
当然,我们可以通过
轻松实现数字 1,2,...,n 的随机排列
sample(1:n, replace=FALSE)
例如
> set.seed(0); sample(1:5, replace=FALSE)
[1] 1 4 3 5 2
但是,我想按照上面的算法步骤手动得到类似的结果。那我试试
## write the function
my_perm = function(n){
x = 1:n # initialize
k = n # position n
out = NULL
while(k>0){
y = sample(x, size=1) # choose one of the numbers at random
out = c(y,out) # put the number in position
x = setdiff(x,out) # the remaining numbers
k = k-1 # and so on
}
out
}
## test the function
n = 5; set.seed(0); my_perm(n) # set.seed for reproducible
并且有
[1] 2 2 4 5 1
这显然是不正确的,因为有两个 2
。我该如何解决这个问题?
您已经正确实现了逻辑,但您只需要注意一件事,它与 R
.
有关
来自?sample
If x has length 1, is numeric (in the sense of is.numeric) and x >= 1, sampling via sample takes place from 1:x
因此,当最后一个数字留在 x
中时,假设数字为 4,将从 1:4 和 return 中的任何 1 个数字进行采样。
例如,
set.seed(0)
sample(4, 1)
#[1] 2
所以你需要调整你的功能,然后代码才能正常工作。
my_perm = function(n){
x = 1:n # initialize
k = n # position n
out = NULL
while(k>1){ #Stop the while loop when k = 1
y = sample(x, size=1) # choose one of the numbers at random
out = c(y,out) # put the number in position
x = setdiff(x,out) # the remaining numbers
k = k-1 # and so on
}
out <- c(x, out) #Add the last number in the output vector.
out
}
## test the function
n = 5
set.seed(0)
my_perm(n)
#[1] 3 2 4 5 1
样本大小应大于 1。您可以通过编写条件来打破它;
my_perm = function(n){
x = 1:n
k = n
out = NULL
while(k>0){
if(length(x)>1){
y = sample(x, size=1)
}else{
y = x
}
out = c(y,out)
x = setdiff(x,out)
k = k-1
}
out
}
n = 5; set.seed(0); my_perm(n)
[1] 3 2 4 5 1
我尝试使用 Sheldon M. Ross Simulation (2006, 4ed., Elsevier)
中的 R 实现一个示例,它想要生成一个随机排列,内容如下:
假设我们有兴趣生成数字 1,2,... ,n
的排列这就是所有n!可能的顺序是同样可能的。
以下算法将通过
完成- 首先随机选择数字 1,2,...,n 中的一个;
- 然后将该数字放在位置 n;
- 然后它随机选择剩余的 n-1 个数字中的一个并将该数字放在位置 n-1 ;
- 然后从剩下的n-2个数中随机选择一个放在n-2位;
- 等等
当然,我们可以通过
轻松实现数字 1,2,...,n 的随机排列sample(1:n, replace=FALSE)
例如
> set.seed(0); sample(1:5, replace=FALSE)
[1] 1 4 3 5 2
但是,我想按照上面的算法步骤手动得到类似的结果。那我试试
## write the function
my_perm = function(n){
x = 1:n # initialize
k = n # position n
out = NULL
while(k>0){
y = sample(x, size=1) # choose one of the numbers at random
out = c(y,out) # put the number in position
x = setdiff(x,out) # the remaining numbers
k = k-1 # and so on
}
out
}
## test the function
n = 5; set.seed(0); my_perm(n) # set.seed for reproducible
并且有
[1] 2 2 4 5 1
这显然是不正确的,因为有两个 2
。我该如何解决这个问题?
您已经正确实现了逻辑,但您只需要注意一件事,它与 R
.
来自?sample
If x has length 1, is numeric (in the sense of is.numeric) and x >= 1, sampling via sample takes place from 1:x
因此,当最后一个数字留在 x
中时,假设数字为 4,将从 1:4 和 return 中的任何 1 个数字进行采样。
例如,
set.seed(0)
sample(4, 1)
#[1] 2
所以你需要调整你的功能,然后代码才能正常工作。
my_perm = function(n){
x = 1:n # initialize
k = n # position n
out = NULL
while(k>1){ #Stop the while loop when k = 1
y = sample(x, size=1) # choose one of the numbers at random
out = c(y,out) # put the number in position
x = setdiff(x,out) # the remaining numbers
k = k-1 # and so on
}
out <- c(x, out) #Add the last number in the output vector.
out
}
## test the function
n = 5
set.seed(0)
my_perm(n)
#[1] 3 2 4 5 1
样本大小应大于 1。您可以通过编写条件来打破它;
my_perm = function(n){
x = 1:n
k = n
out = NULL
while(k>0){
if(length(x)>1){
y = sample(x, size=1)
}else{
y = x
}
out = c(y,out)
x = setdiff(x,out)
k = k-1
}
out
}
n = 5; set.seed(0); my_perm(n)
[1] 3 2 4 5 1