Как вычислить случайность "15% времени"? - PullRequest
4 голосов
/ 14 декабря 2010

Я ищу достойный, изящный метод вычисления этой простой логики.
Прямо сейчас я не могу думать об одном, это кружит голову.

Я обязан совершать какие-либо действия только в 15% случаев.

Я привык к "50% времени", когда я просто изменяю миллисекунды текущего времени и смотрю, чётное это или нет, но я не думаю, что это элегантно.

Как бы я элегантно рассчитал "15% времени"?Может быть, генератор случайных чисел?
Псевдокод или любой другой язык приветствуются.

Надеюсь, это не субъективно, так как я ищу "самый умный" способ сделать это.

Спасибо.

Ответы [ 8 ]

3 голосов
/ 14 декабря 2010

Решение 1 (double)

  • получить случайное двойное число от 0 до 1 (какой бы язык вы не использовали, такая функция должна быть)
  • выполнять действие, только если оно меньше, чем 0,15

Solution 2 (int)

Этого также можно добиться, создав случайное int и посмотрев,делится на 6 или 7. ОБНОВЛЕНИЕ -> Это не оптимально.

2 голосов
/ 14 декабря 2010

Вы можете создать случайное число от 0 до 99 и проверить, не меньше ли оно 15:

if (rnd.Next(100) < 15) ...

Вы также можете уменьшить числа, так как 15/100 соответствует 3/20:

if (rnd.Next(20) < 3) ...
1 голос
/ 14 декабря 2010

Генератор случайных чисел даст вам лучшую случайность.Генерация случайного числа от 0 до 1, проверка на <0,15.</p>

Использование такого времени не является случайным, так как на него влияет время обработки.Если выполнение задачи занимает менее 1 миллисекунды, то следующий случайный выбор будет таким же.

Тем не менее, если вы хотите использовать метод, основанный на миллисекундах, выполните milliseconds % 20 < 3.

1 голос
/ 14 декабря 2010

Просто используйте PRNG.Как всегда, это компромисс между производительностью и точностью.Я думаю, что заниматься своими делами прямо вне времени - пустая трата времени (каламбур).Вы, вероятно, получите эффекты смещения даже хуже, чем при работе линейного конгруэнтного генератора мельницы.

В Java я бы использовал nextInt :

myRNG.nextInt(100) < 15

Или (в основном) эквивалентно:

myRNG.nextInt(20) < 3

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

0 голосов
/ 14 декабря 2010

Вот один подход, который сочетает в себе случайность и гарантию того, что в конечном итоге вы получите положительный результат в предсказуемом диапазоне:

Иметь цель (15 в вашем случае), счетчик (инициализированный в 0) иflag (инициализируется как false).

Accept a request.
If the counter is 15, reset the counter and the flag.
If the flag is true, return negative outcome.
Get a random true or false based on one of the methods described in other answers, but use a probability of 1/(15-counter). 
Increment counter
If result is true, set flag to true and return a positive outcome. Else return a negative outcome.
Accept next request

Это означает, что первый запрос имеет вероятность 1/15 возвращаемого положительного результата, но по 15-му запросу, если положительный результат не был возвращен, есть вероятность1/1 положительного результата.

0 голосов
/ 14 декабря 2010

Эта цитата взята из замечательной статьи о том, как использовать генератор случайных чисел:

Примечание: НЕ используйте

  y = rand()  %  M;

как этофокусируется на младших битах rand ().Для линейных конгруэнтных генераторов случайных чисел, которые часто есть в rand (), младшие байты гораздо менее случайны, чем старшие байты.На самом деле младшие биты циклически изменяются между 0 и 1. Таким образом, rand () может переключаться между четным и нечетным (попробуйте).Обратите внимание, что rand () не обязательно должен быть линейным конгруэнтным генератором случайных чисел.Вполне допустимо, чтобы это было что-то лучше, без этой проблемы.

и содержит формулы и псевдокод для

  • r = [0,1)= {r: 0 <= r <1} действительный </li>
  • x = [0, M) = {x: 0 <= x <M} действительный </li>
  • y = [0, M)= {y: 0 <= y <M} целое число </li>
  • z = [1, M] = {z: 1 <= z <= M} целое число </li>
0 голосов
/ 14 декабря 2010
boolean array[100] = {true:first 15, false:rest};
shuffle(array);
while(array.size > 0)
{
    // pop first element of the array.
    if(element == true)
       do_action();
    else
       do_something_else();
}
// redo the whole thing again when no elements are left.
0 голосов
/ 14 декабря 2010

Используя арифметику по модулю, вы можете легко сделать что-то при каждом X-м прогоне, например

(6 will give you ruthly 15%

if (microtime ()% 6 ===) сделать это

другая вещь:

if(rand(0,1) >= 0.15) do it
...