package com.egeo.jframetext;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.FontMetrics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Rectangle2D;
import javax.swing.ImageIcon;
publicclassAlgoVisHelper {privateAlgoVisHelper(){}
publicstaticfinal Color Red = new Color(0xF44336);
publicstaticfinal Color Pink = new Color(0xE91E63);
publicstaticfinal Color Purple = new Color(0x9C27B0);
publicstaticfinal Color DeepPurple = new Color(0x673AB7);
publicstaticfinal Color Indigo = new Color(0x3F51B5);
publicstaticfinal Color Blue = new Color(0x2196F3);
publicstaticfinal Color LightBlue = new Color(0x03A9F4);
publicstaticfinal Color Cyan = new Color(0x00BCD4);
publicstaticfinal Color Teal = new Color(0x009688);
publicstaticfinal Color Green = new Color(0x4CAF50);
publicstaticfinal Color LightGreen = new Color(0x8BC34A);
publicstaticfinal Color Lime = new Color(0xCDDC39);
publicstaticfinal Color Yellow = new Color(0xFFEB3B);
publicstaticfinal Color Amber = new Color(0xFFC107);
publicstaticfinal Color Orange = new Color(0xFF9800);
publicstaticfinal Color DeepOrange = new Color(0xFF5722);
publicstaticfinal Color Brown = new Color(0x795548);
publicstaticfinal Color Grey = new Color(0x9E9E9E);
publicstaticfinal Color BlueGrey = new Color(0x607D8B);
publicstaticfinal Color Black = new Color(0x000000);
publicstaticfinal Color White = new Color(0xFFFFFF);
publicstaticvoidstrokeCircle(Graphics2D g, int x, int y, int r){
Ellipse2D circle = new Ellipse2D.Double(x-r, y-r, 2*r, 2*r);
g.draw(circle);
}
publicstaticvoidfillCircle(Graphics2D g, int x, int y, int r){
Ellipse2D circle = new Ellipse2D.Double(x-r, y-r, 2*r, 2*r);
g.fill(circle);
}
publicstaticvoidstrokeRectangle(Graphics2D g, int x, int y, int w, int h){
Rectangle2D rectangle = new Rectangle2D.Double(x, y, w, h);
g.draw(rectangle);
}
publicstaticvoidfillRectangle(Graphics2D g, int x, int y, int w, int h){
Rectangle2D rectangle = new Rectangle2D.Double(x, y, w, h);
g.fill(rectangle);
}
publicstaticvoidsetColor(Graphics2D g, Color color){
g.setColor(color);
}
publicstaticvoidsetStrokeWidth(Graphics2D g, int w){
int strokeWidth = w;
g.setStroke(new BasicStroke(strokeWidth, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND));
}
publicstaticvoidpause(int t) {
try {
Thread.sleep(t);
}
catch (InterruptedException e) {
System.out.println("Error sleeping");
}
}
publicstaticvoidputImage(Graphics2D g, int x, int y, String imageURL){
ImageIcon icon = new ImageIcon(imageURL);
Image image = icon.getImage();
g.drawImage(image, x, y, null);
}
publicstaticvoiddrawText(Graphics2D g, String text, int centerx, int centery){
if(text == null)
thrownew IllegalArgumentException("Text is null in drawText function!");
FontMetrics metrics = g.getFontMetrics();
int w = metrics.stringWidth(text);
int h = metrics.getDescent();
g.drawString(text, centerx - w/2, centery + h);
}
}
package com.egeo.jframetext;
import java.awt.EventQueue;
import java.awt.Point;
publicclassAlgoVisualizer {privatestaticint DELAY = 40;
private MonteCarloPiData data;
private AlgoFrame frame;
privateint N;
publicAlgoVisualizer(int sceneWidth, int sceneHeight, int N){
//判断高度宽度是否相等(是否为正方形)if(sceneWidth != sceneHeight)
thrownew IllegalArgumentException("This demo must be run in a square window!");
this.N = N;
//在正方形内画圆
Circle circle = new Circle(sceneWidth/2, sceneHeight/2, sceneWidth/2);
data = new MonteCarloPiData(circle);
// 初始化视图
EventQueue.invokeLater(() -> {
frame = new AlgoFrame("Monte Carlo", sceneWidth, sceneHeight);
new Thread(() -> {
run();
}).start();
});
}
publicvoidrun(){
for(int i = 0 ; i < N ; i ++){
//每100次进行一次绘制if( i % 100 == 0) {
frame.render(data);
//等待时间
AlgoVisHelper.pause(DELAY);
//控制台打印PI值
System.out.println(data.estimatePi());
}
int x = (int)(Math.random() * frame.getCanvasWidth());
int y = (int)(Math.random() * frame.getCanvasHeight());
data.addPoint(new Point(x, y));
}
}
publicstaticvoidmain(String[] args) {
int sceneWidth = 800;
int sceneHeight = 800;
int N = 20000;
AlgoVisualizer vis = new AlgoVisualizer(sceneWidth, sceneHeight, N);
}
}
逻辑处理类
package com.egeo.jframetext;
import java.awt.Point;
import java.util.LinkedList;
publicclassMonteCarloPiData {private Circle circle;
private LinkedList<Point> points;
privateint insideCircle = 0;
publicMonteCarloPiData(Circle circle){
this.circle = circle;
points = new LinkedList<Point>();
}
public Circle getCircle(){
return circle;
}
publicintgetPointsNumber(){
return points.size();
}
public Point getPoint(int i){
if(i < 0 || i >= points.size())
thrownew IllegalArgumentException("out of bound in getPoint!");
return points.get(i);
}
publicvoidaddPoint(Point p){
points.add(p);
//是否在圆内if(circle.contain(p))
insideCircle ++;
}
publicdoubleestimatePi(){
if(points.size() == 0)
return0.0;
int circleArea = insideCircle;
int squareArea = points.size();
return (double)circleArea * 4 / squareArea;
}
}
程序运行效果
蒙特卡洛算法求解三门问题
package com.egeo.jframetext;
publicclass ThreeGatesExperiment {
//模拟次数privateint N;
publicThreeGatesExperiment(int N){
if(N <= 0)
thrownew IllegalArgumentException("N must be larger than 0!");
this.N = N;
}
publicvoidrun(boolean changeDoor){
int wins = 0;
for(int i = 0 ; i < N ; i ++)
if(play(changeDoor))
wins ++;
System.out.println(changeDoor ? "Change" : "Not Change");
System.out.println("winning rate: " + (double)wins/N);
}
private boolean play(boolean changeDoor){
// Door 0, 1, 2//随机中奖的门int prizeDoor = (int)(Math.random() * 3);
//观众选中的门int playerChoice = (int)(Math.random() * 3);
//是否换门if( playerChoice == prizeDoor)
return changeDoor ? false : true;
elsereturn changeDoor ? true : false;
}
publicstaticvoidmain(String[] args) {
int N = 10000000;
ThreeGatesExperiment exp = new ThreeGatesExperiment(N);
exp.run(true);
System.out.println();
exp.run(false);
}
}