如何在满足以下约束的n个元素的数组中分配随机值?

Piy*_*wal 5 arrays algorithm math

假设a是我的n元素数组.

约束:

  1. alpha <= a [i] <= beta.
  2. 0 <= alpha <= beta <= 1.
  3. a中所有元素的总和应该恰好为1.

假设对于给定的alpha和beta值,这样的数组总是可行的

这就是我的想法:

随机分配alpha和beta之间的值.找到数组元素的总和.如果sum> 1,则用x减去所有元素,以满足约束.如果sum <1,则使用x添加所有元素,以满足约束.

但我发现很难找到新映射的值.

bam*_*s53 2

这可以满足当且仅当 alpha \xc3\x97 n \xe2\x89\xa4 1 \xe2\x89\xa4 beta \xc3\x97 n。

\n\n

您可以通过选择 n 个随机数来做到这一点。令 r i为第 i 个随机数,令 R 为随机数之和,S = (beta - alpha)/(1-n\xc3\x97alpha) \xc3\x97 R。设置 a[i] = alpha + r i /S * (beta - alpha)。只要 S 不小于最大随机数,则 的所有元素都a在 alpha 和 beta 之间,且它们的总和为 1。

\n\n
#include <iostream>\n#include <cassert>\n#include <random>\n#include <vector>\n#include <algorithm>\n#include <iterator>\n\nint main() {\n    const double alpha = 0.05, beta = 0.15;\n    const int n = 10;\n\n    if (!(n * alpha <= 1.0 && 1.0 <= n * beta)) {\n        std::cout << "unable to satisfy costraints.\\n";\n        return 0;\n    }\n\n    if (alpha == beta || std::fabs(1.0 - n * alpha) < 1e-6 || std::fabs(1.0 - n * beta) < 1e-6) {\n        std::cout << "Solution for alpha = " << alpha << ", beta = " << beta << " n = " << n << ":\\n";\n        std::fill_n(std::ostream_iterator<double>(std::cout, " "), n, 1.0/n);\n        std::cout << "\\nSum: 1.0\\n";\n        return 0;\n    }\n\n    std::vector<int> r;\n    double S;\n\n    {\n        std::random_device rd;\n        std::seed_seq seed{rd(), rd(), rd(), rd(), rd(), rd(), rd(), rd()};\n        std::mt19937 eng(seed);\n        std::uniform_int_distribution<> dist(0, 1000);\n\n        do {\n            r.clear();\n            std::generate_n(back_inserter(r), n, std::bind(dist, std::ref(eng)));\n\n            int sum = std::accumulate(begin(r), end(r), 0);\n            S = (beta - alpha) / (1 - n * alpha) * sum;\n        } while (S < *std::max_element(begin(r), end(r)));\n\n    }\n\n    std::vector<double> a(n);\n    std::transform(begin(r), end(r), begin(a), [&] (int ri) { return alpha + ri/S * (beta - alpha); });\n\n    for (double ai : a) {\n        assert(alpha <= ai && ai <= beta);\n    }\n\n    std::cout << "Solution for alpha = " << alpha << ", beta = " << beta << " n = " << n << ":\\n";\n    std::copy(begin(a), end(a), std::ostream_iterator<double>(std::cout, " "));\n    std::cout << \'\\n\';\n    std::cout << "Sum: " << std::accumulate(begin(a), end(a), 0.0) << \'\\n\';\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n
\n

alpha = 0.05、beta = 0.15、n = 10 的解:
\n 0.073923 0.117644 0.0834555 0.139368 0.101696 0.0846471 0.115261 0.0759395 0.0918882 0.116178
\n 总和: 1

\n
\n\n
\n\n

您没有指定您希望算法提供的特定分布,但我想我会指出该算法不一定以相同的概率产生每个可能的解决方案;我相信某些解决方案比其他解决方案更有可能产生。

\n