谣言传播模拟

受到该项目启发,病毒传播和谣言传播有些相似,就修改了该项目的代码,变成了谣言传播的程序(参数设置都没有科学性)
项目地址:https://github.com/alastbing/VirusBroadcastController

main.java#

Copy
package rumour; import javax.swing.*; import java.util.List; import java.util.Random; public class Main { public static void main(String[] args) { initPanel(); initInfected(); } // 初始化画布 private static void initPanel() { MyPanel p = new MyPanel(); Thread panelThread = new Thread(p); JFrame frame = new JFrame(); frame.add(p); frame.setSize(Parameter.CITY_WIDTH, Parameter.CITY_HEIGHT); frame.setLocationRelativeTo(null); frame.setVisible(true); frame.setTitle("谣言传播模拟"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); panelThread.start();// 开启画布线程 } // 产生谣言 private static void initInfected() { List<Person> people = PersonPool.getInstance().getPersonList();// 获取所有的市民 Person person; person = people.get(new Random().nextInt(people.size() - 1));// 随机挑选一个市民 person.beInfected();// 让这个市民成为谣言产生者 } }

MyPanel.java#

Copy
package rumour; import javax.swing.*; import java.awt.*; import java.util.List; import java.util.Timer; import java.util.TimerTask; public class MyPanel extends JPanel implements Runnable { public MyPanel() { super(); this.setBackground(new Color(0x444444)); } @Override public void paint(Graphics g) { super.paint(g); // 绘制代表人类的圆点 List<Person> people = PersonPool.getInstance().getPersonList(); if (people == null) { return; } for (Person person : people) { switch (person.getState()) { case Person.State.NORMAL: { // 正常人 // 政府 if (person.getRank() == 2) { g.setColor(new Color(0xe22018)); break; } // 媒体社区 else if (person.getRank() == 1) { g.setColor(new Color(0x21a3f1)); break; } // 普通人 else { g.setColor(new Color(0xdddddd)); break; } // System.out.print(person.getRank()); } case Person.State.OK: { // 辟谣者 g.setColor(new Color(0x80c342)); break; } case Person.State.SHADOW: { // 传谣者 g.setColor(new Color(0xffee00)); break; } } person.update();// 对各种状态的市民进行不同的处理 g.fillOval(person.getX(), person.getY(), 4, 4); } int captionStartOffsetX = 700; int captionStartOffsetY = 40; int captionSize = 24; // 显示数据信息 g.setColor(Color.WHITE); g.drawString("城市总人数:" + PersonPool.getInstance().getPeopleSize(-1), captionStartOffsetX, captionStartOffsetY); g.setColor(new Color(0xdddddd)); g.drawString("正常者人数:" + PersonPool.getInstance().getPeopleSize(Person.State.NORMAL), captionStartOffsetX, captionStartOffsetY + captionSize); g.setColor(new Color(0xffee00)); g.drawString("传谣者人数:" + PersonPool.getInstance().getPeopleSize(Person.State.SHADOW), captionStartOffsetX, captionStartOffsetY + 2 * captionSize); g.setColor(new Color(0x80c342)); g.drawString("辟谣者人数:" + PersonPool.getInstance().getPeopleSize(Person.State.OK), captionStartOffsetX, captionStartOffsetY + 3 * captionSize); g.setColor(new Color(0xffffff)); g.drawString("世界时间(天):" + (int) (worldTime / 10.0), captionStartOffsetX, captionStartOffsetY + 8 * captionSize); } public static int worldTime = 0;// 世界时间 public Timer timer = new Timer(); class MyTimerTask extends TimerTask { @Override public void run() { MyPanel.this.repaint(); worldTime++; } } @Override public void run() { timer.schedule(new MyTimerTask(), 0, 100);// 启动世界计时器,时间开始流动 } }

MathUtil.java#

Copy
package rumour; import java.util.Random; public class MathUtil { // 产生正态分布随机值 private static final Random randomGen = new Random(); public static double stdGaussian(double sigma, double u) { double X = randomGen.nextGaussian(); return sigma * X + u; } }

City.java#

Copy
package rumour; public class City { private int centerX; private int centerY; public City(int centerX, int centerY) { this.centerX = centerX; this.centerY = centerY; } public int getCenterX() { return centerX; } public void setCenterX(int centerX) { this.centerX = centerX; } public int getCenterY() { return centerY; } public void setCenterY(int centerY) { this.centerY = centerY; } }

Person.java#

Copy
package rumour; import java.util.List; import java.util.Random; public class Person extends Point { private City city; double targetXU;// x方向的均值 double targetYU;// y方向的均值 // 市民的状态 public interface State { int NORMAL = 0;// 正常人 int SHADOW = 1;// 相信谣言,开始传谣 int OK = 2;// 相信辟谣,开始辟谣 } public Person(City city, int x, int y, int rank) { super(x, y); this.city = city; // 对市民的初始位置进行N(x,100)的正态分布随机 targetXU = MathUtil.stdGaussian(100, x); targetYU = MathUtil.stdGaussian(100, y); Rank = rank; } // 等级,0普通人,1媒体社交,2政府 public int Rank = 0; public int getRank() { return Rank; } private int state = State.NORMAL; public int getState() { return state; } // 传谣函数 public void beInfected() { state = State.SHADOW; } // 辟谣函数 public void refute() { state = State.OK; } // 计算两点之间的直线距离 public double distance(Person person) { return Math.sqrt(Math.pow(getX() - person.getX(), 2) + Math.pow(getY() - person.getY(), 2)); } // 对各种状态的人进行不同的处理,更新市民状态 public void update() { List<Person> people = PersonPool.getInstance().personList; // 通过一个随机幸运值和安全距离决定传播给其他人 for (Person person : people) { if (person.getRank() == 2) {// 政府辟谣 float random = new Random().nextFloat(); if (random < Parameter.govRate &&(int) (MyPanel.worldTime / 10.0) >= Parameter.Time) { if (distance(person) < Parameter.govInfluence) { this.refute(); break; } } } else if (person.getRank() == 1) {// 媒体传谣辟谣 if (person.getState() == State.OK) { float random = new Random().nextFloat(); if (random < Parameter.mediaRate2 && distance(person) < Parameter.mediaInfluence) { this.refute(); break; } } if (person.getState() == State.SHADOW) { if (this.state != State.SHADOW) { float random = new Random().nextFloat(); if (random < Parameter.mediaRate1 && distance(person) < Parameter.mediaInfluence && this.getState() != State.OK) { this.beInfected(); } } } } else {// 普通人传谣辟谣 if (person.getState() == State.OK) { float random = new Random().nextFloat(); if (random < Parameter.perRate2 && distance(person) < Parameter.perInfluence) { this.refute(); break; } } if (person.getState() == State.SHADOW) { if (this.state != State.SHADOW) { float random = new Random().nextFloat(); if (random < Parameter.perRate1 && distance(person) < Parameter.perInfluence && this.getState() != State.OK) { this.beInfected(); } } } } } } }

PersonPool.java#

Copy
package rumour; import java.util.ArrayList; import java.util.List; import java.util.Random; public class PersonPool { private static PersonPool personPool = new PersonPool(); public static PersonPool getInstance() { return personPool; } List<Person> personList = new ArrayList<Person>(); public List<Person> getPersonList() { return personList; } // 得到各状态市民的数量 public int getPeopleSize(int state) { if (state == -1) { return personList.size(); } int i = 0; for (Person person : personList) { if (person.getState() == state) { i++; } } return i; } private PersonPool() { City city = new City(400, 400);// 设置城市中心为坐标 // 添加城市居民 Random random = new Random(); int x; int y; for (int i = 0; i < Parameter.MEDIA_PERSON_SIZE; i++) { // 产生N(a,b)的数:Math.sqrt(b)*random.nextGaussian()+a x = (int) (100 * random.nextGaussian() + city.getCenterX()); y = (int) (100 * random.nextGaussian() + city.getCenterY()); personList.add(new Person(city, x, y, 1)); } personList.add(new Person(city, city.getCenterX(), city.getCenterY(), 2)); for (int i = 0; i < Parameter.CITY_PERSON_SIZE; i++) { // 产生N(a,b)的数:Math.sqrt(b)*random.nextGaussian()+a x = (int) (100 * random.nextGaussian() + city.getCenterX()); y = (int) (100 * random.nextGaussian() + city.getCenterY()); if (x > 700) { x = 700; } personList.add(new Person(city, x, y, 0)); } } }

Point.java#

Copy
package rumour; public class Point { private int x; private int y; public Point(int x, int y) { this.x = x; this.y = y; } public int getX() { return x; } public void setX(int x) { this.x = x; } public int getY() { return y; } public void setY(int y) { this.y = y; } }

Parameter.java#

Copy
package rumour; //模拟参数 public class Parameter { public static int CITY_PERSON_SIZE = 10000;//城市总人口数量 public static int MEDIA_PERSON_SIZE = 5;//媒体数量 public static int Time = 5;//政府反应时间 public static int govInfluence = 50;//政府影响力 public static int mediaInfluence = 40;//社交媒体影响力 public static int perInfluence = 10;//普通人影响力 public static float govRate = 0.8f;//政府辟谣传播率 public static float mediaRate1 = 0.8f;//媒体谣言传播率 public static float mediaRate2 = 0.4f;//媒体辟谣传播率 public static float perRate2 = 0.4f;//普通人辟谣传播率 public static float perRate1 = 0.5f;//普通人谣言传播率 //城市大小即窗口边界,限制不允许出城 public static final int CITY_WIDTH = 1000; public static final int CITY_HEIGHT = 1000; }
posted @   启林O_o  阅读(348)  评论(0编辑  收藏  举报
编辑推荐:
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 一个奇形怪状的面试题:Bean中的CHM要不要加volatile?
· [.NET]调用本地 Deepseek 模型
· 一个费力不讨好的项目,让我损失了近一半的绩效!
阅读排行:
· PowerShell开发游戏 · 打蜜蜂
· 在鹅厂做java开发是什么体验
· 百万级群聊的设计实践
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战
· 永远不要相信用户的输入:从 SQL 注入攻防看输入验证的重要性
点击右上角即可分享
微信分享提示
CONTENTS