【算法】002、编程实现社会问题
【算法】002、编程实现社会问题
文章目录
- 一、模拟
- 1.1 模拟
- 二、多语言解法
// 一开始有100个人,每个人都有100元
// 在每一轮都做如下的事情 :
// 每个人都必须拿出1元钱给除自己以外的其他人,给谁完全随机
// 如果某个人在这一轮的钱数为0,那么他可以不给,但是可以接收
// 发生很多很多轮之后,这100人的社会财富分布很均匀吗?
一、模拟
初看题目, 觉得很公平, 但程序员是手艺人, 尽量建模并用代码模拟一遍, 看看实际效果
思路:
初始: 模拟100个人, 每个人有100元
操作 t 轮, 每轮 每个人 只要有钱就要给 别人 1元. 若某人已没钱了则不用给但是可以接收.
求: t 轮之后, 100人的财富分布.
可以让 t = 1, 10, 100, 1000 分别看看效果, 看看是否公平.
1.1 模拟
// go
package main
import (
"fmt"
"math"
"math/rand"
"slices"
)
func main() {
times := 1
const PersonCnt = 100
const InitMoney = 100
persons := make([]int, PersonCnt) // 下标: 第几个人, 值: 该人有的钱数
for i := range persons {
persons[i] = InitMoney
}
// t := 0
for range times { // 每轮
// fmt.Printf("开始第%v轮\n", t)
// t++
for i, money := range persons { // 每个人
if money == 0 {
continue // 若该人已没钱了, 则不用给别人了
}
other := i
for other == i { // other 是其他人, 初值为 i. 循环直到 不为i 为止
other = rand.Intn(PersonCnt)
}
// oldi, oldOther := persons[i], persons[other]
persons[i]--
persons[other]++
// fmt.Printf("%v(%v) 给 %v(%v) => (%v) (%v)\n", i, oldi, other, oldOther, persons[i], persons[other])
}
}
fmt.Println(slices.Sorted(slices.Values(persons)))
fmt.Printf("%v轮, 基尼系数%v\n", times, geni(persons))
}
func geni(wealth []int) float64 {
diffs := 0.0
sum := 0
n := len(wealth)
for i := range n {
sum += wealth[i]
for j := range n {
diffs += math.Abs(float64(wealth[i] - wealth[j]))
}
}
return diffs / float64(2*n*sum)
}
每轮明细:
开始第0轮
0(100) 给 64(100) => (99) (101)
1(100) 给 57(100) => (99) (101)
2(100) 给 20(100) => (99) (101)
3(100) 给 29(100) => (99) (101)
4(100) 给 31(100) => (99) (101)
...
95(102) 给 11(99) => (101) (100)
96(101) 给 18(99) => (100) (100)
97(102) 给 58(99) => (101) (100)
98(102) 给 8(100) => (101) (101)
99(101) 给 60(101) => (100) (102)
一轮之后
[99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 101 101 101 101 101 101 101 101 101 101 101 101 102 102 102 102 102 102 102 103 103 105]
1轮, 基尼系数0.005436
十轮之后
[92 94 94 94 95 96 96 96 96 97 97 97 97 97 97 97 97 97 97 97 97 97 97 98 98 98 98 98 98 98 98 98 98 98 98 99 99 99 99 99 99 99 99 99 99 100 100 100 100 100 100 100 100 100 100 100 100 100 101 101 101 101 101 101 101 101 101 101 101 102 102 102 102 102 102 102 102 102 102 102 102 103 103 103 103 103 103 104 104 104 104 104 105 106 106 106 106 107 107 107]
10轮, 基尼系数0.01732
百轮之后
[79 81 81 83 85 87 88 88 89 89 89 90 90 90 91 91 92 92 92 93 93 93 93 93 94 94 94 94 95 95 95 95 95 96 96 96 96 96 96 96 97 97 97 97 97 98 98 98 98 99 99 99 99 99 100 100 100 100 100 100 100 100 101 101 101 102 103 103 104 104 104 104 105 105 105 105 105 106 106 106 106 107 108 108 108 109 109 111 113 115 115 117 117 118 118 123 124 124 125 128]
100轮, 基尼系数0.053774
千轮之后
[26 30 35 36 39 43 48 49 52 53 57 58 59 61 62 65 65 67 70 72 72 73 73 73 75 76 77 79 81 82 82 84 86 87 88 89 89 90 92 92 93 93 96 97 98 98 99 100 100 100 100 101 101 102 103 104 104 106 106 109 109 111 113 113 114 114 114 115 117 118 118 119 119 121 121 122 123 126 128 128 129 129 130 131 133 133 133 136 143 144 146 146 153 159 160 165 165 166 167 172]
1000轮, 基尼系数0.190358
万轮之后
[0 2 2 4 4 8 9 11 11 14 14 17 17 22 28 29 31 31 33 34 35 37 38 38 40 40 40 45 45 46 46 48 49 51 52 53 54 56 56 56 59 60 66 69 70 71 75 77 84 87 89 96 96 97 97 98 99 102 104 104 104 105 107 112 116 118 118 119 122 123 125 128 132 143 147 148 149 152 157 163 164 174 176 180 183 185 190 200 206 207 209 214 214 219 233 255 262 304 334 357]
10000轮, 基尼系数0.420522
百万轮之后
[3 4 4 5 6 9 10 11 11 11 14 14 14 15 15 16 16 19 20 20 21 21 22 24 24 25 26 26 26 26 27 30 30 31 32 34 35 36 36 36 38 38 38 39 40 40 45 47 50 51 59 59 61 62 67 70 71 77 80 82 84 96 98 98 100 104 107 107 108 111 121 122 134 138 151 162 162 167 171 173 175 180 190 193 208 212 222 223 237 245 255 289 296 296 297 305 368 380 461 535]
1000000轮, 基尼系数0.535876
因此, 通过实际编码可知, 随着轮数变多, 财富分布会越来越不均衡. 逐渐超过 0.5 的阈值
二、多语言解法
C p p / G o / P y t h o n / R u s t / J s / T s Cpp/Go/Python/Rust/Js/Ts Cpp/Go/Python/Rust/Js/Ts
// cpp
// go 同上
# python
// rust
// js
// ts