Math.random重复自己

时间:2016-02-19 06:40:58

标签: java math random

到目前为止,我的代码几乎都在努力工作。说明在方法之上。我遇到的唯一问题是Math.random();多次调用时会重复。我想知道是否存在阻止Math.random();重复自身的解决方案;

/**
 * Apply an "efficient selection shuffle" to the argument.
 * The selection shuffle algorithm conceptually maintains two sequences
 * of cards: the selected cards (initially empty) and the not-yet-selected
 * cards (initially the entire deck). It repeatedly does the following until
 * all cards have been selected: randomly remove a card from those not yet
 * selected and add it to the selected cards.
 * An efficient version of this algorithm makes use of arrays to avoid
 * searching for an as-yet-unselected card.
 * @param values is an array of integers simulating cards to be shuffled.   
 */
public static void selectionShuffle(int[] values) {
    ArrayList<Integer> temp=new ArrayList<Integer>();
    int size=52;
    for(int j=0;j<size;j++){
        /*int random=(int)(Math.random()*51);
        temp.add(random);
        values[j]=temp.get(j);*/
        int random=(int)(Math.random()*51);
        temp.add(values[random]);
        values[j]=temp.get(j);
    }
}

6 个答案:

答案 0 :(得分:3)

如果你想要随机顺序的整数0-51而没有重复:

  • 按顺序将这些数字添加到列表中
  • 在该列表中拨打Collections.shuffle

根据birthday paradox,简单地使用(int) (52 * Math.random()) 51次将几乎保证会重复某些数字(当然,有些数字会丢失)。

答案 1 :(得分:0)

据我所知,您认为Math.random正在“重复”,因为您总是选择0到51之间的新数字来添加到values数组中。在您有机会选择这些数字之前,您将覆盖values数组的早期部分。

考虑说明中概述的流程。如果您在每次迭代时从初始数组中选择一次,并将这些选择移动到新的temp数组中,那么每次values不应该变小?也许你并不总是想要一个0-51的随机数。

忽略所有告诉你不同方法进行洗牌的人。显然,你正在尝试实现编码实践所给出的算法。

答案 2 :(得分:0)

不确定您的问题是什么,但请尝试使用java.util.Random。

public static void selectionShuffle(int[] values)
{
    ArrayList<Integer> temp=new ArrayList<Integer>();
    Random randomGenerator = new Random();

    int size=52;

    for(int j=0;j<size;j++){
        // If you wan to generate a random number up to a maximum value,
        // use randomGenerator.nextInt(maximum) instead
        int random = randomGenerator.nextInt() * 51;
        temp.add(values[random]);
        values[j]=temp.get(j);
    }
}

答案 3 :(得分:0)

当数字是随机的时,每个数字都有相同的发生几率,而不管之前发生的事情。这意味着随机数必须能够重复,或者它们不再是真正随机的。

如果你想要一组数字,卡片,歌曲以随机顺序出现而不重复,这就叫做shuffle。注意:最后一个号码,卡片或歌曲根本不是随机的,因为它将是剩下的唯一一个。

使用随机序列,您甚至可以多次出现相同的数字。

http://vanillajava.blogspot.co.uk/2011/10/randomly-no-so-random.html

Random random = new Random(441287210);
for (int i = 0; i < 10; i++)
    System.out.print(random.nextInt(10)+" ");

打印

1 1 1 1 1 1 1 1 1 1

Random random = new Random(-6732303926L);
for(int i = 0; i < 10; i++)
    System.out.print(random.nextInt(10)+" ");

打印

0 1 2 3 4 5 6 7 8 9

答案 4 :(得分:0)

据我所知,您不希望Math.random()多次返回一个数字。如果这是问题,我们要做的是允许Math.random()返回它喜欢的任何内容,但我们只使用非重复的数字。

试试这个:

public static void selectionShuffle(int[] values) {
    ArrayList<Integer> temp=new ArrayList<Integer>();
    int size=52;
    Integer a[]=new Integer[size];
    for(int j=0;j<size;j++){
        int random=(int)(Math.random()*51);
        if(a.[random]==null) //to ensure that only unique nos. are used.
        {
        temp.add(values[random]);
        values[j]=temp.get(j);
        a.[random]=1;
        // the above code will only be executed if `a[random]` is null
        //ensures that this executes only when unique number is generated
    }
    else
    {
      j--; 
    //so that 52 iterations occur successfully. We don't want any iteration to go waste.
    }
 }

我使用了Integer数组来确保使用唯一的数字。每次生成唯一编号时,我们都会将1或其他整数分配给整数数组的特定索引。只有在a[]'s生成的整数对应的索引处未设置random值时,才会执行相关代码。

答案 5 :(得分:0)

你想在没有替换的情况下进行随机抽签,但是你已经实施了随机抽奖......

将牌放入52号阵列中,然后在第一次抽牌中执行以下操作:

(int)(Math.random()*51 + 1);

这给你一个介于1-52之间的随机数,比如你得到4,然后通过删除第四个元素来更新数组,留下你的大小为51的数组。然后进行第二次抽奖:

(int)(Math.random()*50 + 1);

等等......