Explore Ebooks

Categories

Explore Audiobooks

Categories

Explore Magazines

Categories

Explore Documents

Categories

0 ratings0% found this document useful (0 votes)

2K views6 pagesThis tutorial discusses the use of factoradic numbers to represent permutations and presents an algorithm to generate permutations, any permutation, from such representation. The source-code in freepascal of a demo program is also given.

© Attribution Non-Commercial (BY-NC)

PDF, TXT or read online from Scribd

This tutorial discusses the use of factoradic numbers to represent permutations and presents an algorithm to generate permutations, any permutation, from such representation. The source-code in freepascal of a demo program is also given.

Attribution Non-Commercial (BY-NC)

0 ratings0% found this document useful (0 votes)

2K views6 pagesThis tutorial discusses the use of factoradic numbers to represent permutations and presents an algorithm to generate permutations, any permutation, from such representation. The source-code in freepascal of a demo program is also given.

Attribution Non-Commercial (BY-NC)

You are on page 1of 6

Prof. Joel G. Silva Filho

Instituto de Educao Superior de Braslia - IESB

joel-iesb@joelguilherme.com

2012-01-03

Keywords: permutations, inversions, number systems, factoradic numbers, generation of permutations.

Introduction

A permutation on an ordered set of n elements is a well known concept. Whatever the

elements of the set may be, for simplicity and ease of manipulation, we can always represent it by

the set of the first n non-negative integers, or, in other words, the integers modulo-n: Z

n

= {0,1,2,

,n-1}. A permutation on this set is simply a rearrangement of its elements, r = (r(0),r(1), , r(n-

1)), where r(i) is the element that replaces i in the i-th position. For example, any set of 4 elements

can be represented by Z

4

= {0,1,2,3}. We can have then, for example, r

2

= {0,2,1,3} - we will

explain the subscript '2' later, where r

2

(0) = 0, r

2

(1) = 2, r

2

(2) = 1 and r

2

(3) = 3.

Ordered sets and its permutations find extensive application and interest in many areas such

as discrete mathematics, combinatorics, cryptography, computer science, and other areas.

One basic question when studying permutations is how many distinct permutations can we

find for a set of n elements. Considering that all elements in the set are distinct, the answer is easy

to find: we have n possible placements for each element, having n choices for the first, (n-1) for the

second, (n-2) for the third, and so on, such that for the last position we get only one choice, when all

others have already been chosen, getting N = n(n-1)(n-2) 321 , which is a number that

receives the special representation n! and is called the factorial of n (reading as n factorial). The

set of all permutations of n elements is usually denoted by S

n

and it forms the structure of a Group

under the operation of 'composition of permutations', i.e. the successive application of two (or

more) permutations on a given set, which consists the Symmetric Group of order n

(1)

.

Number Systems

We are used to single base number representations, such as base 10, which gives us the

ordinary decimal numbers, and base 2, which gives us the binary numbers, the latter being the basis

of all computer operations. Given a generic base b, we can represent any number in this base as

N = d

n-1

b

n-1

+d

n-2

b

n-2

+ +d

2

b

2

+d

1

b

1

+d

0

b

0

where d

i

, i = 0, .. , (n-1) - for a n digit number - are the digits of the number representation, each

digit being in the range [0 .. (b-1)]. For a base 10 representation the digits are in the range [0 .. 9],

and for a binary (base 2) representation the digits are in the range [0,1]. This representation is

known as a polynomial representation, as each digit can be viewed as the coefficient of a

polynomial in the base b. Also, the order, or position, of each digit assumes, in this way, a value

which is proportional to the corresponding power of the base, and thus this representation is also

known as a positional representation. Other base systems were developed through history, and even

non-positional systems, such as the Roman system

(2)

.

When several bases are considered, we better write a number followed by a subscript which

identifies the base. For example, the decimal number 123 can be written as 123

10

, which shall be

interpreted as

N = 123

10

= 110

2

+ 210

1

+ 310

0

giving rise to the familiar positional values of units, tens, hundreds, and so on. The same number

can also be represented in base 2, as the binary number

N = 123

10

= 1111011

2

= 12

6

+ 12

5

+ 12

4

+ 12

3

+ 02

2

+ 12

1

+ 12

0

.

Factoradic Numbers

Now, what is a factoradic number? A factoradic number is also a positional representation

for a number where a different base is used for each digit, but where the place value of the digits is

not proportional to a power of the base, but rather to its factorial value. So, it is a mixed base

system. The conjunction of the term factorial with mixed radix led to this term factoradic,

though other terms are and have been used in the literature

(3)

.

Any number N < n! can be represented by a unique n digit factoradic number, of the form

N

!

= d

n-1

.(n-1)!+d

n-2

.(n-2)!+ +d

2

.2!+d

1

.1!+d

0

.0!

which, in short, we write as

N

!

= (d

n-1

d

n-2

d

2

d

1

d

0

)

!

,

as we do for a number in any ordinary, fixed, base. Notice the use of the subscript '!' to indicate that

the number is in factoradic notation. It should be observed that:

the i-th digit from right to left, i = 0 .. (n-1), is a base-(i +1) digit, such that we shall have

d

i

s i;

the 1

st

digit, that for i = 0, will always be zero, such that it does not effectively contribute to

the total value of the number (and could even be omitted without loss of representation, as

some authors do);

the place value for the i-th digit is i!.

For example, a number that is less than 5! ( = 120

10

) may be expressed as a 5 digits

factoradic number

N

!

= (d

4

d

3

d

2

d

1

d

0

)

!

and, taking, for example, N = 83

10

, then we have

N

!

= 31210

!

= 34! + 13! + 22! +11! + 00!

= 324 + 16 + 22 +11 + 01

= 72 + 6 +4 + 1 + 0

= 83

10

From now on, where not indicated otherwise, we will use numbers without any subscript to

express decimal numbers, such that we will write 31210

!

= 83.

By induction, it can be proved that n! =

i=0

n1

ii ! + 1 . For example, the largest factoradic

number of 5 digits (n = 5) is 43210

!

, which has as next value (43210

!

+1) = 100000

!

. In other words,

44!+33!+22!+11!+0! = 119 and, 5! =120 = 119+1. This establishes that really any non-negative

integer has a unique representation as a factoradic number.

The conversion of a decimal number to its factoradic representation can be made by the

straightforward method of successive integer divisions by the place value for each position, starting

from i = n-1, and taking the quotients as the corresponding factoradic digits. The remainder of each

division is then divided by the next place value. For the previous example we could have computed

83 = 324 + 11

11 = 16 + 5

5 = 22 + 1

1 = 11 + 0

0 = 00 + 0

Inversions

Consider a set of n = 5 elements, represented by Z

5

= {0,1,2,3,4} and let us label the

elements of the set as p

i

, for i = 0 .. (n-1). A possible permutation on this set is r

0

= (0,1,2,3,4),

which represents the identity permutation, as the order of the original set has not changed. Another

permutation could be r

83

= (3,1,4,2,0) - as mentioned before, we will care about the subscripts later.

It is said that an inversion has occurred in position i, in a given permutation, when p

i

> p

j

, for some

j > i. In r

83

we find that for i = 0 we have 3 inversions, as 4 > 2, 3 and 1. In the same way, for i = 1

we have 1 inversion, for i = 2 we have 2 inversions, for i = 3 we have 1 inversion, and for i = 4 we

have 0 inversions. We will always have 0 inversions for i = (n-1) as there is no further elements

beyond that. If we put this inversion counts in the form of a vector we get what is called the

inversion vector, or inversion table, for the corresponding permutation, also called its Lehmer

Code

(4,5)

, L. For the general case we can write

L(r) = [l

0

(r), l

1

(r), , l

n-1

(r)], where

l

i

(r) = |{j > i: r(i) > r(j)}|.

It can be shown that every permutation has a unique Lehmer Code associated to it, thus

existing a one-to-one mapping between Lehmer Codes and permutations

(3)

.

Returning to our previous example then we have

L

83

= [3,1,2,1,0].

Now, the beauty of it: 83 = 31210

!

, which shows that we can associate each n-digit

factoradic number, one-to-one, with every permutation in S

n

. This finally justifies the use that we

have done for the subscripts added to the example permutations examined so far and gives us a very

easy way for enumerating all permutations in S

n

with a simple decimal index that counts from 0 to

(n! - 1). Another important result of this permutations ordering as factoradic numbers is that they

are obtained in a natural, lexicographical, order.

As a small example, let us take n = 3 and construct a table associating all 6 elements of S

3

to

its corresponding indexes, both in decimal and factoradic representation, as shown in table 1 below:

Table 1: Permutations and associated indexes for n = 3.

N N

!

r

N

0 (0,0,0) (0,1,2)

1 (0,1,0) (0,2,1)

2 (1,0,0) (1,0,2)

3 (1,1,0) (1,2,0)

4 (2,0,0) (2,0,1)

5 (2,1,0) (2,1,0)

From Permutations to Factoradic Numbers and Vice-versa

We have shown how to represent a given permutation as a factoradic number, simply by

constructing its inversion vector. Now it remains to show how we can determine the particular

permutation associated to a given factoradic number or decimal equivalent.

There are many and many ways of generating permutations, including sequential generation

and random generation. The point about generating a permutation from its associated factoradic

representation is that we can generate any permutation, without having to pass through intermediate

processing, or, from a given permutation, obtain a corresponding index for it, considered a

lexicographical ordering for the elements of S

n

.

To obtain the associated permutation of n elements from its corresponding Factoradic value,

or, equivalently, its Lehmer code, or inversion vector, is just a matter of going backwards with

respect to the previous construct. Let us consider n = 5, such that the original set may be regarded as

S = r

0

= {0,1,2,3,4}. Let us assume now that we want to identify r

51

. Considering that N = 51 =

20110

!

, then we can write L(r

51

) = [l

0

, l

1

, l

2

, l

3

, l

4

] = [2,0,1,1,0]. Starting with i = 0 we observe that

l

0

= 2 corresponds to the inversions count for that position. So, to find the corresponding element in

r

0

we just take the element in this set which is bigger than 2 other elements, which in turn is the

element of order 2 in r

0

, or else, r

51

(0) = r

0

(l

0

) = r

0

(2) = 2. Now, we remove this element from the

original set (it has already been used in r

51

), getting r

0

' = {0,1,3,4}, and consider the next element

of L, l

1

= 0. The same process applies now to r

0

', giving r

51

(1) = r

0

'(l

1

) = r

0

'(0) = 0, and so

successively, till we obtain all elements of the wanted permutation. In table 2 that follows it is better

illustrated this process of constructing r

51

:

Table 2: Constructing permutation r

51

(n=5) from its Lehmer Code.

i l

i

Lehmer Code Set S (r

0

) Perm r

51

0 2 [2,0,1,1,0] (0,1,2,3,4) (2,_,_,_,_)

1 0 [2,0,1,1,0] (0,1,3,4,_) (2,0,_,_,_)

2 1 [2,0,1,1,0] (1,3,4,_,_) (2,0,3,_,_)

3 1 [2,0,1,1,0] (1,4,_,_,_) (2,0,3,4,_)

4 0 [2,0,1,1,0] (1,_,_,_,_) (2,0,3,4,1)

Note that l

n-1

being always zero, it corresponds to whatever is the last element remaining in

r

0

' in the last step of the process.

Generating a Permutation

Given the order n and a decimal index N < (n-1)! we can generate the corresponding

permutation with this simple algorithm, in pseudo-language:

1. Define variables:

N,n: int; // Decimal integer and order of the set

i,j,r,v: int; // indexes to arrays

S: array[0..n-1]; // original set

Perm: array[0..n-1]; // permuted set

PlaceValue: array[0..n-1]; // fatoradic place values [0!,1!,2!,..,(n-1)!]

Factoradic:array[0..n-1]; // fatoradic digits corresponding to N

2. Initialize variables

2.1 read n,N

2.2 for i from 0 to (n-1) do

S[i] = I

PlaceValue[i] = i!

enddo

3. Convert N to factoradic

3.1 V = N

3.2 for i from (n-1) downto 0 do

Factoradic[i] = V div PlaceValue[i]

V = V mod PlaceValue[i]

enddo

4. Convert Factoradic to Permutation

for i from 0 to (n-1) do

j = (n-1)-i

r = Factoradic[j]

Perm[i] = S[r]

// delete S[r] by shifting left greater order elements

for j from r to (n-2) do S[j] = S[j+1]

enddo

END

A demo implementation in FreePascal of this algorithm is shown below, together with its

output for n = 5 and N = 51, as done in the previous example:

program Dec2Perm;

(* Program for generating a permutation of a set of n elements from a given

Decimal index, based on the representation of a permutation as a "factoradic

number", i.e. a number represented in the mixed base [(n-1)!,(n-2)!,...,2!,

1!, 0!].

We have limited 'n' to 12, as this is just a demo program and 12! fits into

a 32-bit CPU word. *)

uses SysUtils;

const

progname = 'Dec2Perm';

version = 'v0.9 - 12.01.03';

author = ' (Joel Guilherme)';

nmax = 12;

type

aset = array[0..(nmax-1)] of byte; // a set of integers mod-n

bset = array[0..(nmax-1)] of longword; // a set of integers

var

n: byte; // the order of the set

D,V: longword; // decimal to be converted to a permutation

Dmax: longword; // maximum value for D

i,j,r: byte; // indexes to arrays

Code: word; // indicates input conversion error

S: aset; // this will hold the original, ordered permutation (0,1,2,...,n-1)

Perm: aset; // the permutation associated to N

PlaceValue: bset; // array with fatoradic place values [0!,1!,2!,..,(n-1)!]

Factoradic: bset; // array with a fatoradic number digits corresponding to N

procedure ShowSet(msg: string; span: byte; var Arr: aset);

// writes a set to console

var

r,m: byte;

begin

m := span-1;

write(msg);

for r := 0 to m do

begin

if (r = 0) then

write('[',Arr[r])

else

write(',',Arr[r]);

end;

writeln(']');

end; { ShowSet }

procedure ShowFac(msg: string; span: byte; var Arr: bset);

// writes a factoradic array to console

var

r,m: byte;

begin

m := span-1;

write(msg);

for r := m downto 0 do

begin

if (r = m) then

write('[',Arr[r])

else

write(',',Arr[r]);

end;

writeln(']');

end; { ShowFac }

function factorial(x: longword): longword;

begin

if (x=0) or (x=1) then

factorial := 1

else

factorial := x*factorial(x-1);

end;

procedure Help;

// Shows a "help" message if wrong parameters passed

begin

writeln('usage:');

writeln(' > nextperm <N> <n>');

writeln(' where');

writeln(' - N is a decimal index to a lexicographically permuted set');

writeln(' - n is the order of the set to be permuted');

writeln;

halt(1);

end;

procedure Error(msg: string);

begin

writeln(msg,'! Aborting!');

halt(1);

end;

procedure Initialize;

// initialize arrays and variables

begin

Dmax := factorial(n);

for i := 0 to (n-1) do begin

S[i] := i;

PlaceValue[i] := factorial(i);

end;

end;

{ Main Program }

begin

writeln; writeln(Progname,' ',version);

writeln('Program for generating a lexicographically ordered ');

writeln('permutation from a given decimal index. - ',author); writeln;

if paramcount < 2 then Help;

val(paramstr(1),D,Code);

if Code > 0 then Error('Error reading input N');

val(paramstr(2),n,Code);

if Code > 0 then Error('Error reading input n');

if n > nmax then Error('Given order ''n'' is too big. Maximum is 12');

Initialize;

if D > Dmax then Error('Given decimal ''N'' is too big. Maximu is (n! - 1)');

// Convert N to Factoradic

V := D;

for i := (n-1) downto 0 do begin

Factoradic[i] := V div Placevalue[i];

V := V mod Placevalue[i];

end;

writeln('For n = ',n,':');

ShowSet('Perm(0) = ',n,S);

ShowFac('Factoradic('+inttostr(D)+') = ',n,Factoradic);

// Convert Factoradic to Permutation

for i := 0 to (n-1) do begin

j := (n-1) - i;

r := Factoradic[j];

Perm[i] := S[r];

// delete S[r] from S (by shifting left all greater order elements)

for j := r to (n-2) do S[j] := S[j+1];

end;

ShowSet('Perm('+inttostr(D)+') = ',n,Perm);

writeln;

end.

The program has been compiled with FreePascal 2.4.0 for Linux-Ubuntu 10.04. A sample

output from the program is:

$ ./Dec2Perm 51 5

Dec2Perm v0.9 - 12.01.03

Program for generating a lexicographically ordered

permutation from a given decimal index. - (Joel Guilherme)

For n = 5:

Perm(0) = [0,1,2,3,4]

Factoradic(51) = [2,0,1,1,0]

Perm(51) = [2,0,3,4,1]

Bibliography

(1) Symmetric group, http://en.wikipedia.org/wiki/Symmetric_group - accessed on 2011/12/11.

(2) Positional notation, http://en.wikipedia.org/wiki/Positional_notation - accessed on 2011/12/11.

(3) Factorial number system, http://en.wikipedia.org/wiki/Factorial_number_system - accessed on

2011/12/11.

(4) Permutation, http://en.wikipedia.org/wiki/Permutation - accessed on 2011/12/11.

(5) Enumerating permutations using inversion vectors and factoradic numbering, http://lin-ear-th-

inking.blogspot.com/2012/11/enumerating-permutations-using.html - . accessed on

2011/12/11.