美文网首页Java那些事
用Java程序实现新冠病毒扩散原理

用Java程序实现新冠病毒扩散原理

作者: Bruce基 | 来源:发表于2020-03-27 07:08 被阅读0次

    简单介绍

    最近新冠肺炎在世界蔓延迅速,传染性特别强,感谢并致敬医护人员的努力,为你们致敬为中国加油!

    以下是模拟病毒传染模式,具体方案如下:

    模拟方案

    • 首先需要构造一个200 * 200的格子界面
    • 有四种不同的颜色状态标记着程序执行的过程
    • 程序执行10次,初始化格子也就是0的时候,需要在整个格子最中心的100个格子标记为红色,剩余数据随机抽取四千(且不能重复)标记为黑色,其余没有标记的为白色。
    • 之后第2次到第10次的所有数据随机转化为不同颜色

    说明

    • 红色代表已确诊
    • 黑色代表已死亡
    • 白色代表隔离期
    • 绿色代表未感染

    模拟结果

    新冠病毒扩散图

    执行源码

    import java.awt.Color;
    import java.awt.Container;
    import java.awt.Graphics;
    import java.util.ArrayList;
    import java.util.HashMap;
    import java.util.HashSet;
    import java.util.List;
    import java.util.Random;
    import java.util.Set;
    
    import javax.swing.JFrame;
    
    public class DrawSee extends JFrame {
    
        private static final long serialVersionUID = -3469074514775590338L;
        private static final int sx = 20;// 游戏区域200*200方块的起始横坐标
        private static final int sy = 40;// 游戏区域200*200方块的起始纵坐标
        private static final int w = 3;// 每个小方格的边长
        private static final int rw = 600;// 游戏区域200*200方块的边长
    
        private Graphics jg;
        private Color rectColor = new Color(0xf5f5f5);
        /**
        * DrawSee构造方法
        */
        public DrawSee() {
            Container p = getContentPane();
            setBounds(100, 100, 650, 650);
            setVisible(true);
            p.setBackground(rectColor);
            setLayout(null);
            setResizable(false);
            this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    
            try {
                Thread.sleep(500);
            } catch (Exception e) {
                e.printStackTrace();
            }
    
            // 获取专门用于在窗口界面上绘图的对象
            jg = this.getGraphics();
            // 绘制游戏区域
            paintComponents(jg);
        }
    
        /**
        * 开始
        */
        public void paintComponents(Graphics g) {
            try {
                // 设置线条颜色为红色
                g.setColor(Color.WHITE);
    
                // 绘制外层矩形框
                g.drawRect(sx, sy, rw, rw);
    
                int N = 200;
                /*
                * 绘制水平200个,垂直200个方格。 即水平方向199条线,垂直方向199条线, 外围四周4条线已经画过了,不需要再画。
                */
                for (int i = 1; i < N; i++) {
                    // 绘制第i条竖直线
                    g.drawLine(sx + (i * w), sy, sx + (i * w), sy + rw);
                    // 绘制第i条水平线
                    g.drawLine(sx, sy + (i * w), sx + rw, sy + (i * w));
                }
                // 填写第i行从第1个方格到第N个方格里面的背景颜色(方格序号从0开始)
                int[][] s = new int[N][N];
                int sl = s.length;
                List<Object> list1 = new ArrayList<Object>();
                HashMap<String, String> map = new HashMap<String, String>();
                for (int t = 0; t < 70; t++) {
                    if (t == 0) {
                        t0(N, sl, s);
                    } else {
                        if (t < 60) {
                            tn(N, sl, s, map, list1, t);
                        }
                        dataChange(list1, s, t);
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    
        /**
        * 数据是保留10个步长之后并根据round 向其他状态转变
        * 
        * @param list
        * @param s
        * @param t
        */
        private void dataChange(List<Object> list, int[][] s, int t) {
            int a1 = 0, a2 = 0, a3 = 0, a4 = 0;
            for (int x = list.size() - 1; x >= 0; x--) {
                a3 = Integer.parseInt(list.get(x).toString().split("a")[2].toString());
                if (a3 - t > 1) {
                    a1 = Integer.parseInt(list.get(x).toString().split("a")[0].toString());
                    a2 = Integer.parseInt(list.get(x).toString().split("a")[1].toString());
                    a4 = Integer.parseInt(list.get(x).toString().split("a")[3].toString());
    
                    // 修改概率
                    if (a4 > 0 && a4 <= 3000) {
                        s[a1][a2] = -1;
                    } else if (a4 > 3000 && a4 <= 9000) {
                        s[a1][a2] = 2;
                    } else {
                        s[a1][a2] = 1;
                    }
                    list.remove(x);
                }
            }
    
        }
    
        /**
        * tn时刻数据
        * 
        * @param N
        * @param slt
        * @param sl
        * @param s
        * @param map
        * @param map1
        * @param list1
        * @param t
        */
        private void tn(int N, int sl, int[][] s, HashMap<String, String> map, List<Object> list1, int t) {
            int slt = 0;
            int round = 0;
            HashMap<String, String> map1 = new HashMap<String, String>();
            for (int k = 0; k < s.length; k++) {
                slt = s[k].length;
                for (int k2 = 0; k2 < slt; k2++) {
                    // 状态为1记录并且去除步长在10以内的重复数据 放到list1中
                    if (s[k][k2] == 1) {
                        round = new Random().nextInt(10000);
                        if (map.containsKey(k + "a" + k2 + "a")) {
                            if (t - Integer.parseInt(map.get(k + "a" + k2 + "a").split("a")[2].toString()) > 10) {
                                map.put(k + "a" + k2 + "a", k + "a" + k2 + "a" + t + "a" + round + "a");
                                map1.put(k + "a" + k2 + "a", k + "a" + k2 + "a" + t + "a" + round + "a");
                                list1.add(map1.get(k + "a" + k2 + "a"));
                            }
                        } else {
                            map.put(k + "a" + k2 + "a", k + "a" + k2 + "a" + t + "a" + round + "a");
                            map1.put(k + "a" + k2 + "a", k + "a" + k2 + "a" + t + "a" + round + "a");
                            list1.add(map1.get(k + "a" + k2 + "a"));
                        }
    
                    }
    
                    // 状态为0向其他状态改变
                    if (s[k][k2] == 0) {
                        round = new Random().nextInt(10000);
                        // 修改概率
                        if (round > 0 && round <= 1000) {
                            s[k][k2] = -1;
                        } else if (round > 9000 && round <= getrNum(10000, 0)) {
                            System.out.println("round:" + round);
                            s[k][k2] = 1;
                        } else if (round > 1000 && round <= 9000) {
                            s[k][k2] = 2;
                        } else {
                            s[k][k2] = 0;
                        }
                    }
    
                    // 状态为-1向其他状态改变
                    if (s[k][k2] == -1) {
                        round = new Random().nextInt(10000);
                        // 修改概率
                        if (round > 0 && round <= 4000) {
                            s[k][k2] = 0;
                        } else {
                            s[k][k2] = -1;
                        }
                    }
    
                    // 状态为2向其他状态改变
                    if (s[k][k2] == 2) {
                        round = new Random().nextInt(10000);
                        // 修改概率
                        if (round > 0 && round <= 1000) {
                            s[k][k2] = 0;
                        } else {
                            s[k][k2] = 2;
                        }
                    }
    
                }
            }
            // 上色
            for (int i = 0; i < N; i++) {
                for (int j = 0; j < N; j++) {
                    color(i, j, s);
                }
            }
            map1 = null;
        }
    
        /**
        * t0时刻
        * 
        * @param N
        * @param slt
        * @param sl
        * @param s
        */
        private void t0(int N, int sl, int[][] s) {
            int slt = 0, a1 = 0, a2 = 0;
            List<Object> list = new ArrayList<Object>();
            // 初始化1的值
            for (int k = 0; k < sl; k++) {
                slt = s[k].length;
                for (int k2 = 0; k2 < slt; k2++) {
                    if (k >= 80 && k < 100 && k2 >= 80 && k2 < 100) {
                        s[k][k2] = 1;
                    } else {
                        // 剩余数据
                        list.add(k + "a" + k2 + "a");
                    }
                }
            }
            // 剩余数据全部转换为0
            for (int x = 0; x < list.size(); x++) {
                a1 = Integer.parseInt(list.get(x).toString().split("a")[0].toString());
                a2 = Integer.parseInt(list.get(x).toString().split("a")[1].toString());
                s[a1][a2] = 0;
            }
    
            // 在为0 的基础上抽取4000 数据赋值为-1
            Set<Integer> sets = getRandom(4000, list.size());
            for (Integer itg : sets) {
                a1 = Integer.parseInt(list.get(itg).toString().split("a")[0].toString());
                a2 = Integer.parseInt(list.get(itg).toString().split("a")[1].toString());
                s[a1][a2] = -1;
            }
    
            // 上色
            for (int i = 0; i < N; i++) {
                for (int j = 0; j < N; j++) {
                    color(i, j, s);
                }
            }
        }
    
        /**
        * 讲制定小方格设置为指定背景颜色
        * 
        * @param cx
        *            方格的水平方向序号
        * @param cy
        *            方格的垂直方向序号
        * @param color
        */
        private void setGrid(int cx, int cy, Color color) {
            // 将绘图对象设置为灰色,后面会将方格背景设置为此颜色
            jg.setColor(color);
            /**
            * 方格上绘制一个小一点的矩形,矩形背景颜色为color,
            */
            jg.fillRect(sx + (cx * w), sy + (cy * w), w - 1, w - 1);
    
        }
    
        /**
        * 根据nlength 长度 产生 num 随机数(并且不重复)
        * 
        * @param num
        * @param nlength
        * @return
        */
        public Set<Integer> getRandom(int num, int nlength) {
            if (nlength < num) {
                return null;
            }
            int index = 0;
            Set<Integer> set = new HashSet<Integer>();
            for (int i = 0; i < nlength; i++) {
                index = (int) (Math.random() * nlength);
                if (set.size() >= 4000) {
                    break;
                } else {
                    set.add(index);
                }
    
            }
            return set;
        }
    
        /**
        * main
        * 
        * @param args
        */
        public static void main(String[] args) {
            new DrawSee();
        }
    
        /**
        * 随机生成最小到最大的数据
        * 
        * @param max
        * @param min
        * @return
        */
        private int getrNum(int max, int min) {
            Random random = new Random();
            return random.nextInt(max) % (max - min + 1) + min;
    
        }
    
        /**
        * 设置每种状态的背景颜色
        * 
        * @param i
        * @param j
        * @param s
        */
        private void color(int i, int j, int[][] s) {
            if (s[i][j] == -1) {
                // 状态为空
                setGrid(i, j, Color.BLACK);
            } else if (s[i][j] == 0) {
                // 易感冒
                setGrid(i, j, Color.WHITE);
            } else if (s[i][j] == 1) {
                // 感染者
                setGrid(i, j, Color.RED);
            } else if (s[i][j] == 2) {
                // 恢复者
                setGrid(i, j, Color.GREEN);
            }
        }
    
    }
    

    说明

    本文只做学习参考,如有任何不准确的地方欢迎指正。

    我的邮箱: lulongji2011@163.com

    版权声明:

    本文为博主原创文章,转载请附上原文出处链接和本声明。

    相关文章

      网友评论

        本文标题:用Java程序实现新冠病毒扩散原理

        本文链接:https://www.haomeiwen.com/subject/kimcuhtx.html