У меня есть метод, который использует случайные выборки для приближения вычисления. Этот метод называется миллионы раз, поэтому очень важно, чтобы процесс выбора случайных чисел был эффективным.
Я не уверен, насколько быстрыми javas Random().nextInt действительно, но моя программа, похоже, не приносит столько пользы, как мне бы хотелось.
При выборе случайных чисел я делаю следующее (в полу псевдокоде):
// Repeat this 300000 times
Set set = new Set();
while(set.length != 5)
    set.add(randomNumber(MIN,MAX));
Теперь у этого, очевидно, плохое время ожидания худшего случая, так как случайная функция в теории может добавлять повторяющиеся числа в течение вечности, оставаясь во время цикла навсегда. Однако числа выбираются из {0..45}, поэтому дублирующее значение в большинстве случаев маловероятно.
Когда я использую вышеуказанный метод, его только на 40% быстрее, чем мой другой метод, который не приближается, но дает правильный результат. Это пробегает ~ 1 миллион раз, поэтому я ожидал, что этот новый метод будет как минимум на 50% быстрее.
Есть ли у вас предложения по более быстрому методу? Или, может быть, вы знаете более эффективный способ генерации набора случайных чисел.
Чтобы уточнить, вот два метода:
// Run through all combinations (1 million). This takes 5 seconds
 for(int c1 = 0; c1 < deck.length; c1++){
    for(int c2 = c1+1; c2 < deck.length; c2++){
     for(int c3 = c2+1; c3 < deck.length; c3++){
        for(int c4 = c3+1; c4 < deck.length; c4++){
         for(int c5 = c4+1; c5 < deck.length; c5++){
             enumeration(hands, cards, deck, c1, c2, c3, c4, c5);
         }
            } 
      }     
   }
   }
// Approximate (300000 combinations). This takes 3 seconds
Random rand = new Random();
HashSet<Integer> set = new HashSet<Integer>();
int[] numbers = new int[5];
while(enumerations < 300000){
set.clear();
while(set.size() != 5){
    set.add(rand.nextInt(deck.length));
}
Iterator<Integer> i = set.iterator();
int n = 0;
while(i.hasNext()){
    numbers[n] = i.next();
    n++;
}
После некоторого тестирования и профилирования я нашел этот метод наиболее эффективным:
Random rand = new Random();
int[] numbers = new int[5];
ArrayList<Integer> list = new ArrayList<Integer>();
while(enumerations < 300000){
 while(list.size() != 5) {
     int i = rand.nextInt(deck.length);
        if(!list.contains(i)) list.add(i);
 }
 int index = 0;
 for(int i : list){ numbers[index] = i; index++; }
 enumeration(hands, cards, deck,numbers);
}