Fast constant size overhead permutation generator.
You can use this whenever you need numbers between 0 and x in a random order.
Will print something like this
We use a bijective function r : integer -> integer where
(or just ask and i will provide a proof)
To speed things up we truncate the value to [0, 2^n] for the smallest n such that hi <= 2^n.
Looking at [2] one can see such a function r which could be adopted to jass easily. But for speeds sake we use a simpler pseudo-random function.
[2]: https://graphics.pixar.com/library/MultiJitteredSampling/paper.pdf
You can use this whenever you need numbers between 0 and x in a random order.
Demo
JASS:
function demo takes nothing returns nothing
local integer i
set i = 0
loop
exitwhen i == 5
call BJDebugMsg(I2S(i) +": "+ I2S(Permutation_index(5, 1337, i)))
set i = i +1
endloop
set i = 0
loop
exitwhen i == 5
call BJDebugMsg(I2S(i) +": "+ I2S(Permutation_index(5, 42069, i)))
set i = i +1
endloop
endfunction
Will print something like this
Code:
0: 4
1: 3
2: 2
3: 0
4: 1
0: 4
1: 0
2: 3
3: 2
4: 1
How does it work
We use a bijective function r : integer -> integer where
integer
is our 32bit jass integer type. We want a good pseudo-random function for r. Such functions are rather easy to construct. Now to get from [0, 2^32] into our desired range [0, hi) we simply apply r until it returns a value in range [0, hi). Proving that this terminates is left as an excersize to the reader To speed things up we truncate the value to [0, 2^n] for the smallest n such that hi <= 2^n.
Looking at [2] one can see such a function r which could be adopted to jass easily. But for speeds sake we use a simpler pseudo-random function.
Code
JASS:
library Permutation
private function nextPowerOfTwo takes integer x returns integer
local integer p = 1
loop
exitwhen x <= p
set p = 2*p
endloop
return p
endfunction
// any bijective function from integer to integer
private function R takes integer x, integer seed returns integer
set x = x * 0xe170893d
set x = x + 0x0929eb3f
set x = x * 0x6935fa69
set x = x - seed
set x = x * 0xc860a3df
return x
endfunction
/**
Returns the i'th index of the permutated series [0, hi-1].
@param hi The upper bound of this permutation
@param seed Random seed for the permutation
@param i Index of the permutation. Should be in range [0, hi-1]
pure
*/
public function index takes integer hi, integer seed, integer i returns integer
local integer w = nextPowerOfTwo(hi)
loop
set i = R(i, seed)
// this step isn't neccessary but it should speed up the search
// Also jasshelper doesnt like %. Otherwise we could use i % w
set i = BlzBitAnd(i, w-1)
exitwhen i < hi
endloop
// again thanks to jasshelper we can't use %
return ModuloInteger(i+seed, hi)
endfunction
endlibrary
Sources
[1]: https://web.cs.ucdavis.edu/~rogaway/papers/subset.pdf[2]: https://graphics.pixar.com/library/MultiJitteredSampling/paper.pdf
Last edited: