• [算法] 随机模拟问题


    分钱问题

    • 100个人,初始每人100块钱,每轮每人将1元随机分给另一个人,若干轮过后,100个人的财富分布情况会怎样
    • 画布的原点在左上角,y轴向下

    AlgoVisHelper.java

     1 import java.awt.EventQueue;
     2 import java.util.Arrays;
     3 
     4 public class AlgoVisualizer {
     5     
     6     private static int DELAY = 40;
     7     private int[] money;
     8     private AlgoFrame frame;
     9     
    10     public AlgoVisualizer(int sceneWidth, int sceneHeight) {
    11         
    12         // 初始化数据
    13         money = new int[100];
    14         for(int i = 0 ; i < money.length ; i ++) {
    15             money[i] = 100;
    16         }
    17         
    18         // 初始化视图
    19         EventQueue.invokeLater(()->{
    20             frame = new AlgoFrame("Welcome",sceneWidth,sceneHeight);
    21             new Thread(()->{
    22                     run();
    23             }).start();  
    24         });
    25     }
    26     
    27     private void run() {
    28         while(true) {
    29             Arrays.sort(money);
    30             frame.render(money);
    31             AlgoVisHelper.pause(DELAY);
    32             
    33             for(int k = 0 ; k < 50 ; k ++ ) {
    34                 for(int i = 0 ; i < money.length ; i ++ ) {
    35                         int j = (int)(Math.random() * money.length);
    36                         money[i] -= 1;
    37                         money[j] += 1;
    38                 }
    39             }
    40         }
    41     }
    42     
    43     public static void main(String[] args) {
    44         
    45         int sceneWidth = 1000;
    46         int sceneHeight = 800;
    47         
    48         AlgoVisualizer visualizer = new AlgoVisualizer(sceneWidth, sceneHeight);
    49         
    50     }
    51 }
    View Code

    AlgoVisualizer.java

     1 import java.awt.EventQueue;
     2 import java.util.Arrays;
     3 
     4 public class AlgoVisualizer {
     5     
     6     private static int DELAY = 40;
     7     private int[] money;
     8     private AlgoFrame frame;
     9     
    10     public AlgoVisualizer(int sceneWidth, int sceneHeight) {
    11         
    12         // 初始化数据
    13         money = new int[100];
    14         for(int i = 0 ; i < money.length ; i ++) {
    15             money[i] = 100;
    16         }
    17         
    18         // 初始化视图
    19         EventQueue.invokeLater(()->{
    20             frame = new AlgoFrame("Welcome",sceneWidth,sceneHeight);
    21             new Thread(()->{
    22                     run();
    23             }).start();  
    24         });
    25     }
    26     
    27     private void run() {
    28         while(true) {
    29             Arrays.sort(money);
    30             frame.render(money);
    31             AlgoVisHelper.pause(DELAY);
    32             
    33             for(int k = 0 ; k < 50 ; k ++ ) {
    34                 for(int i = 0 ; i < money.length ; i ++ ) {
    35                         int j = (int)(Math.random() * money.length);
    36                         money[i] -= 1;
    37                         money[j] += 1;
    38                 }
    39             }
    40         }
    41     }
    42     
    43     public static void main(String[] args) {
    44         
    45         int sceneWidth = 1000;
    46         int sceneHeight = 800;
    47         
    48         AlgoVisualizer visualizer = new AlgoVisualizer(sceneWidth, sceneHeight);
    49         
    50     }
    51 }
    View Code

    AlgoFrame.java

     1 import java.awt.Color;
     2 import java.awt.Dimension;
     3 import java.awt.Graphics;
     4 import java.awt.Graphics2D;
     5 import java.awt.RenderingHints;
     6 
     7 import javax.swing.JFrame;
     8 import javax.swing.JPanel;
     9 
    10 public class AlgoFrame extends JFrame{
    11     
    12     private int canvasWidth;
    13     private int canvasHeight;
    14     
    15     public AlgoFrame(String title, int canvasWidth, int canvasHeight) {
    16         
    17         super(title);
    18         
    19         this.canvasWidth = canvasWidth;
    20         this.canvasHeight = canvasHeight;
    21         
    22         AlgoCanvas canvas = new AlgoCanvas();
    23         setContentPane(canvas);
    24         pack();
    25         
    26         setResizable(false);
    27         setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    28         setVisible(true);
    29     }
    30     
    31     public AlgoFrame(String title) {
    32         this(title, 1024, 768);
    33     }
    34     
    35     public int getCanvasWidth() {return canvasWidth;}
    36     public int getCanvasHeight() {return canvasHeight;}
    37 
    38     private int[] money;
    39     public void render(int[] money) {
    40         this.money = money;
    41         repaint();
    42     }
    43     
    44     private class AlgoCanvas extends JPanel{
    45         
    46         public AlgoCanvas() {
    47             super(true);
    48         }
    49         
    50         @Override
    51         public void paintComponent(Graphics g) {
    52             
    53             super.paintComponent(g);
    54             
    55             Graphics2D g2d = (Graphics2D)g;
    56             
    57             //抗锯齿
    58             RenderingHints hints = new RenderingHints(
    59                             RenderingHints.KEY_ANTIALIASING, 
    60                             RenderingHints.VALUE_ANTIALIAS_ON);
    61             g2d.addRenderingHints(hints);
    62             
    63             //具体绘制
    64             int w = canvasWidth / money.length;
    65             for(int i = 0 ; i < money.length ; i ++ ) {
    66                 if(money[i] > 0) {
    67                     AlgoVisHelper.setColor(g2d, AlgoVisHelper.Blue);
    68                     AlgoVisHelper.fillRectangle(g2d, 
    69                             i*w + 1, canvasHeight/2 - money[i], w-1, money[i]);
    70                 }
    71                 else if(money[i] < 0) {
    72                     AlgoVisHelper.setColor(g2d, AlgoVisHelper.Red);
    73                     AlgoVisHelper.fillRectangle(g2d,
    74                             i*w + 1, canvasHeight/2, w-1, -money[i]);
    75                 }
    76             }
    77         }
    78         
    79         @Override
    80         public Dimension getPreferredSize() {
    81             return new Dimension(canvasWidth, canvasHeight);
    82         }
    83     }
    84 }    
    View Code

     

    蒙特卡洛方法

    • 为解决裂变物质的中子随机扩散问题而提出
    • 通过大量随机样本,了解一个系统,进而得到所要计算的值
    • 红色点的数量-->圆的面积;红色点+绿色点的数量-->方的面积
    • PI = 4 * 红色点数 / 总点数

       

    AlgoFrame.java

     1 import java.awt.Color;
     2 import java.awt.Dimension;
     3 import java.awt.Graphics;
     4 import java.awt.Graphics2D;
     5 import java.awt.Point;
     6 import java.awt.RenderingHints;
     7 import java.util.LinkedList;
     8 
     9 import javax.swing.JFrame;
    10 import javax.swing.JPanel;
    11 
    12 public class AlgoFrame extends JFrame{
    13     private int canvasWidth;
    14     private int canvasHeight;
    15     
    16     public AlgoFrame(String title, int canvasWidth, int canvasHeight) {
    17         super(title);
    18         
    19         this.canvasWidth = canvasWidth;
    20         this.canvasHeight = canvasHeight;
    21         
    22         AlgoCanvas canvas = new AlgoCanvas();
    23         setContentPane(canvas);
    24         pack();
    25         
    26         setResizable(false);
    27         setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    28         setVisible(true);
    29     }
    30     
    31     public AlgoFrame(String title) {
    32         this(title, 1024, 768);
    33     }
    34     
    35     public int getCanvasWidth() {return canvasWidth;}
    36     public int getCanvasHeight() {return canvasHeight;}
    37 
    38     private MonteCarloPiaData data;
    39     public void render(MonteCarloPiaData data) {
    40         this.data = data;
    41         repaint();
    42     }
    43     
    44     private class AlgoCanvas extends JPanel{
    45         
    46         public AlgoCanvas() {
    47             super(true);
    48         }
    49         
    50         @Override
    51         public void paintComponent(Graphics g) {
    52             
    53             super.paintComponent(g);
    54             
    55             Graphics2D g2d = (Graphics2D)g;
    56             
    57             //抗锯齿
    58             RenderingHints hints = new RenderingHints(
    59                                         RenderingHints.KEY_ANTIALIASING, 
    60                                         RenderingHints.VALUE_ANTIALIAS_ON);
    61             g2d.addRenderingHints(hints);
    62             
    63             //具体绘制
    64             Circle circle = data.getCircle();
    65             AlgoVisHelper.setStrokeWidth(g2d, 3);
    66             AlgoVisHelper.setColor(g2d, AlgoVisHelper.Blue);
    67             AlgoVisHelper.strokeCircle(g2d, circle.getX(), circle.getY(), circle.getR());
    68             
    69             for(int i = 0 ; i < data.getPointsNumber() ; i ++ ) {
    70                 Point p = data.getPoint(i);
    71                 if(circle.contain(p))
    72                     AlgoVisHelper.setColor(g2d, AlgoVisHelper.Red);
    73                 else
    74                     AlgoVisHelper.setColor(g2d, AlgoVisHelper.Green);
    75                 AlgoVisHelper.fillCircle(g2d, p.x, p.y, 3);
    76             }
    77         }
    78         
    79         @Override
    80         public Dimension getPreferredSize() {
    81             return new Dimension(canvasWidth, canvasHeight);
    82         }
    83     }
    84 }    
    View Code

    AlgoVisualizer.java

     1 import java.awt.EventQueue;
     2 import java.awt.Point;
     3 import java.util.LinkedList;
     4 
     5 public class AlgoVisualizer {
     6     
     7     private static int DELAY = 40;
     8     
     9     private MonteCarloPiaData data;
    10     private AlgoFrame frame;
    11     private int N;
    12     
    13     public AlgoVisualizer(int sceneWidth, int sceneHeight, int N) {
    14         
    15         if(sceneWidth != sceneHeight)
    16             throw new IllegalArgumentException("This demo must be run in a square");
    17         // 初始化数据
    18         this.N = N;
    19         Circle circle = new Circle(sceneWidth/2, sceneHeight/2, sceneWidth/2);
    20         data = new MonteCarloPiaData(circle);
    21         
    22         // 初始化视图
    23         EventQueue.invokeLater(()->{
    24             frame = new AlgoFrame("Get Pi with Monte Carlo",sceneWidth,sceneHeight);
    25             new Thread(()->{
    26                     run();
    27             }).start();  
    28         });
    29     }
    30     
    31     // 动画逻辑
    32     private void run() {
    33         for(int i = 0 ; i < N ; i ++ ) {
    34             
    35             if(i % 100 == 0) {
    36                 frame.render(data);
    37                 AlgoVisHelper.pause(DELAY);
    38                 System.out.println(data.estimatePi());
    39             }
    40             
    41             int x = (int)(Math.random() * frame.getCanvasWidth());
    42             int y = (int)(Math.random() * frame.getCanvasHeight());
    43             data.addPoint(new Point(x,y));
    44         }
    45     }
    46     
    47     public static void main(String[] args) {
    48         
    49         int sceneWidth = 800;
    50         int sceneHeight = 800;
    51         int N = 10000;
    52         
    53         AlgoVisualizer visualizer = new AlgoVisualizer(sceneWidth, sceneHeight, N);
    54     }
    55 }
    View Code

    AlgoVisHelper.java 

     1 import java.awt.BasicStroke;
     2 import java.awt.Color;
     3 import java.awt.Graphics2D;
     4 import java.awt.geom.Ellipse2D;
     5 
     6 public class AlgoVisHelper {
     7     public AlgoVisHelper() {}
     8     
     9     public static final Color Red = new Color(0xF44336);
    10     public static final Color Pink = new Color(0xE91E63);
    11     public static final Color Purple = new Color(0x9C27B0);
    12     public static final Color DeepPurple = new Color(0x673AB7);
    13     public static final Color Indigo = new Color(0x3F51B5);
    14     public static final Color Blue = new Color(0x2196F3);
    15     public static final Color LightBlue = new Color(0x03A9F4);
    16     public static final Color Cyan = new Color(0x00BCD4);
    17     public static final Color Teal = new Color(0x009688);
    18     public static final Color Green = new Color(0x4CAF50);
    19     public static final Color LightGreen = new Color(0x8BC34A);
    20     public static final Color Lime = new Color(0xCDDC39);
    21     public static final Color Yellow = new Color(0xFFEB3B);
    22     public static final Color Amber = new Color(0xFFC107);
    23     public static final Color Orange = new Color(0xFF9800);
    24     public static final Color DeepOrange = new Color(0xFF5722);
    25     public static final Color Brown = new Color(0x795548);
    26     public static final Color Grey = new Color(0x9E9E9E);
    27     public static final Color BlueGrey = new Color(0x607D8B);
    28     public static final Color Black = new Color(0x000000);
    29     public static final Color White = new Color(0xFFFFFF);
    30     
    31     public static void setStrokeWidth(Graphics2D g2d, int w) {
    32         int strokeWidth = w;
    33         g2d.setStroke(new BasicStroke(strokeWidth, BasicStroke.CAP_ROUND,BasicStroke.JOIN_ROUND));
    34     }
    35     public static void setColor(Graphics2D g2d, Color color) {
    36         g2d.setColor(color);
    37     }
    38     public static void strokeCircle(Graphics2D g2d, int x, int y, int r) {
    39         Ellipse2D circle = new Ellipse2D.Double(x-r, y-r, 2*r, 2*r);
    40         g2d.draw(circle);
    41     }
    42     public static void fillCircle(Graphics2D g2d, int x, int y, int r) {
    43         Ellipse2D circle = new Ellipse2D.Double(x-r, y-r, 2*r, 2*r);
    44         g2d.fill(circle);
    45     }
    46     public static void pause(int t) {
    47         try {
    48             Thread.sleep(t);
    49         }
    50         catch(InterruptedException e) {
    51             System.out.println("Error in sleeping.");
    52         }
    53     }
    54 }
    View Code

    Circle.java

     1 import java.awt.Point;
     2 
     3 public class Circle {
     4     
     5     public int x, y, r;
     6     
     7     public Circle(int x, int y, int r ) {
     8         this.x = x;
     9         this.y = y;
    10         this.r = r;
    11     }
    12     
    13     public int getX() { return x; }
    14     public int getY() { return y; }
    15     public int getR() { return r; }
    16     
    17     public boolean contain(Point p) {
    18         return Math.pow(p.getX() - x, 2) + Math.pow(p.getY() - y, 2) <= r*r;
    19     }
    20 }
    View Code

    MonteCarloPiaData.java

     1 import java.awt.Point;
     2 import java.util.LinkedList;
     3 
     4 public class MonteCarloPiaData {
     5     
     6     private Circle circle;
     7     private int insideCircle = 0;
     8     private LinkedList<Point> points;
     9     
    10     public MonteCarloPiaData(Circle circle) {
    11         this.circle = circle;
    12         points = new LinkedList<Point>();
    13     }
    14     
    15     public Circle getCircle() {
    16         return circle;
    17     }
    18     
    19     public Point getPoint(int i) {
    20         if(i < 0 || i >= points.size())
    21             throw new IllegalArgumentException("out of bound in getPoint!");
    22         return points.get(i);
    23     }
    24     
    25     public int getPointsNumber() {
    26         return points.size();
    27     }
    28     
    29     public void addPoint(Point p) {
    30         points.add(p);
    31         if(circle.contain(p))
    32             insideCircle ++;
    33     }
    34     
    35     public double estimatePi() {
    36         if(points.size() == 0)
    37             return 0.0;
    38         int circleArea = insideCircle;
    39         int squareArea = points.size();
    40         return (double)circleArea*4 / squareArea;
    41     }
    42 }
    View Code

    控制台演示

    MonteCarloExperiment.java

     1 import java.awt.*;
     2 
     3 public class MonteCarloExperiment {
     4     
     5     private int squareSide;
     6     private int N;
     7     private int outputInterval = 100;
     8     
     9     public MonteCarloExperiment(int squareSide, int N) {
    10         if(squareSide <= 0 || N <= 0)
    11             throw new IllegalArgumentException("squareSide and N must larger than 0");
    12         this.squareSide = squareSide;
    13         this.N = N;
    14     }
    15     
    16     public void setOutputInterval(int interval) {
    17         if(interval <= 0)
    18             throw new IllegalArgumentException("interval must be larger than 0");
    19         this.outputInterval = interval;
    20     }
    21     
    22     public void run() {
    23         
    24         Circle circle = new Circle(squareSide/2, squareSide/2, squareSide/2);
    25         MonteCarloPiData data = new MonteCarloPiData(circle);
    26         
    27         for(int i = 0 ; i < N ; i ++) {
    28             if( i % outputInterval == 0 )
    29                 System.out.println(data.estimatePi());
    30             int x = (int)(Math.random() * squareSide);
    31             int y = (int)(Math.random() * squareSide);
    32             data.addPoint(new Point(x,y));
    33         }
    34     }
    35     
    36     public static void main(String[] args) {
    37         
    38         int squareSide = 800;
    39         int N = 1000000;
    40         
    41         MonteCarloExperiment exp = new MonteCarloExperiment(squareSide, N);
    42         exp.setOutputInterval(10000);
    43         exp.run();
    44     }
    45 }
    View Code

    三门问题

    • 有三扇门,其中一扇门后面有汽车,两扇后面没东西
    • 当参赛者选定一扇门但未开启时,主持人会开启剩下两扇门中的一扇,这扇门后面一定没有汽车
    • 如果参赛者现在换另一个门,会不会提高中奖概率?
    • 换门中奖率2/3,不换门中奖率1/3
    • 在计算机中模拟,看最后收敛到的结果

     ThreeGateExperiment.java

     1 public class ThreeGatesExperiment {
     2 
     3     private int N;
     4 
     5     public ThreeGatesExperiment(int N){
     6 
     7         if(N <= 0)
     8             throw new IllegalArgumentException("N must be larger than 0!");
     9 
    10         this.N = N;
    11     }
    12 
    13     public void run(boolean changeDoor){
    14 
    15         int wins = 0;
    16         for(int i = 0 ; i < N ; i ++)
    17             if(play(changeDoor))
    18                 wins ++;
    19 
    20         System.out.println(changeDoor ? "Change" : "Not Change");
    21         System.out.println("winning rate: " + (double)wins/N);
    22     }
    23 
    24     private boolean play(boolean changeDoor){
    25 
    26         // Door 0, 1, 2
    27         int prizeDoor = (int)(Math.random() * 3);
    28         int playerChoice = (int)(Math.random() * 3);
    29 
    30         if( playerChoice == prizeDoor)
    31             return changeDoor ? false : true;
    32         else
    33             return changeDoor ? true : false;
    34     }
    35 
    36     public static void main(String[] args) {
    37 
    38         int N = 1000;
    39         ThreeGatesExperiment exp = new ThreeGatesExperiment(N);
    40 
    41         exp.run(true);
    42         System.out.println();
    43         exp.run(false);
    44     }
    45 }
    View Code

        

    你会不会中奖

    • 游戏中有一种宝箱,打开宝箱获得传奇武器的概率是20%
    • 打开5个这样的宝箱,获得传奇武器的概率是多少? 

    WinningPrize.java

     1 public class WinningPrize {
     2 
     3     private double chance;
     4     private int playTime;
     5     private int N;
     6 
     7     public WinningPrize(double chance, int playTime, int N){
     8 
     9         if(chance < 0.0 || chance > 1.0)
    10             throw new IllegalArgumentException("chance must be between 0 and 1!");
    11 
    12         if(playTime <= 0 || N <= 0)
    13             throw new IllegalArgumentException("playTime or N must be larger than 0!");
    14 
    15         this.chance = chance;
    16         this.playTime = playTime;
    17         this.N = N;
    18     }
    19 
    20     public void run(){
    21 
    22         int wins = 0;
    23         for(int i = 0 ; i < N ; i ++)
    24             if(play())
    25                 wins ++;
    26 
    27         System.out.println("winning rate: " + (double)wins/N);
    28     }
    29 
    30     private boolean play(){
    31         for(int i = 0 ; i < playTime ; i ++)
    32             if(Math.random() < chance)
    33                 return true;
    34         return false;
    35     }
    36 
    37     public static void main(String[] args) {
    38 
    39         double chance = 0.2;
    40         int playTime = 5;
    41         int N = 1000000;
    42 
    43         WinningPrize exp = new WinningPrize(chance, playTime, N);
    44         exp.run();
    45     }
    46 }
    View Code

      

  • 相关阅读:
    day7django数据库操作
    day4django请求和响应、视图
    计算数字 k 在 0 到 n 中的出现的次数,k 可能是 0~9 的一个值
    day5crm模型、数据库增删改查
    存储过程和自定义函数的区别
    mysql复制表
    搜索关键词高亮
    classpath目录
    nginx 转发https请求
    Bert pretraining
  • 原文地址:https://www.cnblogs.com/cxc1357/p/12853746.html
Copyright © 2020-2023  润新知