• 使用randn实现randm的通用方法


    使用randn实现randm的通用方法

    分以下两种情况:

    一、n > m

    对于n > m的情况,可以直接截断,即不断使用randn生成随机数,直到该随机数小于等于m的倍数为止(该倍数要小于等于n)。

    比如rand5实现rand2,因为rand5生成的随机数范围为{1,2,3,4,5},如果随机到了5,那就重新生成,直至为1或2或3或4为止,然后模2,并加1 ,即可得到1或2,且生成1 2 的概率都相同,实现了rand2

    #include 
    #include 
    #include 
    using namespace std;
    
    int rand5() {
    	return rand() % 5 + 1;
    }
    
    int rand2() {
    	int res;
    	do{
    		res = rand5();
    	} while(res > 4);
    	return res % 2 + 1;
    }
    
    
    int main() {
    	srand(time(0)); // 设置随机种子,使随机结果不固定
    	printf("rand5的随机结果:\n");
    	for (int i = 0; i < 10; i++) {
    		printf("%d ", rand5());
    	}
    	
    	printf("\n\nrand2的随机结果:\n");
    	for(int i = 0; i < 10; i++) {
    		printf("%d ", rand2());
    	} 
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31

    rand5实现rand2

    二、 n < m

    考虑以下两种情形:

    1. rand5生成rand7

    rand5的范围比rand7小,无法使用前面直接截断的方法。

    考虑到:

    rand5的取值范围为{1,2,3,4,5}

    rand5 - 1的范围为{0,1,2,3,4}

    (rand5 - 1) * 5的范围为{0,5,10,15,20}

    那么,rand5 + (rand5 - 1) * 5 的范围为{1,2,3,4,5,6,7,8,9,10,…, 25},即1~25出现概率均为1/25,截断大于21的部分,然后模7并加1,即为rand7

    #include 
    #include 
    #include 
    using namespace std;
    
    int rand5() {
    	return rand() % 5 + 1;
    }
    
    int rand7() {
    	int res;
    	do{
    		res = rand5() + (rand5() - 1) * 5;
    	} while(res > 21);
    	return res % 7 + 1;
    }
    
    
    int main() {
    	srand(time(0)); // 设置随机种子,使随机结果不固定
    	printf("rand5的随机结果:\n");
    	for (int i = 0; i < 10; i++) {
    		printf("%d ", rand5());
    	}
    	
    	printf("\n\nrand7的随机结果:\n");
    	for(int i = 0; i < 10; i++) {
    		printf("%d ", rand7());
    	} 
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31

    rand5实现rand7

    2. rand5生成rand70

    现在考虑rand5生成rand70,用上述方法只能得到1~25的数,但是70大于25该怎么办?

    (rand5 - 1) * 25的取值范围为{0,25,50,75,100},与1~25的数相加,可以得到1~125的随机整数,且每个数的出现概率相同,再截断大于70的部分,即为rand70

    #include 
    #include 
    #include 
    using namespace std;
    
    int rand5() {
    	return rand() % 5 + 1;
    }
    
    int rand70() {
    	int res;
    	do{
    		res = rand5() + (rand5() - 1) * 5 + (rand5() - 1) * 25;
    	} while(res > 70);
    	return res;
    }
    
    
    int main() {
    	srand(time(0)); // 设置随机种子,使随机结果不固定
    	printf("rand5的随机结果:\n");
    	for (int i = 0; i < 10; i++) {
    		printf("%d ", rand5());
    	}
    	
    	printf("\n\nrand70的随机结果:\n");
    	for(int i = 0; i < 10; i++) {
    		printf("%d ", rand70());
    	} 
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31

    请添加图片描述

    总结:

    r a n d n + ( r a n d n − 1 ) ∗ n randn + (randn - 1) * n randn+(randn1)n 可以生成 1 ~ n 2 1~n^2 1n2的随机整数

    r a n d n + ( r a n d n − 1 ) ∗ n + ( r a n d n − 1 ) ∗ n 2 randn + (randn - 1) * n + (randn - 1) * n^2 randn+(randn1)n+(randn1)n2 可以生成 1 ~ n 3 1~n^3 1n3的随机整数

    ⋯ \cdots

    r a n d n + ( r a n d n − 1 ) ∗ n + ⋯ + ( r a n d n − 1 ) ∗ n i randn + (randn - 1)*n + \cdots + (randn - 1) * n ^i randn+(randn1)n++(randn1)ni 可以生成 1 ~ n i + 1 1~n^{i+1} 1ni+1的随机整数

    因此对于n < m的情况,可以使用 r a n d n randn randn不断的加上 ( r a n d n − 1 ) ∗ n i ( i = 1 , 2 , 3 , . . . ) (randn - 1) * n^i(i = 1, 2, 3, ...) (randn1)nii=1,2,3,...,直至 n i + 1 ≥ m n^{i+1} ≥ m ni+1m,然后截断大于m的最大倍数的部分(该倍数要小于等于 n i + 1 n^{i+1} ni+1),最后模m并加1即可得到 r a n d m randm randm

  • 相关阅读:
    图片、视频修复并超分 - Real-ESRGAN项目使用(一) | 机器学习
    Flask Web——URL与视图
    Docker(一):什么是Docker?
    如何在CPU上进行高效大语言模型推理
    LeetCode——1678.设计 Goal 解析器
    06【MyBatis的配置文件】
    单元测试 :Junit框架
    做直播或短视频 其实有几个精准粉丝就可以很快变现
    WindivertDotnet快速发Ping
    TNF1LTX_TNF2LTX_TNF3LTX 全新板卡10路(TNF1LTX)/11路(TNF2LTX/TNF3LTX)高速任意业务汇聚波长转换板
  • 原文地址:https://blog.csdn.net/luxurie/article/details/126290956