java – Bertrand的悖论模拟
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了java – Bertrand的悖论模拟,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含2717字,纯文字阅读大概需要4分钟。
内容图文
所以,我前几天在Hacker News上看到了这个:http://web.mit.edu/tee/www/bertrand/problem.html
它基本上表示半径为1的圆上的随机和弦的长度大于3的平方根的概率是多少.
看看它,答案显然是1/3,但对HN的评论让人比我更聪明. https://news.ycombinator.com/item?id=10000926
我不想辩论,但我确实想确保我不是疯了.所以我编码了我认为会证明它是P = 1/3,但我最终得到P~.36.所以,我的代码有些不对劲.
我可以进行健全检查吗?
package com.jonas.betrand;
import java.awt.geom.Point2D;
import java.util.Random;
public class Paradox {
final static double ROOT_THREE = Math.sqrt(3);
public static void main(String[] args) {
int greater = 0;
int less = 0;
for (int i = 0; i < 1000000; i++) {
Point2D.Double a = getRandomPoint();
Point2D.Double b = getRandomPoint();
//pythagorean
if (Math.sqrt(Math.pow((a.x - b.x), 2) + Math.pow((a.y - b.y), 2)) > ROOT_THREE) {
greater++;
} else {
less++;
}
}
System.out.println("Probability Observerd: " + (double)greater/(greater+less));
}
public static Point2D.Double getRandomPoint() {
//get an x such that -1 < x < 1
double x = Math.random();
boolean xsign = new Random().nextBoolean();
if (!xsign) {
x *= -1;
}
//formula for a circle centered on origin with radius 1: x^2 + y^2 = 1
double y = Math.sqrt(1 - (Math.pow(x, 2)));
boolean ysign = new Random().nextBoolean();
if (!ysign) {
y *= -1;
}
Point2D.Double point = new Point2D.Double(x, y);
return point;
}
}
编辑:感谢一群人让我直截了当,我发现我找到随机点的方法并不是那么随意.这是该函数的修复,返回约1/3.
public static Point2D.Double getRandomPoint() {
//get an x such that -1 < x < 1
double x = Math.random();
Random r = new Random();
if (!r.nextBoolean()) {
x *= -1;
}
//circle centered on origin: x^2 + y^2 = r^2. r is 1.
double y = Math.sqrt(1 - (Math.pow(x, 2)));
if (!r.nextBoolean()) {
y *= -1;
}
if (r.nextBoolean()) {
return new Point2D.Double(x, y);
} else {
return new Point2D.Double(y, x);
}
}
解决方法:
我相信你需要假设一个固定点说(0,1),然后在圆周围的[0,2 * pi]中选择一个随机的旋转量,用于和弦的第二个点的位置.
只是为了它的地狱我在Swift中写了你不正确的版本(学习Swift!):
struct P {
let x, y: Double
init() {
x = (Double(arc4random()) / 0xFFFFFFFF) * 2 - 1
y = sqrt(1 - x * x) * (arc4random() % 2 == 0 ? 1 : -1)
}
func dist(other: P) -> Double {
return sqrt((x - other.x) * (x - other.x) + (y - other.y) * (y - other.y))
}
}
let root3 = sqrt(3.0)
let total = 100_000_000
var samples = 0
for var i = 0; i < total; i++ {
if P().dist(P()) > root3 {
samples++
}
}
println(Double(samples) / Double(total))
答案确实是0.36.正如评论所解释的那样,随机X值更可能选择pi / 2附近的“扁平区域”,并且极不可能选择0和pi附近的“垂直挤压”区域.
但是在P的构造函数中很容易修复:
(Double(arc4random())/ 0xFFFFFFFF对于[0,1)中的随机浮点数来说很花哨
let angle = Double(arc4random()) / 0xFFFFFFFF * M_PI * 2
x = cos(angle)
y = sin(angle)
// outputs 0.33334509
内容总结
以上是互联网集市为您收集整理的java – Bertrand的悖论模拟全部内容,希望文章能够帮你解决java – Bertrand的悖论模拟所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。