PHP rand () ... получить истинные результаты 50/50?

Я хочу запустить функцию, которая имеет 2 разных результата, но я хочу, чтобы каждый результат был действительно 50%. Я предполагаю, что rand (0,1) - это путь, но мне любопытно, может ли это благоприятствовать одному над другим. Каков наилучший способ получить результат 50/50?

спасибо.

изменить: спасибо, ребята, я не хочу, чтобы он хотя бы случайно, я хочу исход 101010101 не 111001101. Возможно, я должен просто обновить базу данных с последним выводом значения, а затем вернуть напротив?

EDIT2: Хорошо, мне жаль, что мое последнее редактирование вводило в заблуждение. Я вызываю функцию только один раз для каждого пользователя и назначаю это значение как cookie пользователю. Я хочу, чтобы каждый посетивший пользователь получил 1 или 0 в заказе 1010101.

15 ответов


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

простой способ переключения значения:

$val = 1 - $val;

для вызова базы данных:

UPDATE YourTable SET `next_value` = 1 - `next_value`

etc...


в PHP mt_rand() лучший генератор случайных чисел!--5-->

mt_rand(0,1);

достаточно и должно генерировать довольно хорошее значение 50/50.

цитата о mt_rand:

многие генераторы случайных чисел в старых libcs имеют сомнительные или неизвестные характеристики и работают медленно. По умолчанию PHP использует генератор случайных чисел libc с функцией rand (). Функция mt_rand () является заменой для этого.

он использует генератор случайных чисел с известными характеристиками, используя " Mersenne Twister, который будет производить случайные числа в четыре раза быстрее, чем то, что обеспечивает средний libc rand ().

У Билла была хорошая ссылка на визуальный пример. Я не знаю, какой PHP был у пользователя для PHP, но поскольку он включил код, я разместил его на своем сервере (Linux с PHP 5.1.6)


ответ на отредактированный вопрос: Если вы хотите поддерживать точное соотношение 50%, то случайность-это последнее, что вы хотите. Для ваших целей вы, вероятно, просто хотите назначить каждому новому пользователю (не обнаружен файл cookie) автономер из вашей базы данных, а затем дать четному пользователю одну страницу и нечетному пользователю другую страницу (как предложил Робс в комментарии).

if( ($user_id % 2) == 0 )
    // user id is even
else
    // user id is odd

оригинальный ответ: функция RAND () PHP не является особенно хорошей генератор псевдослучайных чисел (см.--8-->Простой Визуальный Пример). Я бы рекомендовал mt_rand ().


оба (rand () и mt_rand ()) возвращают хороший шанс 50%/50%.

вот пример:

$array1 = array(0,0);
$array2 = array(0,0);

for ($x = 0; $x < 10000; $x++) {
  $array1[mt_rand(0,1)] ++;
  $array2[rand(0,1)] ++;
}

print_r($array1);
print_r($array2);

результаты:

Array 1 (mt_rand):
  [0] => 4910
  [1] => 5090
Array 2 (rand):
  [0] => 4970
  [1] => 5030

согласно просьбе автора, он хочет справедливого распределения. Поэтому попробуйте что-то вроде этого:

$digits = 200;
$array = array_fill(0, $digits/2, 0); 
for ($x = 0; $x < $digits/2; $x++)
  $array[] = 1;
shuffle($array);

равное распределение и достаточно случайное. (Предложение Брайана)


по данным руководство по php rand (0,1) - это путь. Но все зависит от того, насколько хорош генератор случайных чисел.


ничего действительно 50/50. Если вы хотите 50/50, сделайте функцию так, чтобы первые 5 результатов были 1, а другие 5-2 и т. д.

rand предназначен для генерации случайных чисел. Это означает, что он может дать 10 раз один и тот же результат подряд, но эй, это случайно.


отказ от ответственности: это глупо делать для вашей конкретной проблемы, но если вы настаиваете на недоверии к генератору случайных чисел, чтобы быть равномерно распределены...

классический алгоритм для генерации результата 50/50, когда вы не доверяете, что ваш генератор будет равномерно распределен, - это следующий алгоритм. Имейте в виду, что этот алгоритм больше предназначен для фиксации случайных чисел, чем псевдослучайных чисел и может фактически сделать результаты на основе mod хуже:

  1. генерировать два случайных бита A и B.
  2. если A==B, goto 1
  3. Возврат B

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


RobS имеет хорошее решение в комментариях, в основном говоря, что каждый пользователь может получить последовательный номер, затем, используя это число % 2, вы получите 0 или 1, который определит, какую страницу обслуживать. Конечно, даже это не совсем гарантированно дает точно соотношение 50/50...это может быть нечетное количество людей!

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

для вас есть альтернативное решение, где вам не придется беспокоиться о нечетных неожиданных корреляциях: на основе ваших комментариев и измененного вопроса Вы просто пытаетесь получить справедливое сравнение анализа между тем, насколько эффективны два разных макета страниц, вы можете просто разделить продажи каждого макета страницы на количество раз, когда он был случайным образом подан. т. е. вы используете свое случайное число генератор, и следите за тем, сколько раз он дает 0, чтобы обслуживать страницу A, и сколько раз он дает 1, чтобы обслуживать страницу B.

Page A                      Page B

50000                       46000
----- = 1163 $/hit          ----- = 1211 $/hit
  43                          38

давая странице B небольшое преимущество.


может быть, вы можете попробовать mt_rand (0,1) вместо Рэнд(0,1)


псевдослучайность никогда не может быть истинной случайностью. Каждое вычисление случайных чисел, основанное на семени или другими средствами, имеет некоторый уровень предопределенности, который может проявляться или не проявляться очевидным образом-например, мини - паттерны. Лучшее, что вы можете надеяться, это почти 50/50.


хотя это псевдослучайный генератор, он никогда не достигнет 50/50 ... читайте sth. о генераторах случайных чисел здесь:http://www.robertnz.net/true_rng.html


Если вы просто хотите чередовать 1 и 0:

$n = 0;
$myval = ($n==1 ? $n=0 : $n=1);

Если вы серьезно хотите вернуть обратное значение на каждой итерации...

function flip() {
    static $truthiness = false;
    $truthiness = !$truthiness;
    return $truthiness;
}

который должен возвращать true, false, true, false, true и т. д...

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

кроме того, если вы не знаете, что делает ключевое слово static, см. Запись руководства PHP на переменная.


это 10101010 не случайно, это шаблон.
result = не result


Это в ответ на ваш комментарий на ваш исходный пост:

ваша цель, чтобы увидеть, какая версия страницы генерирует больше продаж.

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

хотя я не могу представить какой-либо причины для систематического смещения с вашим методом, вы не можете это исключить. (надуманный сценарий: некоторые отслеживающие боты "следуют" за пользователями на вашу страницу, и поэтому пользователь 1 получает A, бот получает B, пользователь 2 получает A, бот получает B и т. д.)

достижение лучшей случайности более разумно при проведении исследования, как вы делаете, чем убедитесь, что каждая страница отображается ровно 50% времени.