uint64_t state; // 随机数生成器的内部状态
RNG(uint64_t seed) : state(seed) {}
state ^= (state >> 12) & 0xFFFFFFFFFFFFFFFF;
state ^= (state << 25) & 0xFFFFFFFFFFFFFFFF;
state ^= (state >> 27) & 0xFFFFFFFFFFFFFFFF;
return static_cast<uint32_t>((state * 0x2545F4914F6CDD1D) >> 32);
// 生成一个 [0, 1) 区间内的随机浮点数
// 将 32 位随机数右移 8 位后,除以 16777216.0 来生成 [0, 1) 区间内的随机浮点数
return (random_u32() >> 8) / 16777216.0f;
// 生成一个 [a, b) 区间内的随机浮点数
float uniform(float a = 0.0f, float b = 1.0f) {
// 使用 [0, 1) 的随机数生成 [a, b) 区间内的随机浮点数
return a + (b - a) * random();
std::tuple<std::vector<std::pair<std::vector<double>, int>>,
std::vector<std::pair<std::vector<double>, int>>,
std::vector<std::pair<std::vector<double>, int>>>
gen_data(RNG &random, int n = 100) {
std::vector<std::pair<std::vector<double>, int>> pts;
for (int i = 0; i < n; ++i) {
// 生成 x 和 y 坐标,范围在 [-2.0, 2.0)
float x = random.uniform(-2.0f, 2.0f);
float y = random.uniform(-2.0f, 2.0f);
int label = (x < 0) ? 0 : (y < 0) ? 1 : 2;
// 将生成的点(向量和标签)存入 pts 向量中
pts.emplace_back(std::vector<double>{x, y}, label);
// 计算训练集、验证集和测试集的大小 (80%, 10%, 10%)
int tr_size = static_cast<int>(0.8 * n); // 训练集大小
int val_size = static_cast<int>(0.1 * n); // 验证集大小
std::vector<std::pair<std::vector<double>, int>> tr(pts.begin(), pts.begin() + tr_size); // 训练集
std::vector<std::pair<std::vector<double>, int>> val(pts.begin() + tr_size, pts.begin() + tr_size + val_size); // 验证集
std::vector<std::pair<std::vector<double>, int>> te(pts.begin() + tr_size + val_size, pts.end()); // 测试集
return std::make_tuple(tr, val, te);