Not logged in.  Login/Logout/Register | List snippets | | Create snippet | Upload image | Upload data

67
LINES

< > BotCompany Repo | #1035206 // WeightlessShuffledIterator - iterate over list in random order using an LSFR (iterator is OSPACE(1))

JavaX fragment (include) [tags: use-pretranspiled]

Transpiled version (9372L) is out of date.

1  
// Deterministic shuffled list iterator using an XORSHIFT RNG
2  
// Each step is O(1), iterator is OSPACE(1)
3  
4  
// This iterator doesn't have a seed parameter and is completely
5  
// deterministic with respect to a given list size.
6  
// If you want to pass a seed, use WeightlessShuffledIteratorWithSeed.
7  
8  
// Performance: Takes between 5 and 18 ns per nextIndex() on a laptop
9  
//              and between 2 and 11 ns on a desktop CPU.
10  
//              (these numbers are actually for WeightlessShuffledIteratorWithSeed,
11  
//              WeightlessShuffledIterator itself is a tiny bit faster.)
12  
13  
sclass WeightlessShuffledIterator<A> extends ItIt<A> is IndexIterator {
14  
  final L<A> list;
15  
  final int n;
16  
  final int bits, cycleLength, a, b, c;
17  
  
18  
  int i; // step counter
19  
  
20  
  // now doing the TripletLSFR stuff directly in here
21  
  int value;
22  
  
23  
  // initialize only with a length (i.e. list containing 0, 1, ...)
24  
  // if you are going to be calling nextIndex() instead of next()
25  
  *(int n) {
26  
    this((L) iotaZeroList(n));
27  
  }
28  
  
29  
  // initialize with a list to shuffle
30  
  *(L<A> *list) {
31  
    n = l(list);
32  
    if (n == 0) ret with a = b = c = bits = cycleLength = 0;
33  
    bits = numberOfBitsNeededToRepresentNOptions(n+1);
34  
    var lsfr = new TripletLSFR(bits);
35  
    meta-for a also as b, c, value, cycleLength { a = lsfr.a; }
36  
  }
37  
  
38  
  public bool hasNext() { ret i < n; }
39  
  
40  
  public A next() {
41  
    ret list.get(nextIndex());
42  
  }
43  
  
44  
  // you can call nextIndex() without having checked hasNext(),
45  
  // then it will just return -1 when the iteration is complete.
46  
  public int nextIndex() {
47  
    if (i >= n) ret -1;
48  
    ++i;
49  
    
50  
    int raw;
51  
    do {
52  
      int x = value;
53  
      x ^= (x << a) & cycleLength;
54  
      x ^= x >>> b;
55  
      x ^= (x << c) & cycleLength;
56  
      value = x;
57  
      raw = postProcessLSFRValue(x-1);
58  
    } while (raw >= n);
59  
    
60  
    ret raw;
61  
  };
62  
  
63  
  int bits() { ret bits; }
64  
  
65  
  // overridable in subclasses
66  
  int postProcessLSFRValue(int i) { ret i; }
67  
}

Author comment

Began life as a copy of #1017660

download  show line numbers  debug dex  old transpilations   

Travelled to 4 computer(s): bhatertpkbcr, ekrmjmnbrukm, mowyntqkapby, mqqgnosmbjvj

No comments. add comment

Snippet ID: #1035206
Snippet name: WeightlessShuffledIterator - iterate over list in random order using an LSFR (iterator is OSPACE(1))
Eternal ID of this version: #1035206/40
Text MD5: f880683492c99eaecdfe76ee643642db
Author: stefan
Category: javax
Type: JavaX fragment (include)
Public (visible to everyone): Yes
Archived (hidden from active list): No
Created/modified: 2023-02-12 14:31:28
Source code size: 2019 bytes / 67 lines
Pitched / IR pitched: No / No
Views / Downloads: 293 / 531
Version history: 39 change(s)
Referenced in: [show references]