2014-09-25 3 views
2

이 질문은 다른 질문 R:sample()과 밀접하게 관련되어 있습니다. 나는 R에서 k 개의 숫자의 모든 순열을 나열하는 방법을 찾고 싶습니다. 각 숫자는 0 : k에서 선택됩니다. k = 7이면 0,1, ..., 7 중에서 7 개의 숫자를 선택할 수 있습니다. 가능한 해법은이고, 다른 하나는 1,1,1,1,1,1,1입니다. 나는 k가 7보다 상당히 클 경우 폭발하기 때문에 모든 순열을 생성하고 싶지 않습니다. 나는 (K-1)를 작성할 필요없이 K 설명하기 위해이 방법을 일반화 할 수있는 방법0에서 k까지의 k 값의 모든 순열을 나열하십시오. k가 합계가

perms7<-matrix(numeric(7*1716),ncol=7) 
count=0 
for(i in 0:7) 
    for(j in 0:(7-i)) 
     for(k in 0:(7-i-j)) 
      for(l in 0:(7-i-j-k)) 
       for(n in 0:(7-i-j-k-l)) 
        for(m in 0:(7-i-j-k-l-n)){ 
          res<-7-i-j-k-l-n-m 
          count<-count+1 
          perms7[count,]<-c(i,j,k,l,n,m,res) 
         } 
head(perms7,10) 

그러나 루프 : 나는이 다음 사용할 수있는 K = 7 예에서 물론

? 나는 재귀 계획을 마련하려고 :

perms7<-matrix(numeric(7*1716),ncol=7) #store solutions (adjustable size later) 
k<-7 #size of interest 
d<-0 #depth 
count=0 #count of permutations 
rec<-function(j,d,a){ 
    a<-a-j #max loop 
    d<-d+1 #depth (posistion) 
    for(i in 0:a) { 
     if(d<(k-1)) rec(i,d,a) 
     count<<-count+1 
     perms7[count,d]<<-i 
     perms7[count,k]<<-k-sum(perms7[count,-k]) 
    } 
} 
rec(0,0,k) 

하지만 붙어있어, 나는이 갈 수있는 올바른 방법이다 확실히 모르겠어요. 이 (매우 구체적인) 문제 또는 그 일부만을 위해 깔끔한 "마법"R 기능이 있는지 궁금합니다. K 개의 = 7 경우

모든 2.097.152 순열 및 그 합계 1.716 = 7에 의해 발견 될 수 k는하기 : 43.046.721 순열 8있다 = k에 대한

library(gtools) 
k=7 
perms <- permutations(k+1, k, 0:k, repeats.allowed=T) #all permutations 
perms.k <- perms[rowSums(perms) == k,] #permutations which sums to k 

하지만 단지 6.435를리스트하고 싶다. 도움을 주시면 대단히 감사하겠습니다!

+0

나는 이것이 하노이 타워의 문제와 관련이있다 생각합니다. 패키지'fun'와'ref'는 이것을 해결하는 함수를 가지고 있습니다. – James

+0

하노이 타워 문제와 어떻게 관련이 있는지 모르겠다. 정교함을 부탁해 주시겠습니까? 기본적으로 Z^k에서 초평면의 카디널리티를 계산할 필요가 있습니다. –

+0

k-tile, k-peg ToH의 가능한 모든 공간의 공간입니다. 분명히 ToH에 대한 최적의 솔루션은 모든 주를 가로 지르려고하지 않을 것이지만 최대한 차선책을 찾으면 답을 얻어야합니다. – James

답변

5

그것에 대해 패키지있다 ...

require(partitions) 
parts(7)         
#[1,] 7 6 5 5 4 4 4 3 3 3 3 2 2 2 1 
#[2,] 0 1 2 1 3 2 1 3 2 2 1 2 2 1 1 
#[3,] 0 0 0 1 0 1 1 1 2 1 1 2 1 1 1 
#[4,] 0 0 0 0 0 0 1 0 0 1 1 1 1 1 1 
#[5,] 0 0 0 0 0 0 0 0 0 0 1 0 1 1 1 
#[6,] 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 
#[7,] 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 

당신은 compositions() 찾고있는 것으로 나타났습니다. 예 : K = 4을 위해 :

parts(4) 

#[1,] 4 3 2 2 1 
#[2,] 0 1 2 1 1 
#[3,] 0 0 0 1 1 
#[4,] 0 0 0 0 1 

compositions(4,4)                   
#[1,] 4 3 2 1 0 3 2 1 0 2 1 0 1 0 0 3 2 1 0 2 1 0 1 0 0 2 1 0 1 0 0 1 0 0 0 
#[2,] 0 1 2 3 4 0 1 2 3 0 1 2 0 1 0 0 1 2 3 0 1 2 0 1 0 0 1 2 0 1 0 0 1 0 0 
#[3,] 0 0 0 0 0 1 1 1 1 2 2 2 3 3 4 0 0 0 0 1 1 1 2 2 3 0 0 0 1 1 2 0 0 1 0 
#[4,] 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 3 3 3 4 

그리고 당신의 수학을 확인하는 ... :-)

ncol(compositions(8,8)) 
#[1] 6435 
+0

이것은 매우 산뜻합니다. composition()이 모든 순열 (permutations)과 부분 집합 (subset)을 계산하는 것이 아닌지 확인하는 방법을 살펴 보겠습니다. 고맙습니다! –

+0

@ J.R. 그것은 매우 빠르다! pacakge에서 C 함수'allblockparts '를 검사해야한다고 생각하기 때문에 소스를 다운로드해야합니다. –

+0

네, 훌륭하게 작동하므로 모든 순열을 먼저 나열하지 않는다고 확신합니다! 처음에 언급 된 링크 된 질문에 대한 해결책으로 그것을 추가하는 것을 고려해야합니다. 'allblockparts '를 살펴볼 것입니다. 다시 감사합니다! –

관련 문제