我创建了一个名为QuickRandom 的类,它的工作是快速生成随机数。非常简单:只取旧值,乘以 double,然后取小数部分。
这是我的 QuickRandom 类的全部内容:
public class QuickRandom {
private double prevNum;
private double magicNumber;
public QuickRandom(double seed1, double seed2) {
if (seed1 >= 1 || seed1 < 0) throw new IllegalArgumentException("Seed 1 must be >= 0 and < 1, not " + seed1);
prevNum = seed1;
if (seed2 <= 1 || seed2 > 10) throw new IllegalArgumentException("Seed 2 must be > 1 and <= 10, not " + seed2);
magicNumber = seed2;
}
public QuickRandom() {
this(Math.random(), Math.random() * 10);
}
public double random() {
return prevNum = (prevNum*magicNumber)%1;
}
}
这是我为测试它而编写的代码:
public static void main(String[] args) {
QuickRandom qr = new QuickRandom();
/*for (int i = 0; i < 20; i ++) {
System.out.println(qr.random());
}*/
//Warm up
for (int i = 0; i < 10000000; i ++) {
Math.random();
qr.random();
System.nanoTime();
}
long oldTime;
oldTime = System.nanoTime();
for (int i = 0; i < 100000000; i ++) {
Math.random();
}
System.out.println(System.nanoTime() - oldTime);
oldTime = System.nanoTime();
for (int i = 0; i < 100000000; i ++) {
qr.random();
}
System.out.println(System.nanoTime() - oldTime);
}
这是一个非常简单的算法,只需将前一个 double 乘以一个“魔数(Magic Number)” double 。我很快就把它拼凑起来,所以我可能会做得更好,但奇怪的是,它似乎工作得很好。
这是 main 方法中注释掉的行的示例输出:
0.612201846732229
0.5823974655091941
0.31062451498865684
0.8324473610354004
0.5907187526770246
0.38650264675748947
0.5243464344127049
0.7812828761272188
0.12417247811074805
0.1322738256858378
0.20614642573072284
0.8797579436677381
0.022122999476108518
0.2017298328387873
0.8394849894162446
0.6548917685640614
0.971667953190428
0.8602096647696964
0.8438709031160894
0.694884972852229
嗯。很随意。事实上,这适用于游戏中的随机数生成器。
以下是未注释部分的示例输出:
5456313909
1427223941
哇!它的执行速度几乎是 Math.random 的 4 倍。
我记得在某处看到 Math.random 使用了 System.nanoTime() 以及大量疯狂的模数和除法。这真的有必要吗?我的算法执行得更快,而且看起来很随机。
我有两个问题:
Math.random 看起来只是简单的乘法和去除小数就足够了?最佳答案
您的 QuickRandom 实现并不是真正的均匀分布。频率通常在较低的值较高,而 Math.random() 具有更均匀的分布。这是 SSCCE这表明:
package com.stackoverflow.q14491966;
import java.util.Arrays;
public class Test {
public static void main(String[] args) throws Exception {
QuickRandom qr = new QuickRandom();
int[] frequencies = new int[10];
for (int i = 0; i < 100000; i++) {
frequencies[(int) (qr.random() * 10)]++;
}
printDistribution("QR", frequencies);
frequencies = new int[10];
for (int i = 0; i < 100000; i++) {
frequencies[(int) (Math.random() * 10)]++;
}
printDistribution("MR", frequencies);
}
public static void printDistribution(String name, int[] frequencies) {
System.out.printf("%n%s distribution |8000 |9000 |10000 |11000 |12000%n", name);
for (int i = 0; i < 10; i++) {
char[] bar = " ".toCharArray(); // 50 chars.
Arrays.fill(bar, 0, Math.max(0, Math.min(50, frequencies[i] / 100 - 80)), '#');
System.out.printf("0.%dxxx: %6d :%s%n", i, frequencies[i], new String(bar));
}
}
}
平均结果如下所示:
QR distribution |8000 |9000 |10000 |11000 |12000
0.0xxx: 11376 :#################################
0.1xxx: 11178 :###############################
0.2xxx: 11312 :#################################
0.3xxx: 10809 :############################
0.4xxx: 10242 :######################
0.5xxx: 8860 :########
0.6xxx: 9004 :##########
0.7xxx: 8987 :#########
0.8xxx: 9075 :##########
0.9xxx: 9157 :###########
MR distribution |8000 |9000 |10000 |11000 |12000
0.0xxx: 10097 :####################
0.1xxx: 9901 :###################
0.2xxx: 10018 :####################
0.3xxx: 9956 :###################
0.4xxx: 9974 :###################
0.5xxx: 10007 :####################
0.6xxx: 10136 :#####################
0.7xxx: 9937 :###################
0.8xxx: 10029 :####################
0.9xxx: 9945 :###################
如果您重复测试,您会发现 QR 分布变化很大,具体取决于初始种子,而 MR 分布是稳定的。有时它会达到所需的均匀分布,但通常不会。这是一个更极端的例子,它甚至超出了图表的边界:
QR distribution |8000 |9000 |10000 |11000 |12000
0.0xxx: 41788 :##################################################
0.1xxx: 17495 :##################################################
0.2xxx: 10285 :######################
0.3xxx: 7273 :
0.4xxx: 5643 :
0.5xxx: 4608 :
0.6xxx: 3907 :
0.7xxx: 3350 :
0.8xxx: 2999 :
0.9xxx: 2652 :
关于java - 这是一个 "good enough"随机算法吗?如果它更快,为什么不使用它?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14491966/
类classAprivatedeffooputs:fooendpublicdefbarputs:barendprivatedefzimputs:zimendprotecteddefdibputs:dibendendA的实例a=A.new测试a.foorescueputs:faila.barrescueputs:faila.zimrescueputs:faila.dibrescueputs:faila.gazrescueputs:fail测试输出failbarfailfailfail.发送测试[:foo,:bar,:zim,:dib,:gaz].each{|m|a.send(m)resc
我正在尝试测试是否存在表单。我是Rails新手。我的new.html.erb_spec.rb文件的内容是:require'spec_helper'describe"messages/new.html.erb"doit"shouldrendertheform"dorender'/messages/new.html.erb'reponse.shouldhave_form_putting_to(@message)with_submit_buttonendendView本身,new.html.erb,有代码:当我运行rspec时,它失败了:1)messages/new.html.erbshou
我在从html页面生成PDF时遇到问题。我正在使用PDFkit。在安装它的过程中,我注意到我需要wkhtmltopdf。所以我也安装了它。我做了PDFkit的文档所说的一切......现在我在尝试加载PDF时遇到了这个错误。这里是错误:commandfailed:"/usr/local/bin/wkhtmltopdf""--margin-right""0.75in""--page-size""Letter""--margin-top""0.75in""--margin-bottom""0.75in""--encoding""UTF-8""--margin-left""0.75in""-
我有一个模型:classItem项目有一个属性“商店”基于存储的值,我希望Item对象对特定方法具有不同的行为。Rails中是否有针对此的通用设计模式?如果方法中没有大的if-else语句,这是如何干净利落地完成的? 最佳答案 通常通过Single-TableInheritance. 关于ruby-on-rails-Rails-子类化模型的设计模式是什么?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.co
我正在使用的第三方API的文档状态:"[O]urAPIonlyacceptspaddedBase64encodedstrings."什么是“填充的Base64编码字符串”以及如何在Ruby中生成它们。下面的代码是我第一次尝试创建转换为Base64的JSON格式数据。xa=Base64.encode64(a.to_json) 最佳答案 他们说的padding其实就是Base64本身的一部分。它是末尾的“=”和“==”。Base64将3个字节的数据包编码为4个编码字符。所以如果你的输入数据有长度n和n%3=1=>"=="末尾用于填充n%
我主要使用Ruby来执行此操作,但到目前为止我的攻击计划如下:使用gemsrdf、rdf-rdfa和rdf-microdata或mida来解析给定任何URI的数据。我认为最好映射到像schema.org这样的统一模式,例如使用这个yaml文件,它试图描述数据词汇表和opengraph到schema.org之间的转换:#SchemaXtoschema.orgconversion#data-vocabularyDV:name:namestreet-address:streetAddressregion:addressRegionlocality:addressLocalityphoto:i
使用带有Rails插件的vim,您可以创建一个迁移文件,然后一次性打开该文件吗?textmate也可以这样吗? 最佳答案 你可以使用rails.vim然后做类似的事情::Rgeneratemigratonadd_foo_to_bar插件将打开迁移生成的文件,这正是您想要的。我不能代表textmate。 关于ruby-使用VimRails,您可以创建一个新的迁移文件并一次性打开它吗?,我们在StackOverflow上找到一个类似的问题: https://sta
我需要从一个View访问多个模型。以前,我的links_controller仅用于提供以不同方式排序的链接资源。现在我想包括一个部分(我假设)显示按分数排序的顶级用户(@users=User.all.sort_by(&:score))我知道我可以将此代码插入每个链接操作并从View访问它,但这似乎不是“ruby方式”,我将需要在不久的将来访问更多模型。这可能会变得很脏,是否有针对这种情况的任何技术?注意事项:我认为我的应用程序正朝着单一格式和动态页面内容的方向发展,本质上是一个典型的网络应用程序。我知道before_filter但考虑到我希望应用程序进入的方向,这似乎很麻烦。最终从任何
我想要做的是有2个不同的Controller,client和test_client。客户端Controller已经构建,我想创建一个test_clientController,我可以使用它来玩弄客户端的UI并根据需要进行调整。我主要是想绕过我在客户端中内置的验证及其对加载数据的管理Controller的依赖。所以我希望test_clientController加载示例数据集,然后呈现客户端Controller的索引View,以便我可以调整客户端UI。就是这样。我在test_clients索引方法中试过这个:classTestClientdefindexrender:template=>
为什么4.1%2返回0.0999999999999996?但是4.2%2==0.2。 最佳答案 参见此处:WhatEveryProgrammerShouldKnowAboutFloating-PointArithmetic实数是无限的。计算机使用的位数有限(今天是32位、64位)。因此计算机进行的浮点运算不能代表所有的实数。0.1是这些数字之一。请注意,这不是与Ruby相关的问题,而是与所有编程语言相关的问题,因为它来自计算机表示实数的方式。 关于ruby-为什么4.1%2使用Ruby返