C ++ вычисление вероятности события - PullRequest
1 голос
/ 27 марта 2019

Я пытаюсь смоделировать столкновение с дикими покемонами. Как указано в формуле:

The rate of Pokémon encounter is determined from a simple mathematical formula:
1 in (187.5 / ( x )) per step.

Let x equal the a value which determines how rare the Pokémon is. The higher the encounter rate, 
the more common the Pokémon is.

Encounter-rate Table
Encounter type Encounter rate
Very common     10
Common          8.5
Semi-rare       6.75
Rare            3.33
Very rare       1.25

Я хочу использовать эту вероятность после каждого нажатия кнопки. Как мне смоделировать это с rand()?

Ответы [ 2 ]

1 голос
/ 27 марта 2019

Я бы сделал это так

Отображение ранда ()

rand() / (float)RAND_MAX

Rand() возвращает значение от 0 до RAND_MAX, поэтому эта формула отображает 0 -> RAND_MAX в 0 -> 1

(float) используется для того, чтобы сделать RAND_MAX float, потому что значение, возвращаемое rand(), равно int, а int / int в c ++ возвращает int

(rand() / (float)RAND_MAX) * 10 

Если вы умножите результат на 10, он отобразит rand() из 0 -> 10

(rand() / (float)RAND_MAX) * 187.5

Это будет карта rand() из 0 -> 187.5

1 в 187,5

Мы сопоставили значение rand() с 0 -> 187.5

Теперь каждый раз, когда мы звоним rand(), он возвращает случайное число от 0->187.5

Для упрощения, скажем, мы отображаем rand() из 0 -> 200

Вероятность того, что rand() вернет число ниже 100, будет равной 1/2, потому что каждое число в диапазоне от 0 до> 200 имеет равный шанс на возвращение (например, rand() может вернуть 25,67, или 100,9, или 140,6. )

( (rand() / (float)RAND_MAX) * 187.5 ) < 1

По тому же принципу существует вероятность 1 из 187,5, что возвращаемое число меньше 1

Окончательное решение

Нам по-прежнему не хватает 1 в 187,5 / X

Чтобы реализовать частоту встреч, вам просто нужно изменить отображение с 0 -> 187.5 на

0 -> 187.5 / X

Мы можем видеть, что если X большой, это означает, что существует высокий уровень столкновения, и 187,5 становится меньше, а возвращаемое число имеет более высокий шанс быть меньше, чем 1, но если частота столкновений низкая, X становится маленьким, и 187,5 получает больше (меньший шанс быть меньше 1)

Финальный код

srand (time(NULL)); // Init rand() with a seed
bool encountered = ( (rand() /  (float)RAND_MAX) * (187.5 / x) ) < 1

Оптимизация

Пользователь указал, что с последним кодом вам нужно вычислить 5 rand () для каждого события, но если немного подправить формулу, вы можете вычислить только 1 rand()

Используя простую математику, вы знаете, что событие, которое происходит один раз (1) за 10/2 шагов событие, которое происходит дважды в (2) за 10 шагов

Таким образом, событие, которое происходит один раз (1) в шагах 187,5 / X, происходит (1 * X) в шагах 187,5

Если мы отобразим rand () из 0 -> 187.5, то для каждого покемона мы сможем вычислить уникальное значение для него, используя только одну rand ()

float randomNumber      = (rand() / (float)RAND_MAX) * 187.5
bool encountedPokemon1  = randomNumber < 1 * encounter_rate_first_pokemon
bool encountedPokemon2  = randomNumber < 1 * encounter_rate_second_pokemon
0 голосов
/ 27 марта 2019

используйте оператор по модулю. rand () вернет число от 0 до максимального значения, которое может содержать целое число. поэтому rand ()% 10 вернет число от 0 до 9.

(rand ()% 1875) <= 10 должно быть истинным 1 из 187,5 раз (или 10 из 1875) </p>

Если вы еще не знаете,% даст вам остаток. Таким образом, x% 10 не может быть больше 9.

Вот ссылка

...