使用 1 和 0 C++ 创建随机 std::vector
Creating a random std::vector with ones and zeros C++
我想按我设置的比例创建一个随机 1 和 0 的向量(在我称之为 dropout 的程序中)该向量与之前创建的向量 CSUM 的大小相同。
在 MATLAB 中它将是
dropout=0.9;
n_elements=size(CSUM)
drpoutmask = (rand(n_elements) > dropout);
在 C++ 中我有
size_t elements = Csum.size();
std::vector<float> y(elements);
std::uniform_real_distribution<float> distribution(0.0f, 1.0f);
std::mt19937 engine; // Mersenne twister MT19937
auto generator = std::bind(distribution, engine);
std::generate_n(y.begin(), elements, generator);
std::vector<int> dropoutmask(elements,0);
float dropout=0.9;
for(int i=0; i<elements; i++)
{
if(y.at(i)>dropout)
{
dropoutmask.at(i)=1;
}
}
}
哪个有效,但是对于巨大的向量来说非常非常慢,有没有更快的方法来做到这一点?我是 C++ 的新手。
任何帮助将不胜感激
你确实知道 bernoulli distribution,对吧?您可以使用它直接生成整数向量。
示例:
#include <iostream>
#include <algorithm>
#include <string>
#include <random>
int main()
{
constexpr double dropout = 0.9; // Chance of 0
constexpr size_t size = 1000;
std::random_device rd;
std::mt19937 gen(rd());
std::bernoulli_distribution dist(1 - dropout); // bernoulli_distribution takes chance of true n constructor
std::vector<int> dropoutmask(size);
std::generate(dropoutmask.begin(), dropoutmask.end(), [&]{ return dist(gen); });
size_t ones = std::count(dropoutmask.begin(), dropoutmask.end(), 1);
std::cout << "vector contains " << ones << " 1's, out of " << size << ". " << ones/double(size) << "%\n";
std::cout << "vector contains " << size - ones << " 0's, out of " << size << ". " << (size - ones)/double(size) << "%\n";
}
或者,您可以创建一个所需大小的整数向量(这会将所有元素设置为 0),将前 N 个元素设置为 1,其中 n 是 (1 - dropout) * size
(你说你想要一个比例,而不是接近比例的随机数量)然后随机播放向量。
#include <iostream>
#include <algorithm>
#include <string>
#include <random>
int main()
{
constexpr double dropout = 0.9; // Chance of 0
constexpr size_t size = 77;
std::random_device rd;
std::mt19937 gen(rd());
std::vector<int> dropoutmask(size);
std::fill_n(dropoutmask.begin(), dropoutmask.size() * (1 - dropout), 1);
std::shuffle(dropoutmask.begin(), dropoutmask.end(), gen);
size_t ones = std::count(dropoutmask.begin(), dropoutmask.end(), 1);
std::cout << "vector contains " << ones << " 1's, out of " << size << ". " << ones/double(size) << "%\n";
std::cout << "vector contains " << size - ones << " 0's, out of " << size << ". " << (size - ones)/double(size) << "%\n";
for (auto i :dropoutmask) {
std::cout << i << ' ';
}
std::cout << '\n';
}
我想按我设置的比例创建一个随机 1 和 0 的向量(在我称之为 dropout 的程序中)该向量与之前创建的向量 CSUM 的大小相同。
在 MATLAB 中它将是
dropout=0.9;
n_elements=size(CSUM)
drpoutmask = (rand(n_elements) > dropout);
在 C++ 中我有
size_t elements = Csum.size();
std::vector<float> y(elements);
std::uniform_real_distribution<float> distribution(0.0f, 1.0f);
std::mt19937 engine; // Mersenne twister MT19937
auto generator = std::bind(distribution, engine);
std::generate_n(y.begin(), elements, generator);
std::vector<int> dropoutmask(elements,0);
float dropout=0.9;
for(int i=0; i<elements; i++)
{
if(y.at(i)>dropout)
{
dropoutmask.at(i)=1;
}
}
}
哪个有效,但是对于巨大的向量来说非常非常慢,有没有更快的方法来做到这一点?我是 C++ 的新手。
任何帮助将不胜感激
你确实知道 bernoulli distribution,对吧?您可以使用它直接生成整数向量。
示例:#include <iostream> #include <algorithm> #include <string> #include <random> int main() { constexpr double dropout = 0.9; // Chance of 0 constexpr size_t size = 1000; std::random_device rd; std::mt19937 gen(rd()); std::bernoulli_distribution dist(1 - dropout); // bernoulli_distribution takes chance of true n constructor std::vector<int> dropoutmask(size); std::generate(dropoutmask.begin(), dropoutmask.end(), [&]{ return dist(gen); }); size_t ones = std::count(dropoutmask.begin(), dropoutmask.end(), 1); std::cout << "vector contains " << ones << " 1's, out of " << size << ". " << ones/double(size) << "%\n"; std::cout << "vector contains " << size - ones << " 0's, out of " << size << ". " << (size - ones)/double(size) << "%\n"; }
或者,您可以创建一个所需大小的整数向量(这会将所有元素设置为 0),将前 N 个元素设置为 1,其中 n 是
(1 - dropout) * size
(你说你想要一个比例,而不是接近比例的随机数量)然后随机播放向量。#include <iostream> #include <algorithm> #include <string> #include <random> int main() { constexpr double dropout = 0.9; // Chance of 0 constexpr size_t size = 77; std::random_device rd; std::mt19937 gen(rd()); std::vector<int> dropoutmask(size); std::fill_n(dropoutmask.begin(), dropoutmask.size() * (1 - dropout), 1); std::shuffle(dropoutmask.begin(), dropoutmask.end(), gen); size_t ones = std::count(dropoutmask.begin(), dropoutmask.end(), 1); std::cout << "vector contains " << ones << " 1's, out of " << size << ". " << ones/double(size) << "%\n"; std::cout << "vector contains " << size - ones << " 0's, out of " << size << ". " << (size - ones)/double(size) << "%\n"; for (auto i :dropoutmask) { std::cout << i << ' '; } std::cout << '\n'; }