n 번째 조합을 생성하는 것을 "랭킹 해제"알고리즘이라고합니다. 순열과 조합은 종종 문제가 매개 변수화되는 방식으로 동일시 될 수 있습니다. 문제가 무엇인지 정확히 알지 못하면 정확한 올바른 접근 방법을 권장하기가 어렵습니다. 실제로 대부분의 조합 문제의 경우 일반적으로 여러 가지 순위 지정 / 순위 지정 해제 알고리즘이 있습니다.
좋은 자원 중 하나는 Kreher와 Stinson의 "Combinatorial Algorithms"입니다. 이 책에는 많은 좋은 순위와 순위를 정하지 않은 알고리즘이 명확하게 설명되어 있습니다. 더 많은 고급 리소스가 있지만 Kreher를 시작점으로 추천합니다. 순위 지정 알고리즘의 예로 다음을 고려하십시오.
/** PKSUL : permutation given its rank, the slots and the total number of items
* A combinatorial ranking is number of the permutation when sorted in lexicographical order
* Example: given the set { 1, 2, 3, 4 } the ctItems is 4, if the slot count is 3 we have:
* 1: 123 7: 213 13: 312 19: 412
* 2: 124 8: 214 14: 314 20: 413
* 3: 132 9: 231 15: 321 21: 421
* 4: 134 10: 234 16: 324 22: 423
* 5: 142 11: 241 17: 341 23: 431
* 6: 143 12: 243 18: 342 24: 432
* From this we can see that the rank of { 2, 4, 1 } is 11, for example. To unrank the value of 11:
* unrank( 11 ) = { 11 % (slots - digit_place)!, unrank( remainder ) }
* @param rank the one-based rank of the permutation
* @param ctItems the total number of items in the set
* @param ctSlots the number of slots into which the permuations are generated
* @param zOneBased whether the permutation array is one-based or zero-based
* @return zero- or one-based array containing the permutation out of the set { ctItems, 1,...,ctItems }
*/
public static int[] pksul( final int rank, final int ctItems, final int ctSlots, boolean zOneBased ){
if( ctSlots <= 0 || ctItems <= 0 || rank <= 0 ) return null;
long iFactorial = factorial_long( ctItems - 1 ) / factorial_long( ctItems - ctSlots );
int lenPermutation = zOneBased ? ctSlots + 1 : ctSlots;
int[] permutation = new int[ lenPermutation ];
int[] listItemsRemaining = new int[ ctItems + 1 ];
for( int xItem = 1; xItem <= ctItems; xItem++ ) listItemsRemaining[xItem] = xItem;
int iRemainder = rank - 1;
int xSlot = 1;
while( true ){
int iOrder = (int)( iRemainder / iFactorial ) + 1;
iRemainder = (int)( iRemainder % iFactorial );
int iPlaceValue = listItemsRemaining[ iOrder ];
if( zOneBased ){
permutation[xSlot] = iPlaceValue;
} else {
permutation[xSlot - 1] = iPlaceValue;
}
for( int xItem = iOrder; xItem < ctItems; xItem++ ) listItemsRemaining[xItem] = listItemsRemaining[xItem + 1]; // shift remaining items to the left
if( xSlot == ctSlots ) break;
iFactorial /= ( ctItems - xSlot );
xSlot++;
}
if( zOneBased ) permutation[0] = ctSlots;
return permutation;
}
이것은 순열 랭킹이지만 위에서 언급 한 것처럼 조합 랭킹을 동등한 순열 문제로 변환 할 수 있습니다.