You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在C++类中正确使用离散分布作为成员变量

解决C++类成员分布变量未正确初始化导致采样始终为0的问题

嘿,这个问题我刚好看过类似的,核心原因很简单:你在构造函数里重新定义了一个和类成员同名的局部变量,导致类的power_dist成员根本没被正确初始化!

问题根源

你在头文件里已经把power_dist声明为FastOnePlusOne的私有成员了,但在构造函数里写了:

std::discrete_distribution<int> power_dist(pmf.begin(),pmf.end());

这行代码创建了一个局部的power_dist变量,它和类成员是完全独立的两个对象。构造函数执行完后,这个局部变量就被销毁了,而类的power_dist成员还是默认构造的状态——std::discrete_distribution默认构造后,每次采样都会返回0,这就是为什么iterate()里的alpha始终是0。

修复方案

只需要去掉构造函数里的类型声明,直接给类成员变量赋值即可:

修改后的构造函数代码:

FastOnePlusOne::FastOnePlusOne(Random& _rand, shared_ptr<Evaluator> _evaluator, Configuration& _config)
    : Optimizer(_rand, _evaluator, _config) {
    // 幂律分布初始化
    int length = 10;
    float B = 1.5;
    vector<double> pmf(length);
    std::iota(pmf.begin(), pmf.end(), 1);
    for(size_t i = 0; i < length; i++) {
        pmf[i] = 1.0 / pow(pmf[i], B);
    }
    pmf.insert(pmf.begin(), 0);
    
    // 直接给类成员变量赋值,不再定义新的局部变量
    power_dist = std::discrete_distribution<int>(pmf.begin(),pmf.end());
    
    std::map<int, int> m;
    for(int n=0; n<10000; ++n) {
        ++m[power_dist(_rand)]; // 顺便建议用传入的_random,而不是rand()
    }
    for(auto p : m) {
        std::cout << p.first << " generated " << p.second << " times\n";
    }
}

额外小建议

注意你代码里用的rand(),既然构造函数已经传入了Random& _rand参数,最好统一使用这个项目自带的随机数生成器,而不是C标准库的rand(),这样能保证随机数的质量和项目整体的一致性。

内容的提问来源于stack exchange,提问作者Alex

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.09 20:47:54