Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

sapply to create unique permutations without overlap

Tags:

r

I am trying to create a function that will do the following:

input: 1:3
output: 1 2 3 2 3 1 3 1 2 

In this way i want to generate all permutations of the input where the elements never overlap for each given index

1 2 3 and  2 3 1 and 3 1 2

I have come as far as:

sapply(1:4,(function(i){paste0(i,i+1,i+2,i+3)}))

but this does not generate the output i am looking for.

like image 632
Hugo van Kessel Avatar asked Apr 29 '26 16:04

Hugo van Kessel


2 Answers

I assume that problem is that we are given n and we want a vector containing 1:n followed by each permutation of 1:n for which the ith element of each such permutation is not i. We generate all permutations and then eliminate those for which the ith position equals i for all i in 1:n, i.e. if P is permutation of 1:n then we only accept it if all(P != 1:n) is TRUE. The calculation below will get large very quickly but for small n it should be ok.

library(RcppAlgos)

n <- 2
p <- permuteGeneral(n)
c(cbind(1:n, t(p[apply(t(p) != 1:n, 2, all), , drop = FALSE])))
## [1] 1 2 2 1

n <- 3
p <- permuteGeneral(n)
c(cbind(1:n, t(p[apply(t(p) != 1:n, 2, all), , drop = FALSE])))
## [1] 1 2 3 2 3 1 3 1 2

n <- 4
p <- permuteGeneral(n)
c(cbind(1:n, t(p[apply(t(p) != 1:n, 2, all), , drop = FALSE])))
## [1] 1 2 3 4 2 1 4 3 2 3 4 1 2 4 1 3 3 1 4 2 3 4 1 2 3 4 2 1 4 1 2 3 4 3 1 2 4 3 2 1
like image 199
G. Grothendieck Avatar answered May 02 '26 06:05

G. Grothendieck


Reading your comment in looks like you can use matrix to generate the wanted numbers like:

n <- 2
matrix(1:n, n+1, n)[1:n,]
#     [,1] [,2]
#[1,]    1    2
#[2,]    2    1

n <- 3
matrix(1:n, n+1, n)[1:n,]
#     [,1] [,2] [,3]
#[1,]    1    2    3
#[2,]    2    3    1
#[3,]    3    1    2

n <- 4
matrix(1:n, n+1, n)[1:n,]
#     [,1] [,2] [,3] [,4]
#[1,]    1    2    3    4
#[2,]    2    3    4    1
#[3,]    3    4    1    2
#[4,]    4    1    2    3

n <- 5
matrix(1:n, n+1, n)[1:n,]
#     [,1] [,2] [,3] [,4] [,5]
#[1,]    1    2    3    4    5
#[2,]    2    3    4    5    1
#[3,]    3    4    5    1    2
#[4,]    4    5    1    2    3
#[5,]    5    1    2    3    4

My first answer to generate all permutations in base using expand.grid was:

x <- 1:3
do.call(expand.grid, lapply(x, \(i) x)) ->.
  .[apply(., 1, anyDuplicated) == 0,]
#   Var1 Var2 Var3
#6     3    2    1
#8     2    3    1
#12    3    1    2
#16    1    3    2
#20    2    1    3
#22    1    2    3
like image 28
GKi Avatar answered May 02 '26 06:05

GKi



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!