38
21

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

「1000人を部屋に集めてお金をランダムな相手に渡し続ける」を色々条件を変えてやってみる

Posted at

はじめに

「100人を部屋に集めてお金をランダムな相手に渡し続ける」とだんだんと貧富の差が生まれる というGigazineの記事があります。

「そりゃあ、まあそうだろ」「おお、驚いた」と色々な感想があると思いますが、簡単な実験なので色々条件を変えてやってみると、意外と面白かったので紹介します。

「1000人を部屋に集めてお金をランダムな相手に渡し続ける」を色々条件を変えてやってみる

100人だと少ない気がしたので1000人でやってみます。

1000人が初期に金1000を持って、各ターンで無作為に誰かに金1を渡す場合

それぞれ、10, 100, 1000, 10000ターン目の所持金額とその人数のヒストグラムは以下のようになりました。

Kobito.0rXvUI.png

基本的に、1000を中心とした正規分布っぽい感じですね。試行を繰り返すと裾野が広がっていくのがわかります。

1000人が初期に金1000を持って、各ターンで無作為に渡すが 自分より金持ちに渡す時は10%の確率で再度誰に渡すか考え直す 場合

自分より金持ちに渡す場合に、10%の確率で渡す相手を再度決め直す場合です。

Kobito.621N5V.png

似たような分布ですが、先程より裾野が狭いです。富の再分配が行われているとでもいいましょうか。

1000人が初期に金1000を持って、各ターンで無作為に渡すが 自分より貧乏人に渡す時は10%の確率で再度誰に渡すか考え直す 場合

先程とは逆に、自分より貧乏人に渡す場合に、10%の確率で渡す相手を再度決め直す場合です。

Kobito.u3hiSE.png

今度は逆に裾野が大きく広がりました。格差社会ですw
貧乏人には仕事を依頼しない社会の縮図でしょうか。

1000人が 初期に金50 を持って、各ターンで無作為に誰かに金1を渡す場合

今度は一番最初のようにお金を渡す条件は特にはないですが、最初の所持金が50だった場合です。

Kobito.FFphBG.png

お金が0になる人が増え、お金を持たない人は誰にも渡さないので、かなり偏っていくようです。

スクリプト

今回使ったスクリプトです。Jupyter Notebookで実行できます。

import numpy as np
import seaborn as sns
import matplotlib.pyplot as plt

%matplotlib inline

N = 1000  # 人数
M = 1000  # 最初の所持金
P = 0     # 金持ち・貧乏に渡す時に再考する確率. しないなら0。10%なら0.1。
plot_index = [10, 100, 1000, 10000]  # グラフ表示を行うターン番号
T = max(plot_index)
plt.figure(figsize=(24, 6))


def transfer_money(moneys):
    transfer = np.zeros_like(moneys)
    for i in range(N):
        if moneys[i] > 0:
            while True:
                to_money = np.random.randint(0, N)
                # 金持ちには渡さない場合: `moneys[to_money] > moneys[i]`
                # 貧乏人には渡さない場合: `moneys[to_money] < moneys[i]`
                if moneys[to_money] < moneys[i] and np.random.random() < P:
                    continue
                break
            transfer[i] -= 1
            transfer[to_money] += 1
    moneys += transfer

moneys = np.ones((N, )) * M

for i in range(T+1):
    if i in plot_index:
        plt.subplot(1, len(plot_index), plot_index.index(i)+1)
        ax = sns.distplot(moneys, kde=False, bins=20)
        ax.set_title("i=%d" % i)
        ax.set_xlabel("money")
        ax.set_ylabel("person count")
    transfer_money(moneys)

plt.show()

さいごに

こういうのは楽しいですね。

38
21
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
38
21

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?