I’m trying to write C++ code which will compute all possible orderings of groups of integers, whose sizes are given in a vector (unknown in length).
For example, if the input is (group1=2, group2=3, group3=2), then I need to compute every ordering of the first 7 integers, in groups of 2, 3, and 2.
Groups matter in avoiding duplicates (i.e. 1234567 is the same as 2134567 which is the same as 1234576).
The output should be:
1234567
1234657
1234756
1235647
...
6734512
But there could be as many as 10 different groups given (usually the size of the group is less than or equal to 5)
I’m still fairly new to C++, but it seems like I need to use next_permutation from algorithm, possibly in recursion, but I haven’t been able to work out the details.
The following is working (inefficient) R code I’ve written, (in case my question was unclear) but it’s far too slow for reasonably large group numbers/sizes.
Thanks!
#Input group sizes for k;
CombnMult<-function(k){
n<-sum(k)
A1<-combn(n,k[1])
CHOOSE<-rep(0,length(k))
CHOOSE[1]<-factorial(n)/(factorial(k[1])*factorial(n-k[1]))
for(i in 1:(length(k)-1)){
CHOOSE[i+1]<-factorial(n-cumsum(k)[i])/(factorial(k[i+1])*factorial(n-cumsum(k)[i+1]))
assign(paste("B",i,sep=''),matrix(get(paste("A",i,sep='')), nrow=cumsum(k)[i]))
if(length((1:n)[is.na(pmatch((1:n),get(paste("B",i,sep=''))[,1]))])>1)
assign(paste("A",i+1,sep=''),apply(get(paste("B",i,sep='')),2,function(z) rbind(matrix(rep(z,CHOOSE[i+1]),ncol=CHOOSE[i+1]),combn((1:n)[is.na(pmatch((1:n),z))],k[i+1]))))
if(length((1:n)[is.na(pmatch((1:n),get(paste("B",i,sep=''))[,1]))])==1)
assign(paste("A",i+1,sep=''),apply(get(paste("B",i,sep='')),2,function(z) rbind(matrix(rep(z,CHOOSE[i+1]),ncol=CHOOSE[i+1]),(1:n)[is.na(pmatch((1:n),z))])))
}
t(get(paste("A",i+1,sep='')))
}
#Example:
CombnMult(c(2,3,2))
This seems to work for me:
How it works: A fairly standard enumeration of all permutations of the identifiers, modified so that the identifiers within a single group are forced to be strictly increasing. At each group boundary, the identifier is allowed to decrease.