PHP rand () ... получить истинные результаты 50/50? - PullRequest
8 голосов
/ 18 марта 2009

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

Спасибо.

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

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

Ответы [ 15 ]

30 голосов
/ 18 марта 2009

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

mt_rand(0,1);

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

Цитата про mt_rand:

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

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

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

10 голосов
/ 18 марта 2009

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

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

Оригинальный ответ: Функция PHP rand () не является особенно хорошим генератором псевдослучайных чисел (см. Простой визуальный пример ). Я бы порекомендовал mt_rand () .

2 голосов
/ 18 марта 2009

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

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

$val = 1 - $val;

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

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

и т.д ...

2 голосов
/ 18 марта 2009

Оба (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);

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

1 голос
/ 18 марта 2009

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

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

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

Скажем, вы заработали 50 000 долларов на странице А с 43 посещениями и 46 000 долларов на странице B с 38 посещениями, вы просто делаете математику ...

Page A                      Page B

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

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

1 голос
/ 18 марта 2009

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

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

  1. Генерирует два случайных бита A и B.
  2. Если A == B, перейти к 1
  3. Возврат B

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

1 голос
/ 18 марта 2009

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

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

1 голос
/ 18 марта 2009

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

0 голосов
/ 18 марта 2009

Это ответ на ваш комментарий к исходному сообщению:

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

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

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

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

0 голосов
/ 18 марта 2009

Это 10101010 не случайно, это шаблон.
результат = не результат

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