C ++计算事件的概率

问题描述 投票:1回答:2

我正在尝试模拟野生口袋妖怪的遭遇。如公式所述:

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()模拟这个?

c++ visual-c++ random probability weighted
2个回答
1
投票

我会这样做的

映射rand()

rand() / (float)RAND_MAX

Rand()返回一个从0到RAND_MAX的值,所以这个公式将0 -> RAND_MAX映射到0 -> 1

(float)用于使RAND_MAX成为一个浮点数,因为rand()返回的值是int,c ++中的int / int返回int

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

如果将结果乘以10,它将映射来自rand()0 -> 10

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

这将映射来自rand()0 -> 187.5

在187.5中的1

我们从rand()绘制了0 -> 187.5的值

现在,每当我们调用rand()时,它将从0->187.5返回一个随机数

为了简化,我们说我们从rand()映射0 -> 200

rand()将返回一个低于100的数字,因为0 - > 200之间的每个数字都有相同的返回机会(例如rand()可以返回25.67或100.9或140.6)

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

按照同样的原则,返回的数字小于1的概率为187.5

最终解决方案

我们仍然缺少187.5 / X中的1

要实现遇到率,您只需要更改0 -> 187.5 To的映射

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()

通过使用简单的数学,您知道在10/2步骤中发生一次(1)的事件是在(2)中以10个步骤发生两次的事件

因此,在187.5 / X步骤中发生一次(1)的事件以187.5步骤发生(1 * X)

如果我们从0 - > 187.5映射rand()那么对于每个小精灵,我们只用一个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
投票

使用模运算符。 rand()将返回一个介于0和整数可以容纳的最高值之​​间的数字。所以rand()%10将返回0到9之间的数字。

(rand()%1875)<= 10应该是187.5次中的1次(或1875中的10次)

如果你还不知道,%会给你余数。所以x%10永远不会大于9。

这是一个reference

© www.soinside.com 2019 - 2024. All rights reserved.