7-3 蒙特卡罗方法求圆周率 (15 分)(Java)
可算写出来了
使用蒙特卡洛仿真方法求圆周率。(具体要求见作业指导书 2020-OO第05次作业-2指导书V1.0.pdf )
输入格式:
从键盘输入四个实型数和一个整型数,分别为矩形左上角的横坐标、纵坐标、矩形长度、矩形宽度和投点次数,数与数之间可以用一个或多个空格或回车分隔。
输出格式:
如果矩形长度与宽度不相等(非正方形)或长宽数据非法,则输出“Wrong Format”。
如果估算出的π与Math.PI差值小于1E-4,则输出“Success”,否则输出“failed”。
输入样例:
在这里给出一组输入。例如:
0 0 1 1 20000000
输出样例:
在这里给出相应的输出。例如:
Success
然后以下是附带PDF里有用的参考
Main方法我是照搬的,然后参照这张图,
以下是我的代码
import sun.security.ssl.CookieExtension;
import java.util.Random;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
double abscissa,ordinate;
double length,width;
int count = 0;
Scanner input = new Scanner(System.in);
abscissa = input.nextDouble();
ordinate = input.nextDouble();
length = input.nextDouble();
width = input.nextDouble();
count = input.nextInt();
Rectangle rectangle = new Rectangle(new Coordinate(abscissa,ordinate),length,width);
MonteCarloSimulation monteCarlo = new MonteCarloSimulation(rectangle);
if(monteCarlo.validateRectangle()){
monteCarlo.setCircle();
if((Math.abs(monteCarlo.simulation(count) - Math.PI)) <= 1e-3){
System.out.println("Success");
}
else{
System.out.println("failed");
}
}else{
System.out.println("Wrong Format");
}
}
}
class Coordinate {
private double abscissa;
private double ordinate;
public Coordinate(){
}
public Coordinate(double abscissa, double ordinate) {
this.abscissa = abscissa;
this.ordinate = ordinate;
}
public double getAbscissa() {
return abscissa;
}
public void setAbscissa(double abscissa) {
this.abscissa = abscissa;
}
public double getOrdinate() {
return ordinate;
}
public void setOrdinate(double ordinate) {
this.ordinate = ordinate;
}
}
class Rectangle{
Coordinate coordinate;
double width;
double length;
public Rectangle(){
}
public Rectangle(Coordinate coordinate, double width, double length) {
this.coordinate = coordinate;
this.width = width;
this.length = length;
}
public Coordinate getCoordinate() {
return coordinate;
}
public void setCoordinate(Coordinate coordinate) {
this.coordinate = coordinate;
}
public double getWidth() {
return width;
}
public void setWidth(double width) {
this.width = width;
}
public double getLength() {
return length;
}
public void setLength(double length) {
this.length = length;
}
}
class Circle{
Coordinate coordinate;
double radius;
public Circle(){
}
public Circle(Coordinate coordinate, double radius) {
this.coordinate = coordinate;
this.radius = radius;
}
public Coordinate getCoordinate() {
return coordinate;
}
public void setCoordinate(Coordinate coordinate) {
this.coordinate = coordinate;
}
public double getRadius() {
return radius;
}
public void setRadius(double radius) {
this.radius = radius;
}
}
class MonteCarloSimulation{
Rectangle rectangle;
Circle circle;
public MonteCarloSimulation() {
}
public MonteCarloSimulation(Rectangle rectangle, Circle circle) {
this.rectangle = rectangle;
this.circle = circle;
}
public MonteCarloSimulation(Rectangle rectangle) {
this.rectangle = rectangle;
}
public Rectangle getRectangle() {
return rectangle;
}
public void setRectangle(Rectangle rectangle) {
this.rectangle = rectangle;
}
public Circle getCircle() {
return circle;
}
public void setCircle(Circle circle) {
this.circle = circle;
}
//设置正方形中的圆
public void setCircle() { //这里是判断输入的是一个正方形后设置的圆,其实就是通过左上角坐标和边长确定一个内接圆
double r = (this.rectangle.getWidth()-this.rectangle.coordinate.getAbscissa())/2;
Circle c = new Circle(new Coordinate(this.rectangle.coordinate.getAbscissa()+r,
this.rectangle.coordinate.getOrdinate()-r),
r);
this.circle = c;
double i = (this.rectangle.getWidth()-this.rectangle.coordinate.getAbscissa())/2;
}
boolean validateRectangle(){
return this.rectangle.width==this.rectangle.length;
}
double simulation(int n){
int countInCircle = 0;
Coordinate coord2 = new Coordinate();
Random random = new Random(); //这是产生随机数的类
for(int i = 0;i < n;i++){ //random.nextDouble()产生的是0~1的随机点
coord2.setAbscissa( //于是我乘以边长加上左上角坐标,使其成为正方形内的随机点
this.rectangle.coordinate.getAbscissa()+random.nextDouble()*this.circle.radius*2);
coord2.setOrdinate(
this.rectangle.coordinate.getOrdinate()-random.nextDouble()*this.circle.radius*2);
if(getDistance(this.circle.coordinate,coord2)<=this.circle.getRadius())
countInCircle++;//如果在圆内则记一次数
}
return (double) countInCircle / n* 4;//这里返回的就是通过蒙特卡罗方法求出的PI;
}
double getDistance(Coordinate coord1,Coordinate coord2){//这里是比较该随机点与圆心的距离
double xx = coord1.getAbscissa()-coord2.getAbscissa();
double yy = coord1.getOrdinate()-coord2.getOrdinate();
return Math.sqrt(xx*xx+yy*yy);
}
}
可能还是写得丑了点。。。。。