C ++基于数学方程生成随机数。

时间:2017-06-07 08:39:42

标签: c++

我有三个整数

  • 距离1
  • 距离2
  • distnace3

总计达到100.

  

距离1 +距离2 +距离3 = 100(EQ1)

我有其他信息

  • 20<距离2< 90(EQ2)和
  • distance1 + distance3> 8(EQ3)

我需要在C ++中计算distance1,distance2和distance3的快速三个正随机值,以支持方程EQ1,EQ2和EQ3。

我的第一个方法是做以下

sum(normsA2 ** 2, axis=0)

有更好的方法吗?有没有可以提供帮助的图书馆?这是执行组合的正确方法吗?

6 个答案:

答案 0 :(得分:4)

首先请注意,每次试用只需要两个随机数,因为第三个受到必须总和为100的限制。

第二个注意事项,如果distance2小于90,且总和为100,则distance1 + distance3必须为11或更多。如果EQ3成立,EQ2必须保留。

使用Mersenne Twister进行采样(在没有任何其他信息的情况下)可能是最好的方法,并拒绝不满足约束的组合。要开始使用,请在distance1之间对distance2[0, 100]进行抽样,无论效率如何,必要时都要进行改进,但 采取绝对精致的 关注您不要在减少被拒绝组合的数量方面引入统计偏差(这就是硬比特)。

请注意,自C ++ 11以来,Mersenne Twister已成为C ++标准的一部分:开始使用类似

的内容
#include <random>
std::random_device rd;
std::mt19937 rng(rd());
std::uniform_int_distribution<int> uni(0, 100);
auto random_integer = uni(rng);

答案 1 :(得分:3)

  1. 在适当的范围内为distance2选择一个随机值。
  2. 在适当的范围内选择distance1的随机值(基于distance2的值)。
  3. 计算distance3

答案 2 :(得分:0)

  

distance1 + distance3&gt; 8(EQ3)

如果我们将distance3作为8EQ3保持良好,因为distance1是一个正数(&gt; = 1)。

  

20&lt;距离2&lt; 90(EQ2)

distance221

现在计算distance3 = 100 - distance1 - distance2。 (常数值)

无需生成随机数;)

如果你真的需要它,只需将其中一个变量递增k,然后减去另一个变量以实现另一个组合。请确保这不会中断EQ2

答案 3 :(得分:0)

首先,EQ3隐含在EQ1 + EQ2中。 (D1 + D3 = 100-D2&GT; 100-90 = 10)

核心问题是:您是否需要统一分配所有可能的组合?

如果是,则需要首先计算每个组合(在这种情况下,不是在每种情况下)。

如果不是,您可以使用更有效的随机函数。

#include <iostream>
#include <random>
#include <vector>

std::default_random_engine generator;
std::vector<std::pair<int, int> > results;

void prepareUniformResult()
{
    for(int d2 = 21; d2 <= 89; d2 ++)
        for(int d1 = 1; d1 <= 99-d2; d1 ++)
        results.push_back(std::make_pair(d1, d2));
}

void randomThreeUniform(int &d1, int &d2, int &d3)
{
    std::uniform_int_distribution<int> idist(0, results.size()-1);
    int ind = idist(generator);
    d1 = results.at(ind).first;
    d2 = results.at(ind).second;
    d3 = 100 - d1 - d2;
}

void randomThreeNonUniform(int &d1, int &d2, int &d3)
{
    std::uniform_int_distribution<int> d2dist(21,89);
    d2 = d2dist(generator);
    std::uniform_int_distribution<int> d1dist(1,100-d2-1);
    d1 = d1dist(generator);
    d3 = 100 - d1 - d2;
}
int main()
{
    int d1,d2,d3;

    prepareUniformResult();

    std::cout<<"Non-uniform results:"<<std::endl;
    for(int i=0;i<10;i++)
    {
        randomThreeNonUniform(d1, d2, d3);
        std::cout<<d1<<" "<<d2<<" "<<d3<<std::endl;
    }

    std::cout<<"Uniform results:"<<std::endl;
    for(int i=0;i<10;i++)
    {
        randomThreeUniform(d1, d2, d3);
        std::cout<<d1<<" "<<d2<<" "<<d3<<std::endl;
    }
    return 0;
}

我们可以统一采样点(蓝点)比非均匀点(橙色点)更好地分布。

enter image description here

答案 4 :(得分:0)

在数学上你已经声明这些是你的条件:

  

我有三个正整数

• distance1
• distance2
• distnace3

that sum up to 100. 


distance1 + distance2 + distance3 = 100 (EQ1)
     

我有其他信息

•20 < distance2 < 90 (EQ2) and
•distance1 + distance3 > 8 (EQ3)

让我们首先使用数学来找到范围&amp;价值领域。这些是AB&amp;你的三个距离C。根据你的说法我们可以看到:

For A We don't have enough information without first finding B & C
A = [Depends On B & C]
B = [21,89]

For C; Since A+C > 8 then:
C > 8 - A
We Know that both A & C are both positive so let's make a small table setting values to A
C > 8 - 1   |  C > 7
C > 8 - 2   |  C > 6
C > 8 - 3   |  C > 5
C > 8 - 4   |  C > 4
C > 8 - 5   |  C > 3
C > 8 - 6   |  C > 2
C > 8 - 7   |  C > 1
C > 8 - 8   |  C > 0 still holds true
C > 8 - 9   |  C > -1  ... ? Still true

How Large can A go? This depends on B & C so we need to use B's domain.

100 = (C > 8 - A) + B[21,89]

We can use B's min and max values or the 
floor & ceiling function to determine the domains of A & C.

If B = 21 (min) then the range of combinations between A & C are
100 - 21 = 79
A[1-78]  &  C[1-78] since you have A+B

If B = 89 (max) then the range of combinations between A & C are
100 - 89 = 21
A[1-20] & C[1-20] since you have A+B

So both A & C have a valid domain of [1,78] since
B has a domain of [21,89] and that A+B+C = 100 and all three are + integers

However the Domains of Both A & C depend on the initial value of B.
If B is small then either A or C or A & C can be large
If B is large then both A & C should be small. 

Let's say that the first random value for B is its max 89
Then A or C would be 100 - 89 - 1 giving a range of values [1,10] for either A or C's domain

Let's say that the first random value for B is its min 21
Then A or C would be 100 - 21 - 1 giving a range of values [1,78] for either A or C's domain

We can combine these domains to look as such: [1, 10...78]

We can see above that in both calculations we have 100 - 1 that is constant

The final pseudo mathematical code would be:
99 - B[21,89] = A[1,10...78] + C[1,10...78] where A + C > 8

我们现在可以使用其完整域的上述评估来设计算法,正如其他人已经说过的那样:

// First use a random number generated to find B in the range of [21,89]
// Then you can find a random number for either A or C in the Range of [1,10...78] 
// depending on what B is. Remember if B is small then either A or C can be large.
// And if B is large then A & C should be fairly small.
// Once you have the 2nd value just calculate the third.

答案 5 :(得分:-1)

等式3无关紧要。它由等式2假设。

距离1可以从1到80,距离2可以从21到99 - 距离1,距离3则由100给出 - 距离1 - 距离2.

因此,您需要确定所需的分发类型。您是否希望均匀分布距离1,在这种情况下,距离2将具有聚集到下端的分布。或距离2上的均匀分布? 或者您想要枚举允许的状态并随机选择一个,给予所有相同的权重?通过创建一个半矩阵来实现这一点,其中距离1为长轴,距离为2。