蒙特卡洛蒲丰投针方法(宋浩老师概率课堂www.bilibili.com/video/BV1ot… ) 验证π值,
100000000投掷,验证结果 π=3.1414777872781303
public class MonteCarloToPi {
/**
* 平行线距离
*/
private static final double D = 10.0;
/**
* 针的长度
*/
private static final double L = 6.0;
@Test
public void throwNeedleToPI() {
int SAMPLE_COUNT = 100000000;
int currentSampleCount = 0;
int matchCount = 0;
while (true) {
currentSampleCount = currentSampleCount + 1;
if (currentSampleCount > SAMPLE_COUNT) {
break;
}
double angle = randomDouble(180.0);
double anglePI = angle * Math.PI / 180;
double x = randomDouble(D / 2);
double xRange = L / 2 * Math.sin(anglePI);
if (x > xRange) {
continue;
}
double value = x / Math.sin(anglePI);
double targetValue = L / 2;
if (value <= targetValue) {
matchCount++;
}
}
System.out.println(String.format("currentSampleCount: %s, matchCount:%s", currentSampleCount, matchCount));
System.out.println(String.format("π=%s", 2 * L * SAMPLE_COUNT / (matchCount * D)));
}
/**
* 生成随机数,在value范围
* @param value
* @return
*/
double randomDouble(double value) {
double multi = 1000000000000000.0;
double multiValue = value * multi;
long longValue = BigDecimal.valueOf(multiValue).longValue();
long random = 0;
while (true) {
random = Math.abs(RandomUtils.nextLong());
if (random <= longValue) {
break;
}
}
return random / multi;
}
}