住み分けのシミュレーション


Schellingの分居モデルという有名なモデルがある.今回はそのモデルを簡易的にPython で組んでみた.

参考コードを提示する.

import numpy as np
import matplotlib.pyplot as plt
import imageio
import random

# パラメータ設定
grid_size = 20  # グリッドのサイズを大きく
empty_ratio = 0.1  # 空き地の割合
satisfaction_threshold = 0.4  # 満足水準を低めに
max_iterations = 200  # 最大反復回数

# グリッドの初期化
num_cells = grid_size * grid_size
num_empty = int(num_cells * empty_ratio)
num_agents = num_cells - num_empty

# 赤人と青人のエージェントを均等に配置
num_each_agent = num_agents // 2
agents = np.array([1] * num_each_agent + [2] * num_each_agent + [0] * num_empty)
np.random.shuffle(agents)
grid = agents.reshape((grid_size, grid_size))

def is_satisfied(x, y, grid, threshold):
    """エージェントが満足しているかどうかを判定する関数"""
    agent = grid[x, y]
    if agent == 0:  # 空き地の場合は無視
        return True
    # 周囲8マスの同色エージェントの割合を計算
    neighbors = []
    for i in range(max(0, x-1), min(grid_size, x+2)):
        for j in range(max(0, y-1), min(grid_size, y+2)):
            if (i, j) != (x, y):
                neighbors.append(grid[i, j])
    same_color = neighbors.count(agent)
    total_neighbors = len([n for n in neighbors if n != 0])
    if total_neighbors == 0:
        return True  # 周囲にエージェントがいない場合は満足とする
    return (same_color / total_neighbors) >= threshold

def find_empty_cell(grid):
    """空き地をランダムに探す関数"""
    empty_cells = list(zip(*np.where(grid == 0)))
    return random.choice(empty_cells)

# GIF用の画像リスト
images = []

# シミュレーションの実行
for iteration in range(max_iterations):
    moves = 0
    for x in range(grid_size):
        for y in range(grid_size):
            if not is_satisfied(x, y, grid, satisfaction_threshold):
                # エージェントが満足していない場合は移動する
                new_x, new_y = find_empty_cell(grid)
                grid[new_x, new_y], grid[x, y] = grid[x, y], 0
                moves += 1
    # 現在のグリッドをプロットして画像として保存
    fig, ax = plt.subplots()
    ax.imshow(grid, cmap='bwr', interpolation='nearest')
    ax.set_title(f'Segregation Model (Iteration {iteration + 1})')
    ax.axis('off')
    # 画像をバッファに保存してGIF用リストに追加
    fig.canvas.draw()
    image = np.frombuffer(fig.canvas.tostring_rgb(), dtype='uint8')
    image = image.reshape(fig.canvas.get_width_height()[::-1] + (3,))
    images.append(image)
    plt.close(fig)

    # 移動が発生しなかった場合はシミュレーションを終了
    if moves == 0:
        break

# GIFの保存
imageio.mimsave('segregation_model.gif', images, fps=5)
print("GIFファイルが 'segregation_model.gif' として保存されました。")

参考文献

  • 伊藤岳, & 山影進. (2016). 社会科学における実証的シミュレーション: シェリングの分居モデルの拡張と空間データとの接合例. 青山国際政経論集, (96), 101-124.

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です