Search code examples
functionpermutationalgebrabijection

Generating reversible permutations over a set


I want to traverse all the elements in the set Q = [0, 2^16) in a non sequential manner. To do so I need a function f(x) Q --> Q which gives the order in which the set will be sorted. for example:

f(0) = 2345   
f(1) = 4364   
f(2) = 24   
(...)

To recover the order I would need the inverse function f'(x) Q --> Q which would output:

f(2345) = 0
f(4364) = 1
f(24) = 2
(...)

The function must be bijective, for each element of Q the function uniquely maps to another element of Q.

How can I generate such a function or are there any know functions that do this?


Solution

  • EDIT: In the following answer, f(x) is "what comes after x", not "what goes in position x". For example, if your first number is 5, then f(5) is the next element, not f(1). In retrospect, you probably thought of f(x) as "what goes in position x". The function defined in this answer is much weaker if used as "what goes in position x".


    Linear congruential generators fit your needs.

    A linear congruential generator is defined by the equation

    f(x) = a*x+c (mod m)
    

    for some constants a, c, and m. In this case, m = 65536.

    An LCG has full period (the property you want) if the following properties hold:

    1. c and m are relatively prime.
    2. a-1 is divisible by all prime factors of m.
    3. If m is a multiple of 4, a-1 is a multiple of 4.

    We'll go with a = 5, c = 1.

    To invert an LCG, we solve for f(x) in terms of x:

    x = (a^-1)*(f(x) - c) (mod m)
    

    We can find the inverse of 5 mod 65536 by the extended Euclidean algorithm, or since we just need this one computation, we can plug it into Wolfram Alpha. The result is 52429.

    Thus, we have

    f(x) = (5*x + 1) % 65536
    f^-1(x) = (52429 * (x - 1)) % 65536