我想创建一个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_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;
}
我的问题:
std::generator
。我正在尝试它,因为我看过其他类似的帖子,似乎它允许我一次生成多个随机数,所以我不必为每个元素运行MxN次。这是真的吗?如何正确使用它?lower_bound
和upper_bound
?我知道我可以更改distribution(0,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版本)而无需太多工作。
我会以随机顺序解决它们:
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 ++没有与numpy
相同的库(虽然它也有很多库 - 只是没有那么通用)。做两个嵌套的for
s你不会错的。你可能更好的服务只是声明一个NxM
数组而不是像vector
那样的here。random_device
来初始化它的例子。