Почему при использовании $RANDOM результаты распределяются неравномерно?

Usandogrep:

grep -f /dir1/dir2/file.csv /dir1/dir2/*

Esto extraerá patrones de su archivo .csvy los buscará en los archivos ubicados en /dir1/dir2. Sugiero no tener su.csv en el mismo directorio que desea buscar, de lo contrario, será una coincidencia. Si desea buscar recursivamente dentro de dir2, agregue el indicador -ra grep.

14
05.07.2019, 18:26
2 ответа

Чтобы расширить тему смещения по модулю, ваша формула:

max=$((6*3600))
$(($RANDOM%max/3600))

И в этой формуле $RANDOMявляется случайным значением в диапазоне 0 -32767.

   RANDOM Each time this parameter is referenced, a random integer between
          0 and 32767 is generated.

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

0 = 0-3599
1 = 3600-7199
2 = 7200-10799
3 = 10800-14399
4 = 14400-17999
5 = 18000-21599
0 = 21600-25199
1 = 25200-28799
2 = 28800-32399
3 = 32400-32767

Итак, в вашей формуле вероятность для 0, 1, 2 вдвое больше, чем для 4, 5. И вероятность 3 также немного выше, чем для 4, 5. Отсюда ваш результат с 0, 1, 2 в качестве победителей и 4, 5 в качестве проигравших.

При смене на 9*3600получается как:

0 = 0-3599
1 = 3600-7199
2 = 7200-10799
3 = 10800-14399
4 = 14400-17999
5 = 18000-21599
6 = 21600-25199
7 = 25200-28799
8 = 28800-32399
0 = 32400-32767

1 -8 имеют одинаковую вероятность, но все еще есть небольшое смещение для 0, и, следовательно, 0 все еще был победителем в вашем тесте со 100 000 итераций.

Чтобы исправить смещение по модулю, вы должны сначала упростить формулу (если вы хотите только 0 -5, тогда по модулю будет 6, а не 3600 или даже более безумное число, в этом нет смысла ). Одно только это упрощение уменьшит вашу погрешность на много (32766 карт до 0, 32767 до 1, что даст крошечную погрешность этим двум числам ).

Чтобы полностью избавиться от предвзятости, вам нужно повторно -бросить, (например, ), когда $RANDOMменьше, чем 32768 % 6(, исключить состояния, которые не полностью соответствуют доступному случайному диапазону ).

max=6
for f in {1..100000}
do
    r=$RANDOM
    while [ $r -lt $((32768 % $max)) ]; do r=$RANDOM; done
    echo $(($r%max))
done | sort | uniq -c | sort -n

Результат проверки:

  16425 5
  16515 1
  16720 0
  16769 2
  16776 4
  16795 3

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

37
27.01.2020, 19:50

Это смещение по модулю. Если RANDOMсоставлен правильно, каждое значение от 0 до 32767 создается с равной вероятностью. Когда вы используете модуль, вы изменяете вероятности :вероятности всех значений выше модуля добавляются к значениям, которым они соответствуют.

В вашем примере 6×3600 составляет примерно две трети диапазона значений. Таким образом, вероятности верхней трети складываются с вероятностями нижней трети, а это означает, что значения от 0 до 2 (приблизительно )будут получены в два раза чаще, чем значения от 3 до 5. 9×3600 — это почти 32767, поэтому смещение по модулю намного меньше и влияет только на значения от 32400 до 32767.

Чтобы ответить на ваш главный вопрос, по крайней мере в Bash случайная последовательность полностью предсказуема, если вы знаете начальное число. См. intrand32в variables.c.

23
27.01.2020, 19:50

Теги

Похожие вопросы