генерация случайных чисел в Java - PullRequest
1 голос
/ 13 марта 2010

Я хочу создать 30 таблиц, которые состоят из следующих полей. Например,

Service_ID   Service_Type     consumer_feedback 
  75           Computing        1                 
  35           Printer          0                 
  33           Printer         -1                
3 rows in set (0.00 sec)
mysql> select * from consumer2;
Service_ID   Service_Type     consumer_feedback   
  42           data             0
  75           computing        0
mysql> select * from consumer3;
Service_ID   Service_Type     consumer_feedback 
  43           data            -1
  41           data             1 
  72           computing       -1

Как вы можете сделать вывод из приведенных выше таблиц, я получаю значения обратной связи. Я сгенерировал эти consumer_feedback значения, Service_ID, Service_Type, используя концепцию случайных чисел. Я использовал функцию:

int min1=31;//printer
int max1=35;//the values are generated if the Service_Type is printer.
int provider1 = (int) (Math.random() * (max1 - min1 + 1) ) + min1;
int min2=41;//data
int max2 =45
int provider2 = (int) (Math.random() * (max2 - min2 + 1) ) + min2;
int min3=71;//computing
int max3=75;
int provider3 = (int) (Math.random() * (max3 - min3 + 1) ) + min3;        
int min5 = -1;//feedback values
int max5 =1;
int feedback = (int) (Math.random() * (max5 - min5 + 1) ) + min5;

Мне нужно, чтобы Service_Types был равномерно распределен по всем 30 таблицам. Точно так же мне нужно, чтобы значение обратной связи 1 было сгенерировано много раз, кроме 0 и -1.

Ответы [ 4 ]

2 голосов
/ 13 марта 2010

Если у вас есть 30 чисел и вам нужно, чтобы эти 30 чисел были найдены вашим методом, тогда генератор случайных чисел не подойдет вам. В этом случае, я думаю, было бы более целесообразно добавить эти 30 чисел в список и вызвать метод [Collections.shuffle] [1], чтобы перетасовать содержимое списка, а затем просто просмотреть его с помощью блока for ... each , Если вы хотите получить действительно случайные числа, то вам следует использовать класс Random, как объяснил Стивен.

Просто помните, что вы НЕ должны создавать новый экземпляр класса Random каждый раз, когда вам нужно случайное число:

public Random()

Creates a new random number generator. Its seed is initialized to a value based on the current time:

   public Random() { this(System.currentTimeMillis()); }

Two Random objects created within the same millisecond will have the same sequence of random numbers.

С http://java.sun.com/j2se/1.4.2/docs/api/java/util/Random.html#Random()

Рекомендуется использовать Random.nextInt(int n) с максимальным целочисленным значением, поскольку обычная практика Random.nextInt() % n не генерирует равномерно распределенные числа.

Если вам нужно число от 50 до 100, это просто так:

Random r = new Random();
public int yourMethod() {
   return r.nextInt(50) + 50;
}

[1]: http://java.sun.com/j2se/1.4.2/docs/api/java/util/Collections.html#shuffle(java.util.List, java.util.Random)

1 голос
/ 13 марта 2010

Под капотом Math.random() использует экземпляр java.util.Random для генерации чисел. Вы можете избежать путаницы в отображении двойных чисел в целые, напрямую используя API-интерфейс Random:

Сделайте что-то вроде этого:

import java.util.Random;

...

private static Random prng = new Random();

...

int min1=31;//printer

int  max1=35;//the values are generated if the Service_Type is printer.

int provider1 = prng.nextInt(max1 - min1 + 1) + min1;

Конечно, число, сгенерированное Random, не очень случайное, но оно вполне достаточно для вашего случая использования. Тем не менее, мне интересно, разве вы не добьетесь большего успеха, используя стратегию «Round Robin» для распределения нагрузки между устройствами.

0 голосов
/ 14 марта 2010

В принципе, у вас может быть список кодов consumer_feedback (равномерно распределенных), а затем вы удаляете из него коды, но с использованием случайного индекса, чтобы вы могли гарантировать точное количество каждого кода consumer_feedback, который вы хотите связать с «Сервисами».

Это код Groovy, который иллюстрирует концепцию:

Предположения:

  • 99 записей услуг
  • 3 различных кода обратной связи для потребителей

Чтобы иметь равное распределение, я должен назначить код «consumer_feedback» 33 «Сервисам» и сделать это для каждого. (Для простоты я выбираю числа, кратные 3, поскольку у вашего вопроса было 3 кода consumer_feedback)

//Creating the pool of available feedback codes 
feedbacks = []
feedback = 0;
3.times {
    33.times {
        feedbacks << feedback
    }
    feedback++
}

rnd = new Random()

idx = 0
services = [:]
99.times {
    services["Service_${idx++}"] =
        feedbacks.remove(rnd.nextInt(feedbacks.size()))
}

println Collections.frequency(services.values(), 0)
println Collections.frequency(services.values(), 1)
println Collections.frequency(services.values(), 2)

println services
0 голосов
/ 13 марта 2010

Редактировать: Этот ответ основан на неправильном прочтении вопроса, где я взял "много раз, кроме 0 и -1", чтобы обозначить "много больше раз, чем 0 и -1" . Я оставляю этот ответ на тот случай, если он пригодится кому-то еще, но я сомневаюсь, что он будет полезен для оригинального постера.


Чтобы сгенерировать неоднородные случайные числа, вам необходимо указать, какие веса должны быть. Например, возможно, вы хотите, чтобы в 1 было в три раза больше единиц, чем в 0 или -1.

Вот метод, который принимает массив из трех double значений, где первое значение является весом для -1, второе значение является весом для 0, а третье значение является весом для 1. Это будет сгенерируйте -1, 0 или 1 с различной вероятностью на основе заданных вами весов.

public int minusOneZeroOrOne(final double[] weights)
{
    if (weights.length != 3)
        throw new IllegalArgumentException("Must provide three weights");
    double weightTotal = 0.0;
    for (final double next : weights)
        weightTotal += next;
    double random = Math.random() * weightTotal;
    if (random < weights[0])
        return -1;
    if (random < (weights[0] + weights[1]))
        return 0;
    return 1;
}

Я проверил этот метод, вызвав его с массивом веса { 1.0, 1.0, 3.0 } (то есть в три раза больше 1, чем 0 или -1), сто тысяч раз, и я получил следующие результаты:

$ java RandomTest | sort | uniq -c
  20062 -1
  19776 0
  60162 1

Как видите, я получил примерно в три раза больше результатов "1", чем результатов "0" или "-1".

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...