Given the following code:
List<Integer> consensusGroupOrder = new ArrayList<>(); for (int i = 0; i < numberOfItems; i++) { consensusGroupOrder.add(i + 1); } Collections.shuffle(consensusGroupOrder, new Random(seed)); int count = 1; Map<Integer, Integer> returnValue = new HashMap<>(); for(Integer group: consensusGroupOrder) { returnValue.put(count++, group); }
When I set numberOfItems to 4 and starting with a seed of 1, when dumping returnValue as Json I get:
{ "1": 4, "2": 1, "3": 2, "4": 3 }
Incrementing seed, the fourth item in the list is always 3. Seed = 5:
{ "1": 4, "2": 1, "3": 2, "4": 3 }
Seed = 10:
{ "1": 2, "2": 4, "3": 1, "4": 3 }
Seed = 255:
{ "1": 1, "2": 2, "3": 4, "4": 3 }
I am seeding Random as I need the result to be deterministic based on seed, but why is the 4th item always 3? Only when seed = 256 does the fourth item change.
I found this question, the answer is to call nextInt() on the Random: Collection.shuffle with seeded Random – anomaly with List of size 16
It feels like calling nextInt() before using the Random is just kicking the problem along the seed value for a while and again it will occur somewhere?
Advertisement
Answer
I just went with the author proposed work-around on Collection.shuffle with seeded Random – anomaly with List of size 16:
List<Integer> consensusGroupOrder = new ArrayList<>(); for (int i = 0; i < numberOfItems; i++) { consensusGroupOrder.add(i + 1); } Random r = new Random(seed); r.nextInt(); Collections.shuffle(consensusGroupOrder, r); int count = 1; Map<Integer, Integer> returnValue = new HashMap<>(); for(Integer group: consensusGroupOrder) { returnValue.put(count++, group); }