Algorithm 如何根据概率选择一个数字?

Algorithm 如何根据概率选择一个数字?,algorithm,math,probability,Algorithm,Math,Probability,我想从0,1,2,3…n中选择一个随机数,但是我想让它成为选择k | 0的机会 解决此问题将为您提供: p1 + p2 + ... + pn = 1 (p2 * x) + (p3 * x) + ... + (pn * x) + pn = 1 ((p3*x) * x) + ((p4*x) * x) + ... + ((p_n-1*x) * x) + pn = 1 .... pn* (x^(n-1) + x^(n-2) + ... +x^1 + x^0) = 1 pn*(1-x^n)/(1-x) =

我想从
0,1,2,3…n
中选择一个随机数,但是我想让它成为选择
k | 0的机会
解决此问题将为您提供:

p1 + p2 + ... + pn = 1
(p2 * x) + (p3 * x) + ... + (pn * x) + pn = 1
((p3*x) * x) + ((p4*x) * x) + ... + ((p_n-1*x) * x) + pn = 1
....
pn* (x^(n-1) + x^(n-2) + ... +x^1 + x^0) = 1
pn*(1-x^n)/(1-x) = 1
pn = (1-x)/(1-x^n)
p1 + p2 + ... + pn = 1
(p2 + x) + (p3 + x) + ... + (pn + x) + pn = 1
((p3+x) + x) + ((p4+x) + x) + ... + ((p_n-1+x) + x) + pn = 1
....
pn* ((n-1)x + (n-2)x + ... +x + 0) = 1
pn* x = n(n-1)/2
pn = n(n-1)/(2x)
这为您提供了需要设置为
pn
的概率,您可以从中计算所有其他p1、p2、…p_n-1的概率

现在,您可以使用一个“黑盒”RNG来选择带有分布的数字,就像您提到的线程中的数字一样

一种简单的方法是设置辅助数组:

aux[i] = p1 + p2 + ... + pi
现在,在
0
aux[n]
之间绘制一个均匀分布的随机数,并使用二进制搜索(aux数组已排序)获得第一个值,
aux
中的匹配值大于您得到的随机均匀数


原始答案,用于删减(在编辑问题之前):

对于
n
项,您需要解方程:

p1 + p2 + ... + pn = 1
p1 = p2 + x
p2 = p3 + x
...
p_n-1 = pn + x
解决此问题将为您提供:

p1 + p2 + ... + pn = 1
(p2 * x) + (p3 * x) + ... + (pn * x) + pn = 1
((p3*x) * x) + ((p4*x) * x) + ... + ((p_n-1*x) * x) + pn = 1
....
pn* (x^(n-1) + x^(n-2) + ... +x^1 + x^0) = 1
pn*(1-x^n)/(1-x) = 1
pn = (1-x)/(1-x^n)
p1 + p2 + ... + pn = 1
(p2 + x) + (p3 + x) + ... + (pn + x) + pn = 1
((p3+x) + x) + ((p4+x) + x) + ... + ((p_n-1+x) + x) + pn = 1
....
pn* ((n-1)x + (n-2)x + ... +x + 0) = 1
pn* x = n(n-1)/2
pn = n(n-1)/(2x)
这为您提供了需要设置为
pn
的概率,您可以从中计算所有其他p1、p2、…p_n-1的概率

现在,您可以使用一个“黑盒”RNG来选择带有分布的数字,就像您提到的线程中的数字一样



请注意,这并不能保证您会有这样一个解决方案,即
0编辑此答案是针对OPs原始问题的,其不同之处在于,每个概率都应该比前一个概率低一个固定的量

好吧,让我们看看约束是怎么说的。你想要P(k)=P(k-1)-x。因此,我们:

p(0)

p(1)=p(0)-x

p(2)=p(0)-2x

此外,Sumk p(k)=1。总之,我们得到:

1=(n+1)p(0)-x*n/2(n+1)


这为您提供了x和p(0)之间的简单约束。根据另一个来求解一个。

为此,我将使用Boost提供的用于均匀分布的Mersenne Twister算法,然后使用映射函数将随机分布的结果映射到实际选择的数字

下面是一个可能实现的快速示例,尽管我省略了四次方程式实现,因为它是众所周知的:

int f_of_xib(int x, int i, int b)
{
    return x * i * i / 2 + b * i;
}

int b_of_x(int i, int x)
{
    return (r - ( r ) / 2 );
}


int pickANumber(mt19937 gen, int n, int x)
{
    // First, determine the range r required where the probability equals i * x
    // since probability of each increasing integer is x higher of occuring.
    // Let f(i) = r and given f'(i) = x * i then r = ( x * i ^2 ) / 2 + b * i
    // where b = ( r - ( x * i ^ 2 ) / 2 ) / i . Since r = x when i = 1 from problem
    // definition, this reduces down to b = r - r / 2. therefore to find r_max simply
    // plugin x to find b, then plugin n for i, x, and b to get r_max since r_max occurs
    // when n == i.

    // Find b when 
    int b = b_of_x(x);
    int r_max = f_of_xib(x, n, b);

    boost::uniform_int<> range(0, r_max);
    boost::variate_generator<boost::mt19937&, boost::uniform_int<> > next(gen, range);

    // Now to map random number to desired number, just find the positive value for i
    // when r is the return random number which boils down to finding the non-zero root
    // when 0 = ( x * i ^ 2 ) / 2 + b * i - r
    int random_number = next();

    return quadtratic_equation_for_positive_value(1, b, r);
}



int main(int argc, char** argv)
{
    mt19937 gen;
    gen.seed(time(0));

    pickANumber(gen, 10, 1);

    system("pause");
}
int f_of_xib(int x,int i,int b)
{
返回x*i*i/2+b*i;
}
int b_of_x(int i,int x)
{
申报表(r-(r)/2);
}
内部pickANumber(mt19937 gen,内部n,内部x)
{
//首先,确定概率等于i*x时所需的范围r
//因为每一个递增的整数发生的概率是x。
//设f(i)=r,给定f'(i)=x*i,则r=(x*i^2)/2+b*i
//式中,b=(r-(x*i^2)/2)/i.因为当问题中的i=1时r=x
//定义,这将减少到b=r-r/2。因此,只需找到r_max
//插件x查找b,然后插件n查找i、x和b,以获得r_max,因为r_max出现
//当n==i时。
//什么时候找到b
int b=x(x)的b_;
int r_max=u xib(x,n,b)的f_;
均匀整数范围(0,r\u max);
boost::下一个变量发生器(发电机,量程);
//现在要将随机数映射到所需数,只需找到i的正值
//当r是返回的随机数时,归结为寻找非零根
//当0=(x*i^2)/2+b*i-r时
int random_number=next();
返回四次方方程,求出正值(1,b,r);
}
int main(int argc,字符**argv)
{
mt19937 gen;
种子代(时间(0));
pickANumber(gen,10,1);
系统(“暂停”);
}

我想你的意思是“k | 0@j|u random_hacker”是的,tnxWow,这真的不清楚。这不是p1=p2+x,而是p1=p2*x,这是我在描述问题时的错误。我用乘法来解释lawer。Sorry@Ilya_Gazman你的问题是“降低x”,意思是减法,不是除法。无论如何,除法也可以做得非常类似,但是使用几何级数求和,而不是算术级数,然后得到formula@Ilya_Gazman我添加了一个乘法的解决方案,这是相同的原理。你也可以看看指数分布,它是一个紧密的变量,虽然是连续的。@Ilya_Gazman至于加法解(减法,而不是除法),请注意我明确写的内容-它对某些值不起作用,因为它可能导致某些
pi
的负值,或大于1的值。如果不放宽要求,您将无能为力,因为这是解决带有
n
变量的
n
线性公式的答案,并且只有一个解决方案