C++中如何生成满足特定比例的随机树大小?
解决方案
首先,原代码存在两个问题:每次调用GenerateTree()时都会重新初始化随机数生成器,这会导致随机性变差;其次,当前的数值范围与你需要的比例不匹配。以下是三种实现指定比例生成树的方法:
方法一:手动阈值映射(适合理解原理)
根据目标比例划分随机数范围,将生成的随机数映射到对应的树大小。同时修正随机数生成器的初始化方式(仅初始化一次):
#include <random> enum class TreeSize : uint32_t { Small, // 占15%:0-14 Medium, // 占30%:15-44 Large, // 占40%:45-84 ExtraLarge// 占15%:85-99 }; TreeSize GenerateTree() { // 静态变量确保随机数生成器只初始化一次 static std::random_device rd; static std::mt19937_64 mt(rd()); static std::uniform_int_distribution<int32_t> dist(0, 99); // 共100个数值,对应100% int value = dist(mt); if (value < 15) return TreeSize::Small; else if (value < 45) // 15+30 return TreeSize::Medium; else if (value < 85) // 15+30+40 return TreeSize::Large; else return TreeSize::ExtraLarge; }
调用该函数1000次,生成的树大小会近似符合指定比例(随机结果存在微小波动)。
方法二:使用std::discrete_distribution(原生工具,更简洁)
C++标准库中的std::discrete_distribution专门用于带权重的随机选择,可直接为每种树大小设置对应占比的权重:
#include <random> enum class TreeSize : uint32_t { Small, Medium, Large, ExtraLarge }; TreeSize GenerateTree() { static std::random_device rd; static std::mt19937_64 mt(rd()); // 权重对应各类型占比:Small(15%), Medium(30%), Large(40%), ExtraLarge(15%) static std::discrete_distribution<> dist({15, 30, 40, 15}); int index = dist(mt); switch(index) { case 0: return TreeSize::Small; case 1: return TreeSize::Medium; case 2: return TreeSize::Large; case 3: return TreeSize::ExtraLarge; default: return TreeSize::Small; // 理论上不会触发 } }
此方法无需手动计算阈值,由标准库处理权重分配,代码更简洁易维护。
方法三:生成精确数量的树(无随机波动)
若需要严格精确的数量(如恰好150棵小型树、300棵中型树),可预先生成包含指定数量的树列表,再随机打乱顺序:
#include <random> #include <vector> #include <algorithm> enum class TreeSize : uint32_t { Small, Medium, Large, ExtraLarge }; std::vector<TreeSize> GenerateExactTrees(int totalCount) { std::vector<TreeSize> trees; trees.reserve(totalCount); // 计算各类型的精确数量 int smallCount = totalCount * 0.15; int mediumCount = totalCount * 0.3; int largeCount = totalCount * 0.4; int extraLargeCount = totalCount - smallCount - mediumCount - largeCount; // 处理四舍五入误差 // 填充列表 for(int i = 0; i < smallCount; ++i) trees.push_back(TreeSize::Small); for(int i = 0; i < mediumCount; ++i) trees.push_back(TreeSize::Medium); for(int i = 0; i < largeCount; ++i) trees.push_back(TreeSize::Large); for(int i = 0; i < extraLargeCount; ++i) trees.push_back(TreeSize::ExtraLarge); // 随机打乱顺序 static std::random_device rd; static std::mt19937_64 mt(rd()); std::shuffle(trees.begin(), trees.end(), mt); return trees; } // 使用示例: // auto trees = GenerateExactTrees(1000);
这种方式能保证每种树的数量完全符合比例,适合对数量精度要求高的场景。
内容的提问来源于stack exchange,提问作者Josh Sanders
相关产品推荐
相关产品推荐

