在c ++ 11中生成随机数组

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

我想创建一个MxN数组(在M维空间中的N粒子),在上下边界内填充随机数。我有一个工作的python代码,看起来像这样:

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

每行代表一个粒子,每列代表问题空间中的一个维度。所以upper_boundlower_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之间的随机数,但是如何在python版本中合并lower_boundupper_bound?我知道我可以更改distribution(0,1)中的值,但问题是每个维度的限制可能不同(因此每列可以有不同的有效范围),那么考虑范围是什么是生成随机数的最有效方法对于每个维度?

谢谢

c++ random std
2个回答
1
投票

首先,您使用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';
    }
}

您可以将其概括为生成任意维度张量(如NumPy版本)而无需太多工作。


1
投票

我会以随机顺序解决它们:

  • 你有几个选择 - 每行使用一个生成器,像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]
  • 2.矢量化来自numpy库,而不是来自Python本身。它最多提供了一些不错的用户体验。 C ++没有与numpy相同的库(虽然它也有很多库 - 只是没有那么通用)。做两个嵌套的fors你不会错的。你可能更好的服务只是声明一个NxM数组而不是像vector那样的here
  • 1.由于我们不知道错误,因此不确定如何帮助解决问题。 cplusplus.com reference有一个如何参考random_device来初始化它的例子。
© www.soinside.com 2019 - 2024. All rights reserved.