zoukankan      html  css  js  c++  java
  • 关于100个人随机给钱的模拟实验

    前言

    在知乎上看到一个好玩的问题:房间里有100个人,每人都有100元钱,他们在玩一个游戏。每轮游戏中,每个人都要拿出一元钱随机给另一个人,最后这100个人的财富分布是怎样的?

    今天使用java中的GUI来模拟一下。

    实现

    效果图如下

    红色表示负债,模拟次数大概150W次。

    代码实现

    可视化主类

    import java.awt.EventQueue;
    import java.util.Arrays;
    
    public class AlgoVisualizer {
    
      private static int DELAY = 40;
      private int[] money;
      private AlgoFrame frame;
    
      public AlgoVisualizer(int sceneWidth, int sceneHeight) {
    
        // 初始化数据
        money = new int[100];
        for (int i = 0; i < money.length; i++) {
          money[i] = 100;
        }
    
        // 初始化视图
        EventQueue.invokeLater(() -> {
          frame = new AlgoFrame("Money Problem", sceneWidth, sceneHeight);
          new Thread(this::run).start();
        });
      }
    
      public void run() {
    
        while (true) {
    
          // 改进2:是否排序
          Arrays.sort(money);
          frame.render(money);
          AlgoVisHelper.pause(DELAY);
    
          // 改进1:每一帧执行的轮数
          for (int k = 0; k < 50; k++) {
            for (int i = 0; i < money.length; i++) {
              // 改进3:允许money为负值
              //if(money[i] > 0){
              int j = (int) (Math.random() * money.length);
              money[i] -= 1;
              money[j] += 1;
              //}
            }
          }
        }
      }
    
      public static void main(String[] args) {
    
        int sceneWidth = 1000;
        int sceneHeight = 800;
    
        AlgoVisualizer vis = new AlgoVisualizer(sceneWidth, sceneHeight);
      }
    }
    

    窗口类

    import java.awt.Dimension;
    import java.awt.Graphics;
    import java.awt.Graphics2D;
    import java.awt.RenderingHints;
    import javax.swing.JFrame;
    import javax.swing.JPanel;
    
    /**
     * 主窗口
     */
    public class AlgoFrame extends JFrame {
    
      private int canvasWidth;
      private int canvasHeight;
    
      public AlgoFrame(String title, int canvasWidth, int canvasHeight) {
    
        super(title);
    
        this.canvasWidth = canvasWidth;
        this.canvasHeight = canvasHeight;
    
        AlgoCanvas canvas = new AlgoCanvas();
        setContentPane(canvas);
        pack();
    
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setResizable(false);
    
        setVisible(true);
      }
    
      public AlgoFrame(String title) {
    
        this(title, 1024, 768);
      }
    
      public int getCanvasWidth() {
        return canvasWidth;
      }
    
      public int getCanvasHeight() {
        return canvasHeight;
      }
    
      // data
      private int[] money;
    
      public void render(int[] money) {
        this.money = money;
        repaint();
      }
    
      private class AlgoCanvas extends JPanel {
    
        public AlgoCanvas() {
          // 双缓存
          super(true);
        }
    
        @Override
        public void paintComponent(Graphics g) {
          super.paintComponent(g);
    
          Graphics2D g2d = (Graphics2D) g;
    
          // 抗锯齿
          RenderingHints hints = new RenderingHints(
              RenderingHints.KEY_ANTIALIASING,
              RenderingHints.VALUE_ANTIALIAS_ON);
          hints.put(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
          g2d.addRenderingHints(hints);
    
          // 具体绘制
          int w = canvasWidth / money.length;
          for (int i = 0; i < money.length; i++) {
            if (money[i] > 0) {
              AlgoVisHelper.setColor(g2d, AlgoVisHelper.Blue);
              AlgoVisHelper.fillRectangle(g2d,
                  i * w + 1, canvasHeight / 2 - money[i], w - 1, money[i]);
            } else {
              AlgoVisHelper.setColor(g2d, AlgoVisHelper.Red);
              AlgoVisHelper.fillRectangle(g2d,
                  i * w + 1, canvasHeight / 2, w - 1, -money[i]);
            }
          }
        }
    
        @Override
        public Dimension getPreferredSize() {
          return new Dimension(canvasWidth, canvasHeight);
        }
      }
    }
    

    工具类

    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;
    
    /**
     * 工具类
     */
    public class AlgoVisHelper {
    
      private AlgoVisHelper() {
      }
    
      public static final Color Red = new Color(0xF44336);
      public static final Color Pink = new Color(0xE91E63);
      public static final Color Purple = new Color(0x9C27B0);
      public static final Color DeepPurple = new Color(0x673AB7);
      public static final Color Indigo = new Color(0x3F51B5);
      public static final Color Blue = new Color(0x2196F3);
      public static final Color LightBlue = new Color(0x03A9F4);
      public static final Color Cyan = new Color(0x00BCD4);
      public static final Color Teal = new Color(0x009688);
      public static final Color Green = new Color(0x4CAF50);
      public static final Color LightGreen = new Color(0x8BC34A);
      public static final Color Lime = new Color(0xCDDC39);
      public static final Color Yellow = new Color(0xFFEB3B);
      public static final Color Amber = new Color(0xFFC107);
      public static final Color Orange = new Color(0xFF9800);
      public static final Color DeepOrange = new Color(0xFF5722);
      public static final Color Brown = new Color(0x795548);
      public static final Color Grey = new Color(0x9E9E9E);
      public static final Color BlueGrey = new Color(0x607D8B);
      public static final Color Black = new Color(0x000000);
      public static final Color White = new Color(0xFFFFFF);
    
    
      public static void strokeCircle(Graphics2D g, int x, int y, int r) {
    
        Ellipse2D circle = new Ellipse2D.Double(x - r, y - r, 2 * r, 2 * r);
        g.draw(circle);
      }
    
      public static void fillCircle(Graphics2D g, int x, int y, int r) {
    
        Ellipse2D circle = new Ellipse2D.Double(x - r, y - r, 2 * r, 2 * r);
        g.fill(circle);
      }
    
      public static void strokeRectangle(Graphics2D g, int x, int y, int w, int h) {
    
        Rectangle2D rectangle = new Rectangle2D.Double(x, y, w, h);
        g.draw(rectangle);
      }
    
      public static void fillRectangle(Graphics2D g, int x, int y, int w, int h) {
    
        Rectangle2D rectangle = new Rectangle2D.Double(x, y, w, h);
        g.fill(rectangle);
      }
    
      public static void setColor(Graphics2D g, Color color) {
        g.setColor(color);
      }
    
      public static void setStrokeWidth(Graphics2D g, int w) {
        int strokeWidth = w;
        g.setStroke(new BasicStroke(strokeWidth, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND));
      }
    
      public static void pause(int t) {
        try {
          Thread.sleep(t);
        } catch (InterruptedException e) {
          System.out.println("Error sleeping");
        }
      }
    
      public static void putImage(Graphics2D g, int x, int y, String imageURL) {
    
        ImageIcon icon = new ImageIcon(imageURL);
        Image image = icon.getImage();
    
        g.drawImage(image, x, y, null);
      }
    
      public static void drawText(Graphics2D g, String text, int centerx, int centery) {
        if (text == null) {
          throw new 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);
      }
    
    }
    

    参考

    该如何面对这个残酷的世界?-搜狐财经
    关于“房间里有100个人,每人都有100元钱,每轮每人要拿一元钱随机给另一个人”这个游戏的解析解。-知乎
    关于100个人随机给钱的模拟实验。-知乎

  • 相关阅读:
    Jq操作表格
    最新web 2.0 配色 (一)
    Jqtable edit
    Jq公告渐隐弹出
    Jq模拟最大化最小化关闭
    JqtoggleClass
    Jq弹出公告
    jquery左右拉效果
    最新web 2.0 配色 (二)
    ZenCoding各个工具安装
  • 原文地址:https://www.cnblogs.com/strongmore/p/14591720.html
Copyright © 2011-2022 走看看