有关生日悖论的词条
这是一个很有趣的一个问题,自己就用Kotlin模拟了一遍。
假设有10000000个班级,每个班级人数为23人:
package com.birthdayparadox
import java.util.*
class BirthdayParadox {
companion object {
private const val classNum = 10000000
private const val studentNum = 23
@JvmStatic
fun main(args: Array<String>) {
var equalTimes = 0
for (i in 0 until classNum) {
val randomArray =
createRandomArray(studentNum)
if (isSameElementInArray(randomArray)) {
equalTimes++
}
}
val percent = equalTimes * 1.0f / classNum * 100
println("学生人数为 $studentNum 的 $classNum 个班级中生日相同的概率为:$percent%")
}
private fun createRandomArray(size: Int): IntArray {
val ia = IntArray(size)
for (i in 0 until size) {
ia[i] = Random().nextInt(365)
}
return ia
}
private fun isSameElementInArray(array: IntArray): Boolean {
if (array.isEmpty()) {
return false
}
for (i in array) {
if (array.indexOf(i) != array.lastIndexOf(i)) {
return true
}
}
return false
}
}
}
输出结果显示生日相同的概率为:50.724857%,验证了生日悖论的说法。
关于这个问题,我们可以在深入一点。比如班级中3位同学生日相同的概率是多少?4位呢?5位又是多少呢?
假设有10000000个班级,每个班级人数为55人:
package com.birthdayparadox
import java.util.*
class BirthdayParadox2 {
companion object {
private const val classNum = 10000000
private const val studentNum = 55
@JvmStatic
fun main(args: Array<String>) {
val map = mutableMapOf<Int, Int?>()
for (i in 0 until classNum) {
val randomArray =
createRandomArray(studentNum)
val sameCountSet =
getSameElementCountInArrayToSet(randomArray)
for (j in sameCountSet) {
for (m in 2 until studentNum) {
if (j == m) {
map[m] = if (map[m] == null) 1 else map[m]!!.plus(1)
}
}
}
}
println("学生人数为 $studentNum 的 $classNum 个班级中")
for (entry in map) {
entry.value?.run {
val percent = entry.value!!.toFloat() / classNum * 100
println("有 ${entry.key} 人相同的生日概率是:$percent%")
}
}
}
private fun createRandomArray(size: Int): IntArray {
val intArray = IntArray(size)
for (i in 0 until size) {
intArray[i] = Random().nextInt(365)
}
return intArray
}
private fun getSameElementCountInArrayToSet(array: IntArray): Set<Int> {
val arrayToSet = array.toSet()
val frequencyList = mutableListOf<Int>()
for (i in arrayToSet) {
val frequency = Collections.frequency(array.toMutableList(), i)
frequencyList.add(frequency)
}
return frequencyList.toSet().filter { i -> i > 1 }.toSortedSet()
}
}
}
输出结果如下:
学生人数为 55 的 10000000 个班级中
有 2 人相同的生日概率是:98.19454%
有 3 人相同的生日概率是:15.88791%
有 4 人相同的生日概率是:0.60795003%
有 5 人相同的生日概率是:0.016490001%
有 6 人相同的生日概率是:4.3999997E-4%
有 7 人相同的生日概率是:2.0E-5%