算法002_财富分布基尼系数

算法

public class 算法002_财富分布基尼系数 {
    /**
     * 一开始有100个人,每个人都有100元
     * 在每一轮都做如下的事情 :
     * 每个人都必须拿出1元钱给除自己以外的其他人,给谁完全随机
     * 如果某个人在这一轮的钱数为0,那么他可以不给,但是可以接收
     * 发生很多很多轮之后,这100人的社会财富分布很均匀吗?
     */
    @Test
    public void test() {
        System.out.println("一个社会的基尼系数是一个在0~1之间的小数");
        System.out.println("基尼系数为0代表所有人的财富完全一样");
        System.out.println("基尼系数为1代表有1个人掌握了全社会的财富");
        System.out.println("基尼系数越小,代表社会财富分布越均衡;越大则代表财富分布越不均衡");
        System.out.println("在2022年,世界各国的平均基尼系数为0.44");
        System.out.println("目前普遍认为,当基尼系数到达 0.5 时");
        System.out.println("就意味着社会贫富差距非常大,分布非常不均匀");
        System.out.println("社会可能会因此陷入危机,比如大量的犯罪或者经历社会动荡");
        System.out.println("测试开始");
        // 人数
        int persons = 100;
        // 轮转次数
        int lunZhuanCounts = 10000;
        System.out.println(calculateMoney(persons, lunZhuanCounts));
    }

    // 发钱
    public double calculateMoney(int persons, int lunZhuanCounts) {
        // 一人100块
        int[] money = new int[persons];
        Arrays.fill(money, 100);
        // 存储每个人是否还有钱发
        boolean[] hasMoney = new boolean[persons];
        // 轮转次数
        for (int i = 0; i < lunZhuanCounts; i++) {
            // 默认每个人没钱,有钱的人设置为false。这里也可以默认有钱,没钱的人设置为true。
            Arrays.fill(hasMoney, true);
            for (int j = 0; j < money.length; j++) {
                if (money[j] > 0) {
                    hasMoney[j] = true;
                }
            }

            for (int j = 0; j < persons; j++) {
                // 计算j给谁发钱
                int other = j;
                do {
                    // (int) (Math.random() * n);
                    // int : 0 ~ n-1,等概率随机
                    other = (int) (Math.random() * persons);
                } while (other == j);
                // 发钱
                if (hasMoney[j] == true) {
                    money[j]--;
                    money[other]++;
                }
            }

        }

        return calculateGiNi(money);
    }

    public double calculateGiNi(int[] money) {
        double moneySum = 0;
        double moneyJueDuiZhiCha = 0;
        for (int i = 0; i < money.length; i++) {
            moneySum += money[i];
            for (int j = 0; j < money.length; j++) {
                moneyJueDuiZhiCha += Math.abs(money[i] - money[j]);
            }
        }
        return moneyJueDuiZhiCha / (2 * money.length * moneySum);
    }
}

测试

测试开始
0.567438

Process finished with exit code 0
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值