How to resolve the algorithm Permutations/Rank of a permutation step by step in the Tcl programming language
How to resolve the algorithm Permutations/Rank of a permutation step by step in the Tcl programming language
Table of Contents
Problem Statement
A particular ranking of a permutation associates an integer with a particular ordering of all the permutations of a set of distinct items. For our purposes the ranking will assign integers
0.. ( n ! − 1 )
{\displaystyle 0..(n!-1)}
to an ordering of all the permutations of the integers
0.. ( n − 1 )
{\displaystyle 0..(n-1)}
. For example, the permutations of the digits zero to 3 arranged lexicographically have the following rank: Algorithms exist that can generate a rank from a permutation for some particular ordering of permutations, and that can generate the same rank from the given individual permutation (i.e. given a rank of 17 produce (2, 3, 1, 0) in the example above). One use of such algorithms could be in generating a small, random, sample of permutations of
n
{\displaystyle n}
items without duplicates when the total number of permutations is large. Remember that the total number of permutations of
n
{\displaystyle n}
items is given by
n !
{\displaystyle n!}
which grows large very quickly: A 32 bit integer can only hold
12 !
{\displaystyle 12!}
, a 64 bit integer only
20 !
{\displaystyle 20!}
. It becomes difficult to take the straight-forward approach of generating all permutations then taking a random sample of them. A question on the Stack Overflow site asked how to generate one million random and indivudual permutations of 144 items.
Let's start with the solution:
Step by Step solution about How to resolve the algorithm Permutations/Rank of a permutation step by step in the Tcl programming language
Source code in the tcl programming language
# A functional swap routine
proc swap {v idx1 idx2} {
lset v $idx2 [lindex $v $idx1][lset v $idx1 [lindex $v $idx2];subst ""]
}
# Fill the integer array <vec> with the permutation at rank <rank>
proc computePermutation {vecName rank} {
upvar 1 $vecName vec
if {![info exist vec] || ![llength $vec]} return
set N [llength $vec]
for {set n 0} {$n < $N} {incr n} {lset vec $n $n}
for {set n $N} {$n>=1} {incr n -1} {
set r [expr {$rank % $n}]
set rank [expr {$rank / $n}]
set vec [swap $vec $r [expr {$n-1}]]
}
}
# Return the rank of the current permutation.
proc computeRank {vec} {
if {![llength $vec]} return
set inv [lrepeat [llength $vec] 0]
set i -1
foreach v $vec {lset inv $v [incr i]}
# First argument is lambda term
set mrRank1 {{f n vec inv} {
if {$n < 2} {return 0}
set s [lindex $vec [set n1 [expr {$n - 1}]]]
set vec [swap $vec $n1 [lindex $inv $n1]]
set inv [swap $inv $s $n1]
return [expr {$s + $n * [apply $f $f $n1 $vec $inv]}]
}}
return [apply $mrRank1 $mrRank1 [llength $vec] $vec $inv]
}
proc factorial {n} {
for {set result 1; set i 2} {$i <= $n} {incr i} {
set result [expr {$result * $i}]
}
return $result
}
set items1 [lrepeat 4 ""]
set rMax1 [factorial [llength $items1]]
for {set rank 0} {$rank < $rMax1} {incr rank} {
computePermutation items1 $rank
puts [format "%3d: \[%s\] = %d" \
$rank [join $items1 ", "] [computeRank $items1]]
}
puts ""
set items2 [lrepeat 21 ""]
set rMax2 [factorial [llength $items2]]
foreach _ {1 2 3 4} {
# Note that we're casting to (potential) bignum, so entier() not int()
set rank [expr {entier(rand() * $rMax2)}]
computePermutation items2 $rank
puts [format "%20lld: \[%s\] = %lld" \
$rank [join $items2 ", "] [computeRank $items2]]
}
proc uniform {limit} {
set bits [expr {ceil(log($limit)/log(2))+10}]
for {set b [set r 0]} {$b < $bits} {incr b 16} {
incr r [expr {2**$b * int(rand() * 2**16)}]
}
return [expr {$r % $limit}]
}
You may also check:How to resolve the algorithm Regular expressions step by step in the Perl programming language
You may also check:How to resolve the algorithm Substring/Top and tail step by step in the PowerShell programming language
You may also check:How to resolve the algorithm XML/DOM serialization step by step in the PHP programming language
You may also check:How to resolve the algorithm Special variables step by step in the J programming language
You may also check:How to resolve the algorithm Price fraction step by step in the Common Lisp programming language