这几天写代码的时候,发现自己需要一个随机数生成器。平方取中,线性同余以及java自带的Random(这个好像用的也是线性同余?)看起来效果不够理想,而梅林旋转虽然质量高但是真的好复杂。

我对于这个生成器期望大约是:

1.≥一亿的循环周期。

2.理论上任意种子都有落在取值范围内任意一个非无限小区间的可能。

3.知道初始种子以后可以快速推算使用这个种子进行第n次生成获得的数字。

4.低时间复杂度,中等以下代码量和理解难度。

也许看起来好他妈苛刻?但是我脑筋一转还真就想到一个。

那就是使用三角函数(这里以sin为例)。

以一个long或者double作为种子-seed,以一个整数或者有限位浮点数为a。生成的第n个随机数为sin((n-1)*a+seed)。

代码量低到一两行代码就能写完,原理简单到义务教育毕业大约就能看懂。简单运算就能得知使用某个种子进行第N次生成获得的数字为何。而且sin的周期是2π,一个整数或者有限位的小数加多少次也加不出π的整数倍,所以在忽略精度溢出的情况下,可以说应该永不重复,同时可能落在取值范围内任意一个非无限小区间。

当然,由于sin函数的形状,这样子处理落在不同区间内的概率会不同。但思路想到利用π这里了,改进一下也不难,比如(((n-1)*a+seed)%π)/π就可以保证落在各个区间的概率基本相等(除的时候可以用BigDecimal,更精准)。

最后再补充一下,如果觉得(((n-1)*a+seed)%π)/π这个方法输出数字变化频率较为明显(易于看出是每次加一个固定值后取模),将这个公式输出的随机值变换后作为自己的增量效果并不好,例如下图。

​
for(int i=0;i<10000;i++){valD=BigDecimal.valueOf(val).divideAndRemainder(pi)[1].divide(pi,6).doubleValue();val=(long)(val+1+4.2*valD);System.out.println(valD);
}​

我试过自己能想到的几种变换,都会导致随机数落点变得很不均匀。

但是,可以进行两次运算,将第一次运算输出的随机数变换后作为第二个式子的增量。例如下图。

for(int i=0;i<10000;i++){valD=BigDecimal.valueOf(time+i).divideAndRemainder(pi)[1].divide(pi,6).doubleValue();val=(long)(val+1+10*valD);System.out.println(BigDecimal.valueOf(val).divideAndRemainder(pi)[1].divide(pi,6).doubleValue());
}

这样子输出的随机数落点既然均匀,同时输出数字规律就不是那么明显了,没那么易于一眼看出是加某个固定值再取模。但是呢,不再可以知道种子和固定增量瞬间推算第N次输出的随机值。。

不知道如此简单的方案之前有没有人想到过,但不论有没有,我当时想到的时候觉得自己像个小天才(厚着脸皮夸一下自己)。

一个非常简单粗暴又理论上不会重复的随机数算法相关推荐

  1. java爬虫好的教程_[Java教程]一个更加简单粗暴的爬虫

    [Java教程]一个更加简单粗暴的爬虫 0 2017-09-30 16:00:13 今天上午看到一篇文章:一个简单粗暴的爬虫 - 必应今日美图.我也用自己的方式更加简单的实现了这个功能.下面我就贴一下 ...

  2. 简单粗暴理解与实现机器学习之K-近邻算法(三):距离度量、欧氏距离、曼哈顿距离、切比雪夫距离、闵可夫斯基距离、标准化距离、余弦距离、汉明距离、杰卡德距离、马氏距离

    K-近邻算法 文章目录 K-近邻算法 学习目标 1.3 距离度量 1 欧式距离**(Euclidean Distance):** 2 **曼哈顿距离(Manhattan Distance):** 3 ...

  3. 简单粗暴理解与实现机器学习之K-近邻算法(十):交叉验证,网格搜索(模型选择与调优)API、鸢尾花案例增加K值调优

    K-近邻算法 文章目录 K-近邻算法 学习目标 1.10 交叉验证,网格搜索 1 什么是交叉验证(cross validation) 1.1 分析 1.2 为什么需要交叉验证 **问题:那么这个只是对 ...

  4. 简单粗暴直接,洗脑广告为何越骂越火?

    又见洗脑广告. 10月14日,大家在电梯里应该都看到了沈腾主演的一则视频广告,简单粗暴直接的形式给人留下深刻印象:不断重复易车"全知道"的沈腾,带出易车新的slogan" ...

  5. 【DIY】废物利用,最简单粗暴便宜的DIY定时器方法,没有之一

    微信关注 "DLGG创客DIY" 设为"星标",重磅干货,第一时间送达. 山不在高,有仙则名.水不在深,有龙则灵. 作品不用高端,实用就行. 这次废物利用,做一 ...

  6. 【S操作】一个简单粗暴易用的远程调试方案——OTA http update

    公众号关注 "DLGG创客DIY" 设为"星标",重磅干货,第一时间送达. 问题的提出: 在公司如何调试家里的物联网设备(esp8266设备)? 最近搞热水器自 ...

  7. 一个简单粗暴的前后端分离方案

    项目背景 刚刚参加完一个项目,背景:后端是用java,后端服务已经开发的差不多了,现在要通过web的方式对外提供服务,也就是B/S架构.后端专注做业务逻辑,不想在后端做页面渲染的事情,只向前端提供数据 ...

  8. 简单粗暴地理解 JavaScript 原型链 (一个充满歪门邪理的理解方法,有助于新手哦!)...

    原型链理解起来有点绕了,网上资料也是很多,每次晚上睡不着的时候总喜欢在网上找点原型链和闭包的文章看,效果极好. 不要纠结于那一堆术语了,那除了让你脑筋拧成麻花,真的不能帮你什么.简单粗暴点看原型链吧, ...

  9. 一个简单粗暴的营销方案,让麻辣烫老店业绩增长40倍以上!

    今天给大家分享一个麻辣烫老店简单粗暴业绩增长40倍的操盘实录,就以第一人称来叙述了.这家原本生意寥寥的麻辣烫老店,只花了一个星期的时间,从原本一天一百多块钱的营业额,做到了每天四千多的进账.天天都人气 ...

最新文章

  1. 3名女研究生,状告哈佛!
  2. scikit-learn 朴素贝叶斯类库使用小结
  3. 如何使用Swift Playgrounds制作东西
  4. java udp ip端口 设置_UDP端口扫描Java只找到1个开放的UDP端口
  5. 终于有人把Docker讲清楚了
  6. 微信小程序自动定位城市
  7. 《WINDOWS游戏编程之从零开始》第四章学习笔记
  8. mysql全量备份命令_linux下进行定时mysql数据库全量备份
  9. Docker升级Wekan
  10. LeetCode刷题-四因数
  11. PHP全国快递寄件接口,1天接入四通一达,极兔,宅急送,德邦,京东,天天
  12. Echarts 修改地图的标示
  13. windows WinExec()
  14. [转载] UEFI+GPT双硬盘安装Win10+Ubuntu16.04双系统
  15. Kotlin - 改良策略模式
  16. 专利申请的有关资料有哪些
  17. 【TWVRP】模拟退火算法求解带时间窗的车辆路径规划问题【含Matlab源码 160期】
  18. DS1820时序分析
  19. quartz 配置文档
  20. htc one x android5.0,HTC One M8升级Android 5.0后有哪些变化?

热门文章

  1. 个体肠道菌群是精准营养干预代谢健康成功的基础
  2. 国外程序员整理的机器学习资源大全
  3. pandas 中 dropna()函数
  4. 【无标题】ubuntu22.04 golang安装和配置环境变量
  5. 【诸葛学堂】《考书大课-统编版必读常考名著名师精讲直播课》
  6. p6spy监测mysql_P6Spy监控你的Spring boot数据库操作
  7. xilinx 时钟问题
  8. linux中c语言对滑屏进行判断,自动化测试程序之二模拟触摸屏点击事件跟滑动事件(C语言)...
  9. vue-pdf 跳坑
  10. pythonjson中list操作_Python中json的简单读写操作