ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

谣言传播模拟

2020-07-15 12:02:15  阅读:365  来源: 互联网

标签:java int 谣言 传播 person static new public 模拟


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

main.java

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

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

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

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

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

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

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

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;
}

标签:java,int,谣言,传播,person,static,new,public,模拟
来源: https://www.cnblogs.com/Qi-Lin/p/13207338.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有