Gentoo Archives: gentoo-user

From: Kai Krakow <hurikhan77@×××××.com>
To: gentoo-user@l.g.o
Subject: [gentoo-user] Re: OT: Mapping random numbers (PRNG)
Date: Thu, 26 Jun 2014 23:20:48
Message-Id: e6iu7b-2hs.ln1@hurikhan77.spdns.de
In Reply to: [gentoo-user] Re: OT: Mapping random numbers (PRNG) by Kai Krakow
1 Kai Krakow <hurikhan77@×××××.com> schrieb:
2
3 > Matti Nykyri <Matti.Nykyri@×××.fi> schrieb:
4 >
5 >> If you are looking a mathematically perfect solution there is a simple
6 >> one even if your list is not in the power of 2! Take 6 bits at a time of
7 >> the random data. If the result is 62 or 63 you will discard the data and
8 >> get the next 6 bits. This selectively modifies the random data but keeps
9 >> the probabilities in correct balance. Now the probability for index of
10 >> 0-61 is 1/62 because the probability to get 62-63 out of 64 if 0.
11 >
12 > Why not do just something like this?
13 >
14 > index = 0;
15 > while (true) {
16 > index = (index + get_6bit_random()) % 62;
17 > output << char_array[index];
18 > }
19 >
20 > Done, no bits wasted. Should have perfect distribution also. We also don't
21 > have to throw away random data just to stay within unaligned boundaries.
22 > The unalignment is being taken over into the next loop so the "error"
23 > corrects itself over time (it becomes distributed over the whole set).
24
25 It is worth noting that my approach has the tendency of generating random
26 characters in sequence. I think there are several possibilities to fix this,
27 one being swapping two elements in the char array on each access. That fixed
28 this particular problem in my tests. Here's are quick ruby snippet I played
29 with:
30
31 $ cat random.rb
32 # danger: ugly code ahead
33 dist = [0] * 62
34 seq = [0, 0]
35 chars = [*('A'..'Z'), *('a'..'z'), *('0'..'9')]
36 orig_chars = chars.dup
37
38 index = 0
39 old = nil
40 (62 * 10).times do
41 # generate random wrapped index
42 index = (index + rand(64)) % 62
43
44 # swap two indexed positions and output the char
45 chars[0], chars[index] = chars[index], chars[0]
46 $stdout.write chars[0]
47
48 # count the generated indexes
49 dist[index] = dist[index] + 1
50
51 # count if indexes were generated in sequence by looking
52 # them up in the original sorted chars array
53 unless old.nil?
54 seq[0] = seq[0] + 1 if old < orig_chars.index(chars[0])
55 seq[1] = seq[1] + 1 if old > orig_chars.index(chars[0])
56 end
57 old = orig_chars.index(chars[0])
58 end
59 puts
60
61 # check the average, it should always equal the loop count
62 # multiplicator
63 avg = dist.inject(:+) / 62.0
64
65 # calculate if the algorithm preferred sequences
66 seq = [*seq, seq[0] - seq[1]]
67
68 # output some stats
69 puts avg
70 puts dist.inspect
71 puts dist.map {|v| avg - v }.inspect
72 puts seq.inspect
73
74
75 --
76 Replies to list only preferred.

Replies

Subject Author
Re: [gentoo-user] Re: OT: Mapping random numbers (PRNG) thegeezer <thegeezer@×××××××××.net>