首页 > 编程语言 >分享一个go源码的均匀采样底层实现原理

分享一个go源码的均匀采样底层实现原理

时间:2024-06-22 14:43:21浏览次数:12  
标签:采样 int32 32 int31n 源码 low go prod uint32

// int31n也就是下面这个函数, 跟上面Int31n效果是一样的. 但是效率更高.算法不一样. 这个算法非常精彩,效率也更高.
// int31n returns, as an int32, a non-negative pseudo-random number in the half-open interval [0,n).
// n must be > 0, but int31n does not check this; the caller must ensure it.
// int31n exists because Int31n is inefficient, but Go 1 compatibility
// requires that the stream of values produced by math/rand remain unchanged.
// int31n can thus only be used internally, by newly introduced APIs.
//
// For implementation details, see:
// https://lemire.me/blog/2016/06/27/a-fast-alternative-to-the-modulo-reduction
// https://lemire.me/blog/2016/06/30/fast-random-shuffling
func (r *Rand) int31n(n int32) int32 {
	v := r.Uint32()               //v是通过伪随机算法得到的一个0到2^32次幂之间的一个随机数.
	prod := uint64(v) * uint64(n) //得到prod是一个64位随机数.并且是n的倍数.显然因为v最大不超过2^32,所以prod的高32位:int32(prod >> 32)必小于n.
	low := uint32(prod)           //low是prod的低32位
	if low < uint32(n) {          //这个函数的算法核心重点:如果low大于等于n,那么我们prod的高32位可以看做1到 [prod/n]*n之间数的均匀采样得到的. 如果low小于n,那么就一定要让prod采样来自于一个n的倍数的区间.这就涉及下面thresh的计算.
		thresh := uint32(-n) % uint32(n) // 这个阈值运算的计算思想如下. 涉及到补码的知识. 道理如下: 首先我们v是取的1到2^32之间的随机数. uint32(-n)加上n就得到2^32, thresh是uint32(-n)比n的倍数多出来的数. 所以整个区间1到2^32次幂,我们需要扣除thresh这么多个数, 剩下来的就是n的倍数了.这就符合我们上面一行注释要求的需要一个n的倍数的区间来保证均匀分布性.
		for low < thresh {               //小于阈值就重新计算.直到保证抽样区间是n的倍数.
			v = r.Uint32()
			prod = uint64(v) * uint64(n)
			low = uint32(prod)
		}
	}
	return int32(prod >> 32)
}


标签:采样,int32,32,int31n,源码,low,go,prod,uint32
From: https://www.cnblogs.com/zhangbo2008/p/18262321

相关文章

  • 新闻管理与推荐系统Python+Django+协同过滤推荐算法+管理系统
    一、介绍新闻管理与推荐系统。本系统使用Python作为主要开发语言开发的一个新闻管理与推荐的网站平台。网站前端界面采用HTML、CSS、BootStrap等技术搭建界面。后端采用Django框架处理用户的逻辑请求,并将用户的相关行为数据保存在数据库中。通过Ajax技术实现前后端的数据通信。......
  • 基于Django的智慧校园考试的设计与实现
    一、项目背景1.1项目研究背景在信息技术日益发展的今天,传统的教育模式正面临着重大的挑战与改革。尤其是在全球新冠疫情的影响下,线上教学模式成为常态,这促使学校、教育机构急需一套高效、可靠且用户友好的在线考试系统来适应这一变化。基于这样的背景,我们提出了开发“智慧校......
  • C#.net6.0语言+B/S架构+前后端分离 手术麻醉信息管理系统源码
    C#.net6.0语言+B/S架构+前后端分离手术麻醉信息管理系统源码什么是手术麻醉信息管理系统满足医院等级评级需求满足电子病历评级需求满足科室需求术前1、患者术前评估/诊断2、术前讨论制定手术方案3、手术准备4、术前准备术中1、送手术室2、麻醉前3、手术术后1......
  • golang runtime.Caller 获取调用堆栈信息, Caller(1) 和 Caller(2) 的区别
     funcwhoCalledMe(){//获取调用堆栈信息_,fileName,lineNo,ok:=runtime.Caller(2)if!ok{fmt.Println("Failedtogetcallerinformation")return}fmt.Printf("Calledfrom:%s:%d\n",fileName,lineNo......
  • Java计算机毕业设计博物馆管理系统(开题报告+源码+论文)
    本系统(程序+源码)带文档lw万字以上 文末可获取一份本项目的java源码和数据库参考。系统程序文件列表开题报告内容研究背景随着信息技术的飞速发展,传统博物馆的管理模式已经难以适应现代社会的需求。博物馆作为重要的文化传承和展示机构,需要更加高效、智能的管理系统来支撑......
  • django中的信号机制
    django中的信号机制1.1什么是信号机制#什么是信号机制Django框架包含了一个信号机制,它允许若干个发送者(sender)通知一组接收者(receiver)某些特定操作或事件(events)已经发生了,接收者收到指令信号(signals)后再去执行特定的操作。1.2信号的工作机制Django中的信号工作机......
  • HKCU\Environment\UserInitMprLogonScript;HKLM\Software\Microsoft\Windows NT
    HKCU\Environment\UserInitMprLogonScript: 这个键位于HKEY_CURRENT_USER(HKCU)的Environment分支下,它用于存储与当前用户环境相关的设置。UserInitMprLogonScript 键可能被设置为在用户登录时运行一个脚本或程序。这个脚本通常用于配置用户特定的环境设置或执行一些登录......
  • Spring Boot 源码分析五:Spring Boot AutoConfiguration 自动配置机制
    1.引言在前几篇文章中,我们探讨了SpringBoot的启动流程及其扩展机制。在本篇文章中,我们将深入分析SpringBoot的自动配置(AutoConfiguration)机制,这是SpringBoot最具特色和强大的功能之一。2.自动配置概述SpringBoot的自动配置机制旨在根据项目中的类路径和配置属性,自......
  • java毕业设计之在线考试系统(springboot完整源码+说明文档+演示视频)
    1项目介绍本系统主要包括管理员和用户两个角色组成;主要包括首页、个人中心、用户管理、教师管理、课程信息管理、班级信息管理、试题管理、在线试题管理、考试管理等功能的管理系统。2、项目技术项目后端框架:Java+ssm项目前端框架:vue2,ssm3、开发环境springboot环境......
  • C/C++ 堆栈stack算法详解及源码
    堆栈(stack)是一种常见的数据结构,具有"先进后出"(LastInFirstOut,LIFO)的特性。堆栈算法允许在堆栈顶部进行元素的插入和删除操作。堆栈的操作包括:入栈(Push):将元素添加到堆栈的顶部。出栈(Pop):从堆栈的顶部移除元素。取栈顶元素(Top):获取堆栈顶部的元素,但不对其进行删除操作。......