首页 > 其他分享 >随机造数据的技巧总结

随机造数据的技巧总结

时间:2023-05-03 09:34:08浏览次数:34  
标签:总结 std 技巧 int 生成 随机 随机数 data kDataNum

以下是一个简单的使用 C++11 新特性生成随机数数据的程序示例:

#include <iostream>
#include <random>  // 引入随机数生成器的头文件
using namespace std;
int main(){
    // 创建 C++11 随机数生成器
    mt19937_64 rng(std::random_device{}());
    // 使用随机数生成器创建均匀分布
    uniform_int_distribution<int> dist(0, 100);
    // 随机生成 10 个整数并输出它们
    for (int i = 0; i < 10; i++){
        int random_num = dist(rng);
        cout << random_num << " ";
    }
    cout << endl;
    return 0;
}

这个程序用到了 C++11 的两个新特性:随机数生成器和随机分布。std::mt19937_64 是生成随机数的类,可以用 std::random_device 类来获取系统的随机种子,然后把它作为构造函数中的参数传给 std::mt19937_64 的对象来生成随机数。std::uniform_int_distribution<int> 则是一个随机的整数分布,它需要两个参数来构造一个均匀分布:分别是随机数的范围的最小值和最大值。

当然也可以用 rand() 函数生成随机数。但在C++11中已经有更加强大的随机数生成器(如上文),推荐使用更加先进的方式生成随机数。rand() 函数会使用计算机的时间作为随机种子,因此可能会存在一些问题,具体如下:

  1. rand() 可能不够随机:使用 rand() 接口会有产生伪随机数的风险,而 C++11 标准引入了更加随机的随机数生成器;

  2. rand() 生成随机数的范围受限:rand() 生成的随机数范围是 [0, RAND_MAX] ,而且计算 RAND_MAX 时,可能会限制随机数的分布均匀性。

下面是一个使用 rand() 函数生成区间内随机数的示例代码:

#include <iostream>
#include <cstdlib>   // 引入 srand() 和 rand() 函数
using namespace std;
signed main(void){
    const int kLowerBound = 1;  // 区间下限
    const int kUpperBound = 100;  // 区间上限
    const int kDataNum = 20;  // 需要生成的数据量

    // 设置种子
    srand(time(nullptr));
	//或者srand(time(NULL))也行,NULL换为0也可以。

    // 生成随机数
    int data[kDataNum];
    for (int i = 0; i < kDataNum; i++)
        data[i] = rand() % (kUpperBound - kLowerBound + 1) + kLowerBound;

    // 输出生成的数据
    for (int i = 0; i < kDataNum; i++)
        cout << data[i] << " ";
    cout << std::endl;
    return 0;
}

上述代码中,我们已经设置种子并使用 rand() 函数生成了区间 [1, 100] 内的随机数,并将它们存储在了一个数组(data)中。如果需要生成非整数的区间内的随机数,可以将 rand() % (kUpperBound - kLowerBound + 1) + kLowerBound 改为较为通用的式子 ((double) rand() / RAND_MAX) * (kUpperBound - kLowerBound) + kLowerBound

总之,虽然在 C++11 引入的随机数库中有更先进、可靠、易用的随机数生成器,但是这里提供的方法仍然是缺乏更可靠性、更灵活性的解决方案之一。

上面的程序将生成 10 个 0 到 100 之间的随机整数并输出它们。你可以根据需要进行修改,例如改变随机数的范围或者将生成的随机数存储到一个数组中。

如果给定的得分表有特殊性质,例如排序好的、连续递增或递减的等,我们可以通过这些特殊性质来快速地生成多组数据。

以一个简单的例子来说明,如果给定的得分表是一个递增的数列,我们可以按照以下方式构造等多组数据:

  1. 随机生成一个数作为第一个数。
  2. 从第二个数开始,每个数比前一个数多增加若干个随机的增量,增量的大小可以根据需要自己设定,可以是一个固定的数,也可以是一个随机数。
  3. 重复第2步,直到生成需要的数据量。

以下是一个使用 C++ 的程序示例:

#include <iostream>
#include <random>  // 引入随机数生成器的头文件
using namespace std;
signed main(void){
    const int kDataNum = 10;  // 需要生成的数据量
    int data[kDataNum];  // 保存生成的数据的数组
    // 随机生成第一个数
    random_device rd;
    mt19937 gen(rd());
    uniform_int_distribution<> dis(0, 100);
    data[0] = dis(gen);
    // 生成后面的数
    uniform_int_distribution<> delta_dis(1, 10);  // 增量取 1 到 10 之间的随机数
    for (int i = 1; i < kDataNum; i++)
        data[i] = data[i - 1] + delta_dis(gen);
    // 输出生成的数据
    for (int i = 0; i < kDataNum; i++)
        cout << data[i] << " ";
    cout << endl;
    return 0;
}

这个程序将生成一个长度为 10 的递增数列,每个数之间的增量随机取 1 到 10 之间的整数。你可以根据需要修改随机数的范围和增量的大小来生成其他类型的数据。除了递增的数列外,类似的方式也可以用于递减数列、正负交替等有特殊性质的得分表。

下面以不同的得分表特殊性质为例,展示如何快速生成多组数据。

  1. 递增的得分表
#include <iostream>
#include <random>  // 引入随机数生成器的头文件
using namespace std;
signed main(void){
    const int kDataNum = 20;  // 需要生成的数据量
    int data[kDataNum];  // 保存生成的数据的数组
    // 随机生成第一个数
    random_device rd;
    mt19937 gen(rd());
    uniform_int_distribution<> dis(0, 100);
    data[0] = dis(gen);
    // 生成后面的数
    uniform_int_distribution<> delta_dis(1, 10);  // 增量取 1 到 10 之间的随机数
    for (int i = 1; i < kDataNum; i++)
        data[i] = data[i - 1] + delta_dis(gen);
    // 输出生成的数据
    for (int i = 0; i < kDataNum; i++)
        cout << data[i] << " ";
    cout << endl;
    return 0;
}
  1. 递减的得分表
#include <iostream>
#include <random>  // 引入随机数生成器的头文件
using namespace std;
signed main(void){
    const int kDataNum = 20;  // 需要生成的数据量
    int data[kDataNum];  // 保存生成的数据的数组
    // 随机生成第一个数
    random_device rd;
    mt19937 gen(rd());
    uniform_int_distribution<> dis(0, 100);
    data[0] = dis(gen);
    // 生成后面的数
    uniform_int_distribution<> delta_dis(1, 10);  // 减量取 1 到 10 之间的随机数
    for (int i = 1; i < kDataNum; i++)
        data[i] = data[i - 1] - delta_dis(gen);
    // 输出生成的数据
    for (int i = 0; i < kDataNum; i++)
        cout << data[i] << " ";
    cout << endl;
    return 0;
}
  1. 奇数偶数交替的得分表
#include <iostream>
#include <random>  // 引入随机数生成器的头文件
using namespace std;
signed main(void){
    const int kDataNum = 20;  // 需要生成的数据量
    int data[kDataNum];  // 保存生成的数据的数组
    // 随机生成第一个数
    random_device rd;
    mt19937 gen(rd());
    uniform_int_distribution<> dis(0, 100);
    data[0] = dis(gen) % 2;  // 取出第一个数的奇偶性
    // 生成后面的数
    uniform_int_distribution<> delta_dis(1, 10);  // 取 1 到 10 之间的随机数
    for (int i = 1; i < kDataNum; i++)
        data[i] = data[i - 1] + (i % 2 == 0 ? delta_dis(gen) : -delta_dis(gen));
    // 输出生成的数据
    for (int i = 0; i < kDataNum; i++)
    	cout << data[i] << " ";
    cout << endl;
    return 0;
}
  1. 以一定规律重复的得分表
#include <iostream>
using namespace std;
signed main(){
    const int kDataNum = 20;  // 需要生成的数据量
    int data[kDataNum];  // 保存生成的数据的数组
    // 生成数据
    for (int i = 0; i < kDataNum; i++)
        data[i] = i % 3;  // 每3个数重复一次
    // 输出生成的数据
    for (int i = 0; i < kDataNum; i++)
        cout << data[i] << " ";
	cout<<endl;
	return 0;
}

也可以生成随机树,序列,图等。

下面是使用 std::mt19937_64 随机生成序列、树和图的示例代码:

  1. 随机生成序列
#include <iostream>
#include <vector>
#include <random>

int main()
{
    const int kDataNum = 20;
    std::random_device rd;
    std::mt19937_64 gen(rd());
    std::uniform_int_distribution<> dis(1, 100);
    std::vector<int> data(kDataNum);
    for (int i = 0; i < kDataNum; i++)
    {
        data[i] = dis(gen);
    }
    for (int i = 0; i < kDataNum; i++)
    {
        std::cout << data[i] << " ";
    }
    std::cout << std::endl;
    return 0;
}
  1. 随机生成树、图
    生成随机树的常用方法是随机生成一张图,然后选取一颗生成树。下面是使用C++的STL库中的std::mt19937_64生成随机图和随机树的示例代码:
#include <iostream>
#include <random>
#include <vector>
#include <algorithm>

const int N = 10; //图中节点数

int main() {
    std::mt19937_64 eng{std::random_device{}()};

    std::uniform_int_distribution<int> dist(0, N - 1); //生成随机整数分布

    //生成图
    std::vector<std::vector<int>> graph(N, std::vector<int>(N, 0));
    for (int i = 0; i < N; i++) {
        for (int j = 0; j < i; j++) {
            graph[i][j] = graph[j][i] = dist(eng) % 2; //1/2的概率连边
        }
    }

    //打印图
    std::cout << "Graph:" << std::endl;
    for (const auto &row : graph) {
        for (int x : row) {
            std::cout << x << " ";
        }
        std::cout << std::endl;
    }

    //生成随机树
    std::vector<int> visited(N, 0);
    std::vector<int> tree;
    tree.push_back(0);
    visited[0] = 1;
    while (tree.size() < N) {
        std::vector<int> candidates;
        for (int i : tree) {
            for (int j = 0; j < N; j++) {
                if (graph[i][j] && !visited[j]) {
                    candidates.push_back(j);
                }
            }
        }
        if (candidates.empty()) {
            std::cerr << "Graph is not connected, cannot generate a tree." << std::endl;
            return 1;
        }
        std::shuffle(candidates.begin(), candidates.end(), eng); //打乱候选节点顺序
        int new_node = candidates.front();
        tree.push_back(new_node);
        visited[new_node] = 1;
    }

    //打印生成的随机树
    std::cout << "Tree: ";
    for (int x : tree) {
        std::cout << x << " ";
    }
    std::cout << std::endl;

    return 0;
}

这个程序使用了C++的STL库中的std::mt19937_64作为随机数生成器,以及std::uniform_int_distribution作为生成随机整数的分布,生成了一个大小为N的随机图和一颗以0为根节点的随机树。程序输出的结果如下:

Graph:
0 0 1 1 0 1 0 0 1 0 
0 0 1 0 0 1 1 0 1 0 
1 1 0 0 1 0 1 0 1 0 
1 0 0 0 0 0 1 1 0 0 
0 0 1 0 0 1 0 0 0 0 
1 1 0 0 1 0 0 0 0 1 
0 1 1 1 0 0 0 0 0 0 
0 0 0 1 0 0 0 0 0 0 
1 1 1 0 0 0 0 0 0 1 
0 0 0 0 0 1 0 0 1 0 
Tree: 0 2 1 6 3 8 5 4 9 7 

结语 :总之,随机数使用的方法很多,还请根据读者由实际情况自己思考体会。

标签:总结,std,技巧,int,生成,随机,随机数,data,kDataNum
From: https://www.cnblogs.com/GOD-HJ/p/17368686.html

相关文章

  • 每日总结2023-05-02
     对于listView,内部item为这种格式,<?xmlversion="1.0"encoding="utf-8"?><LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"android:layo......
  • 2023.5.2 高一下半期总结
    2023.5.2高一下半期总结随着半期考试的结束,高一已经过去了上半学期。上半学期主要用于寒假集训的总结和整理,巩固知识点,我们对整理的题单进行了有效的覆盖,扎实了基础;还扩展了FWT、点分治等算法。上半期对我而言,唯一美中不足的是,省选的Day2得到了近乎爆零的成绩,与其他队友间都有相......
  • g++ 命令总结
    g++是C++编译器,用于将C++代码编译为可执行文件。基本语法:g++[选项]文件名常用选项:-ofilename:指定输出文件名为filename;-Wall:打印所有警告信息;-Wextra:打印更多的警告信息;-std=c++11:将语言标准设置为C++11;-std=c++14:将语言标准设置为C++14;-std=c++17:将语言标准设置为C......
  • 机器学习算法 随机森林学习 之决策树
    随机森林是基于集体智慧的一个机器学习算法,也是目前最好的机器学习算法之一。随机森林实际是一堆决策树的组合(正如其名,树多了就是森林了)。在用于分类一个新变量时,相关的检测数据提交给构建好的每个分类树。每个树给出一个分类结果,最终选择被最多的分类树支持的分类结果。回归则是不......
  • 01_JS技巧
    1.判断对象数据类型示例代码如下constisType=(type)=>(target)=>`[object${type}]`===Object.prototype.toString.call(target)constisArray=isType('Array')constisObject=isType('Object')constisBoolean=isType('......
  • 13 总结
    13总结目录13总结思考:区块链中应用保险理赔场景有什么问题?保险理赔速度慢,并不是支付技术问题,主要是因为理赔的内容需要人工审核。区块链做防伪溯源?观点:因为区块链是不可篡改的,在区块链上可以查到有机蔬菜生产的全过程,所以是一个很好的应用场景?问题:技术本身没有什么问......
  • 简单总结JavaScript中的微任务和宏任务
    在JavaScript中,任务被分为宏任务和微任务。宏任务:常见的宏任务有setTimeout、setInterval、I/O、UI渲染等等。这些任务都是由浏览器或Node.js中的事件循环调度执行的,它们会被放入一个任务队列(taskqueue)中,等待执行。微任务:常见的微任务有Promise、MutationObserver等。......
  • 利用Linux系统生成随机密码的8种方法
    Linux操作系统的一大优点是对于同样一件事情,你可以使用高达数百种方法来实现它。例如,你可以通过数十种方法来生成随机密码。本文将介绍生成随机密码的十种方法。1.使用SHA算法来加密日期,并输出结果的前10个字符:[root@kafka60shell]#date+%s|sha256sum|base64|head-c10......
  • 磁盘单双缓冲区时间计算题总结
    题型一:问处理一个块所用的总时间是多少这是要处理多块数据,但是题目问处理一块的时间。这是一个套路,一般人会直接算出150。根据甘特图推出结论,单缓冲区处理每块数据用时为:MAX(缓冲区到磁盘所用时间,CPU处理所用时间)+工作区到缓冲区所用时间直接代入得出120。套路就是:求一个......
  • MySql在服务器上使用问题的总结
    服务器是WindowsServer2012,我自己安装了一个MySql数据库,然后一个Web程序和客户端程序都想访问数据库,但是遇到一堆问题。主要是我仍然坚持使用.net2.0,挂接MySql.Data6.7.4版本。解决后记录一下1.IIS访问数据库的问题未能加载文件或程序集“MySql.Data”或它的某一个依赖项。找......