Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

增加Kotlin版本项目,使代码更易阅读 #39

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
76 changes: 38 additions & 38 deletions src/MathUtil.java → VirusBroadcast_by_Java/src/MathUtil.java
Original file line number Diff line number Diff line change
@@ -1,38 +1,38 @@
import java.util.Random;
/**
* 数学算法工具类
*
* @ClassName: MathUtil
* @Description: 数学算法工具类
* @author: Bruce Young
* @date: 2020年02月06日 11:27
*/
public class MathUtil {
/**
* 仅仅使用一个随机数生成器
*/
private static final Random randomGen = new Random();
/**
* 标准正态分布化
* <p>
* 流动意愿标准化后判断是在0的左边还是右边从而决定是否流动。
* <p>
* 设X随机变量为服从正态分布,sigma是影响分布形态的系数 u值决定正态分布均值
* <p>
* <p>
* 推导:
* StdX = (X-u)/sigma
* X = sigma * StdX + u
*
* @param sigma 正态标准差sigma值
* @param u 正态均值参数mu
* @return
*/
public static double stdGaussian(double sigma, double u) {
double X = randomGen.nextGaussian();
return sigma * X + u;
}
}
import java.util.Random;

/**
* 数学算法工具类
*
* @ClassName: MathUtil
* @Description: 数学算法工具类
* @author: Bruce Young
* @date: 2020年02月06日 11:27
*/
public class MathUtil {
/**
* 仅仅使用一个随机数生成器
*/
private static final Random randomGen = new Random();

/**
* 标准正态分布化
* <p>
* 流动意愿标准化后判断是在0的左边还是右边从而决定是否流动。
* <p>
* 设X随机变量为服从正态分布,sigma是影响分布形态的系数 u值决定正态分布均值
* <p>
* <p>
* 推导:
* StdX = (X-u)/sigma
* X = sigma * StdX + u
*
* @param sigma 正态标准差sigma值
* @param u 正态均值参数mu
* @return
*/
public static double stdGaussian(double sigma, double u) {
double X = randomGen.nextGaussian();
return sigma * X + u;
}

}
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
12 changes: 12 additions & 0 deletions VirusBroadcast_by_Kotlin/.idea/VirusBroadcast_by_Kotlin.iml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 10 additions & 0 deletions VirusBroadcast_by_Kotlin/.idea/kotlinc.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

19 changes: 19 additions & 0 deletions VirusBroadcast_by_Kotlin/.idea/libraries/KotlinJavaRuntime.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions VirusBroadcast_by_Kotlin/.idea/misc.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 7 additions & 0 deletions VirusBroadcast_by_Kotlin/.idea/modules.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion .idea/vcs.xml → VirusBroadcast_by_Kotlin/.idea/vcs.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 12 additions & 0 deletions VirusBroadcast_by_Kotlin/VirusBroadcast_by_Kotlin.iml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" name="KotlinJavaRuntime" level="project" />
</component>
</module>
30 changes: 30 additions & 0 deletions VirusBroadcast_by_Kotlin/src/Constants.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/**
* @ClassName: Constants
* @Description: 模拟参数
* @Author: cnctemaR
* @Date: 2020/2/7 0:40
* */
object Constants {
const val ORIGINAL_COUNT = 50//初始感染数量
const val BROAD_RATE = 0.8//传播率
const val SHADOW_TIME = 140.0//潜伏时间,14天为140
const val HOSPITAL_RECEIVE_TIME = 10//医院收治响应时间
const val BED_COUNT = 1000//医院床位
/**
* 流动意向平均值,建议调整范围:[-0.99,0.99]
*
*
* -0.99 人群流动最慢速率,甚至完全控制疫情传播
* 0.99为人群流动最快速率, 可导致全城感染
*/
const val u = 0.99
const val CITY_PERSON_SIZE = 5000//城市总人口数量
const val FATALITY_RATE = 0.50//fatality_rate病死率,根据2月6日数据估算(病死数/确诊数)为0.02
const val DIE_TIME = 100//死亡时间均值,30天,从发病(确诊)时开始计时
const val DIE_VARIANCE = 1.0//死亡时间方差
/**
* 城市大小即窗口边界,限制不允许出城
*/
const val CITY_WIDTH = 700
const val CITY_HEIGHT = 800
}
139 changes: 139 additions & 0 deletions VirusBroadcast_by_Kotlin/src/EntityClass.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
import java.util.*
import java.util.ArrayList


/**
* @ClassName:
* @Description:
* @Author: cnctemaR
* @Date: 2020/2/7 0:12
* */
open class Point(open var x: Int, open var y: Int) {
fun moveTo(x: Int, y: Int) {
this.x += x
this.y += y
}
}

/**
* @ClassName:
* @Description:
* @Author: cnctemaR
* @Date: 2020/2/7 0:12
* */
class Bed(x: Int, y: Int) : Point(x, y) {
var isEmpty = true
}

/**
* @ClassName:
* @Description:
* @Author: cnctemaR
* @Date: 2020/2/7 0:12
* */
class MoveTarget(var x: Int, var y: Int) {
var arrived: Boolean = false //是否到达目标点
}

/**
* @ClassName:
* @Description:
* @Author: cnctemaR
* @Date: 2020/2/7 0:12
* */
class City(var centerX: Int, var cneterY: Int)

/**
* @ClassName:
* @Description:
* @Author: cnctemaR
* @Date: 2020/2/7 0:12
* */
class Hospital private constructor(x: Int, y: Int) : Point(x, y) {
companion object {
const val HOSPITAL_X = 720
const val HOSPITAL_Y = 80
val hospital = Hospital(HOSPITAL_X,HOSPITAL_Y)
}

var width = 0
private set
var height = 600
private set
val point = Point(HOSPITAL_X, HOSPITAL_Y) //第一个床位所在坐标,用于给其他床位定绝对坐标
val beds = ArrayList<Bed>()

//初始化构造
init {
//医院矩形所在坐标
this.x = HOSPITAL_X
this.y = HOSPITAL_Y + 10
//根据床位数量调整医院矩形的大小
if (Constants.BED_COUNT == 0) {
width = 0
height = 0
}
//根据医院床位数量计算医院宽度
//因为高度定了只能装载100个床位
val column = Constants.BED_COUNT / 100
width = column * 6
//根据第一个床位坐标初始化其他床位的坐标
for (i in 0 until column)
for (j in 10..606 step 6) {
val bed = Bed(point.x + i * 6, point.y + j)
beds.add(bed)
if (beds.size >= Constants.BED_COUNT) //确定医院床位承载数量
break
}
}

fun pickBed(): Bed? {
return beds.find { it.isEmpty }
}

//死亡或痊愈出院空出床位
fun returnBed(bed: Bed?): Bed? {
if (bed != null)
bed.isEmpty = true
return bed
}
}

/**
* @ClassName:
* @Description:
* @Author: cnctemaR
* @Date: 2020/2/7 0:12
* */
class PersonPool private constructor() {
var personList: MutableList<Person> = ArrayList()
private set

init {
val city = City(400, 400) //设置城市中心为坐标(400,400)
for (i in 0 until Constants.CITY_PERSON_SIZE) {
val random = Random()
var x = (100 * random.nextGaussian() + city.centerX).toInt()
val y = (100 * random.nextGaussian() + city.cneterY).toInt()
if (x > 700)
x = 700

personList.add(Person(city, x, y))
}
}

companion object {
val personPool = PersonPool()
}

/**
* @param state 市民类型 Person.State的值,若为-1则返回当前总数目
* @return 获取指定人群数量
*/
fun getPeopleSize(state: Int): Int {
if (state == -1)
return personList.size
return personList.count {it.state == state}
}

}
56 changes: 56 additions & 0 deletions VirusBroadcast_by_Kotlin/src/Main.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import javax.swing.JFrame
import java.util.Random



/**
* @ClassName:
* @Description:
* @Author: cnctemaR
* @Date: 2020/2/7 0:12
* */
private var hospitalWidth: Int = 0

fun main(args: Array<String>) {
initHospital()
initPanel()
initInfected()
}

/**
* 初始化画布
*/
fun initPanel(){
val p = MyPanel()
val panelThread = Thread(p)
val frame = JFrame()
frame.add(p)
frame.setSize(Constants.CITY_WIDTH + hospitalWidth + 300, Constants.CITY_HEIGHT)
frame.setLocationRelativeTo(null)
frame.isVisible = true
frame.title = "瘟疫传播模拟"
frame.defaultCloseOperation = JFrame.EXIT_ON_CLOSE
panelThread.start()//开启画布线程,即世界线程,接着看代码的下一站可以转MyPanel.java

}

/**
* 初始化医院参数
*/
private fun initHospital() {
hospitalWidth = Hospital.hospital.width
}

/**
* 初始化初始感染者
*/
private fun initInfected(){
val people = PersonPool.personPool.personList //获取所有的市民
for (i in 0 until Constants.ORIGINAL_COUNT) {
var person: Person
do {
person = people[Random().nextInt(people.size - 1)]//随机挑选一个市民
} while (person.isInfected())//如果该市民已经被感染,重新挑选
person.beInfected()//让这个幸运的市民成为感 染者
}
}
Loading