为什么 std::rand 总是生成 0?

Why does std::rand always generate 0?

提问人:blulow 提问时间:5/1/2023 最后编辑:blulow 更新时间:5/8/2023 访问量:104

问:

我正在实现一个单层感知器,我的函数存在问题,例如每次调用函数时它都会生成 0。因此,我在计算时得到的结果不准确。这是我的函数的一个片段,它应该生成一个介于 0 和 1 之间的数字:weight_coefactivationweight_coef

#include <iostream>
#include <vector>
#include <cstdlib>
#include <ctime>

using namespace std;

//Helper function to generate a random number between 0 and 1
double weight_coef() {
    //((double)rand() / RAND_MAX);
    srand(time(NULL));
    double random = static_cast<double>(rand() / RAND_MAX);
    random = round(random * 100) / 100.0; //to 2 dec points
    return random;
}

int main() {
    // Set up the variables
    vector<double> w = { weight_coef(), weight_coef(), weight_coef()};
}

如果您能提出问题所在,将不胜感激。

C++ 随机种子 感知器 均匀分布

评论

2赞 Eljay 5/1/2023
rand() / RAND_MAX是。0
2赞 Pepijn Kramer 5/1/2023
不要像在函数中那样在每次函数调用时重新初始化 random weight_coef。
2赞 Pepijn Kramer 5/1/2023
还可以看看C++的随机函数:。具体来说,uniform_real_distribution可以指定范围的位置。在任何情况下,都不要使用整数算术来计算浮点值。
4赞 Pepijn Kramer 5/1/2023
其他说明:不要使用“using namespace std;”并学习通过常量引用传递向量,您的激活函数将传递向量的副本(并且再次不要混合整数/浮点),签名应该是double activation(const std::vector<double>& x, const std::vector<double>& w)
0赞 Dave Newton 5/7/2023
切线:最好将代码和解释减少到重现问题所需的最小数量。这个问题与神经网络无关。

答:

1赞 davidlowryduda 5/2/2023 #1

问题是 std::rand 返回一个保证介于 0 和 之间的整数。因此权重系数代码RAND_MAX

double weight_coef() {
    srand(time(NULL));
    double random = static_cast<double>(rand() / RAND_MAX); // <-- LOOK
    /* The above line will always set random to 0 */
    random = round(random * 100) / 100.0;
    return random;
}

将始终返回 0(实际上它几乎总是 0,并且概率为 1)。一种解决方案是取随机整数,将其修改为 100,然后将其解释为两位十进制数字的概率。但请注意,这将略微不均匀,因为可能无法被 100 整除(并且可能是 2^31 - 1 = 2147483647)。1/RAND_MAXRAND_MAX

如果你想做一个均匀的随机变量,你可以做这样的事情

#include <iostream>
#include <random>

const int LOWER_BOUND = 0;
const int UPPER_BOUND = 100;

std::random_device rand_dev;
std::mt19937 gen;
std::uniform_int_distribution<int> dist;

int random_int() {
  return dist(gen);
}

int main()
{
  gen = std::mt19937(rand_dev());
  dist = std::uniform_int_distribution<int>(LOWER_BOUND, UPPER_BOUND);

  for (int i = 0; i < 10; i++) {
      std::cout << random_int() << "\n";   // generate 10 random integers
  }
}

我注意到在每次函数调用中反复重新初始化种子也不是一个好主意。取而代之的是,设置一次种子 - 可能在 main 中(正如我发布的代码片段中隐式所做的那样)。