代码之家  ›  专栏  ›  技术社区  ›  Physicist

用c++11生成随机数组

  •  -1
  • Physicist  · 技术社区  · 6 年前

    MxN 数组( M 粒子进入 N

    # upper_bound/lower_bound are arrays of shape (dim,)
    positions = np.random.rand(num_particle,dim)*(upper_bound-lower_bound)+lower_bound
    

    每行表示一个粒子,每列表示问题空间中的一个维度。所以 upper_bound lower_bound 适用于每列。现在我想把上面的代码翻译成c++,我有这样的东西:

    #include <iostream>
    #include <vector>
    #include <random>
    #include <algorithm>
    #include <ctime>
    
    typedef std::vector<double> vect1d;
    
    std::vector<vect1d> positions;
    
    for (int i=0; i<num_particle; i++){
        std::mt19937_64 generator(static_cast<std::mt19937::result_type>(time(0)));
        std::uniform_real_distribution<double> distribution(0,1);
        vect1d pos(dimension);
        std::generate(pos.begin(),pos.end(),distribution(generator));
        positions[i] = pos;
        }
    

    我的问题:

    1. std::generator . 我正在尝试它,因为我已经看过其他类似的帖子,它似乎允许我一次生成多个随机数,所以我不必为每个元素运行MxN次。这是真的吗?如何正确使用?

    2. 在python中,我可以通过矢量化和广播来操纵numpy数组。在c++中最“矢量化”的方法是什么?

    3. 上面的(不正确的)代码只创建0到1之间的随机数,但是如何合并 上限 distribution(0,1) ,但问题是每个维度的限制可能不同(因此每个列可以有不同的有效范围),那么考虑到每个维度的范围,生成随机数的最有效方法是什么?

    谢谢

    2 回复  |  直到 6 年前
        1
  •  1
  •   Daniel    6 年前

    首先,使用Python版本所做的工作比需要的要多,只需使用:

    np.random.uniform(lower_bound, upper_bound, size=(num_particle, dim))
    

    在C++尝试中,行

    std::generate(pos.begin(),pos.end(),distribution(generator));
    

    不正确,因为第三个参数必须是函数而不是值。一个合理的C++等价物是:

    using RandomVector = std::vector<double>;
    using RandomMatrix = std::vector<RandomVector>;
    
    template <typename Generator=std::mt19937_64>
    RandomMatrix&
    fill_uniform(const double low, const double high, RandomMatrix& result)
    {
        Generator gen {static_cast<typename Generator::result_type>(time(0))};
        std::uniform_real_distribution<double> dist {low, high};
        for (auto& col : result) {
            std::generate(std::begin(col), std::end(col), [&] () { return dist(gen); });
        }
        return result;
    }
    
    template <typename Generator=std::mt19937_64>
    RandomMatrix
    generate_uniform(const double low, const double high,
                     const std::size_t ncols, const std::size_t nrows)
    {
        RandomMatrix result(ncols, RandomVector(nrows));
        return fill_uniform<Generator>(low, high, result);
    }
    
    int main()
    {
        auto m = generate_uniform(2, 11, 2, 3);
        for (const auto& col : m) {
            for (const auto& v : col) {
                std::cout << v << " ";
            }
            std::cout << '\n';
        }
    }
    

        2
  •  1
  •   Horia Coman    6 年前

    我将按随机顺序称呼他们:

    • 3.您有几个选项-每行使用一个生成器,创建如下 distribution(row_lower_limit, row_upper_limit) 希望 要重用同一个生成器,只需执行以下操作 row_lower_limit + distribution(generator) * (row_upper_limit - row_lower_limit) U[row_lower_limit, row_upper_limit] .
    • numpy 库,而不是Python本身。它最多提供了一些不错的用户体验。C++没有等效的库 努比 for s、 你最好还是宣布 NxM 数组而不是 vector ,就像 here .
    • 1.由于我们不知道错误,所以不确定如何帮助解决问题。这个 cplusplus.com reference 有一个例子说明如何通过引用 random_device .