Java.util.Collection.Shuffle在使用种子随机变量时不生成随机结果

Java.util.Collection.Shuffle在使用种子随机变量时不生成随机结果,java,random,collections,Java,Random,Collections,给定以下代码: List<Integer> consensusGroupOrder = new ArrayList<>(); for (int i = 0; i < numberOfItems; i++) { consensusGroupOrder.add(i + 1); } Collections.shuffle(consensusGroupOrder, new Rando

给定以下代码:

        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);
        }
递增种子,列表中的第四项始终为3。种子=5:

{
  "1": 4,
  "2": 1,
  "3": 2,
  "4": 3
}
种子=10:

{
  "1": 2,
  "2": 4,
  "3": 1,
  "4": 3
}
种子=255:

{
  "1": 1,
  "2": 2,
  "3": 4,
  "4": 3
}
我是随机播种,因为我需要根据种子确定结果,但为什么第四项总是3?只有当seed=256时,第四项才会更改

我发现了这个问题,答案是随机调用nextInt():


在使用随机数之前调用nextInt()感觉就像是将问题沿着种子值踢了一段时间,然后它又会在某个地方发生?

你真倒霉!第一个正种子将非3种子拖移到最后一个位置是256。你自己试试这段代码,找出将非3种子拖到最后一个位置的前10个种子

public class Main {

  public static void main(String[] args) {
    IntStream.range(0, 1_000_000).filter(Main::lastPositionIsNot3).limit(10).forEach(System.out::println);
  }

  public static boolean lastPositionIsNot3(long seed) {
    List<Integer> consensusGroupOrder = new ArrayList<>();

    int numberOfItems = 4;
    for (int i = 0; i < numberOfItems; i++) {
      consensusGroupOrder.add(i + 1);
    }
    Collections.shuffle(consensusGroupOrder, new Random(seed));

    return consensusGroupOrder.get(3) != 3;
  }
}
这是我打印的750404。预计约有四分之三的种子不会拖到最后。实际数量比我们预期的多404粒(0.05%)。如果你检查种子的整个范围(0到2^48-1)并计算有多少个非-3种子被洗牌到最后,我预计这个百分比会低很多


简言之,前256个种子的样本量太小,无法说明种子的分布情况。

我只是同意作者提出的解决方案:

List consensusGroupOrder=new ArrayList();
对于(int i=0;i
这是否回答了您的问题@onkarruikar谢谢,但我希望随机性取决于种子,所以不确定这是否有帮助?谢谢。我不确定我是否完全理解,但假设我想用100个相邻种子的范围来创建一个均匀分布,我会将种子乘以某个值吗?@SteveFord我想你需要知道有多少种子-其中2^48个!前256个种子都将a 3拖到最后一个位置,这很难被称为“不均匀”。如果你想让25个种子将a 3拖到最后,25个种子将a 2拖到最后,25个种子将a 1拖到最后,25个种子将a 4拖到最后,那么你应该通过试错法找到这100个种子。@SteveFord在那一点上,你还能称它为“随机”吗?为什么不把[1,2,3,4]的100个排列硬编码成你想要的排列分布,然后从中选择呢?:)
public class Main {

  public static void main(String[] args) {
    IntStream.range(0, 1_000_000).filter(Main::lastPositionIsNot3).limit(10).forEach(System.out::println);
  }

  public static boolean lastPositionIsNot3(long seed) {
    List<Integer> consensusGroupOrder = new ArrayList<>();

    int numberOfItems = 4;
    for (int i = 0; i < numberOfItems; i++) {
      consensusGroupOrder.add(i + 1);
    }
    Collections.shuffle(consensusGroupOrder, new Random(seed));

    return consensusGroupOrder.get(3) != 3;
  }
}
long count = IntStream.range(0, 1_000_000).filter(Main::lastPositionIsNot3).count();
System.out.println(count);
        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);
        }