同期のモデリング


ホタルの同期モデルというモデルがある.

これはホタルの発光が自然と同期していく過程をモデリングしたものである.

今回はそのモデルを組んでみた.

コードは下記.

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation
from scipy.spatial.distance import cdist

# パラメータ設定
grid_size = 20  # グリッドのサイズ(20x20)
num_fireflies = grid_size * grid_size  # ホタルの総数
positions = np.array([(i, j) for i in range(grid_size) for j in range(grid_size)])  # ホタルの位置
phases = np.random.rand(num_fireflies)  # ホタルの初期位相(0から1の間のランダムな値)
T = 1.0  # サイクルタイム
dt = 0.01  # 時間の増分
num_steps = 500  # シミュレーションのステップ数
k = 0.05  # 位相調整の強さ
sync_number = 5  # 同期するホタルの数
sync_distance = 3  # 同期するホタルとの最大距離

# ホタル間の距離を計算
distances = cdist(positions, positions)

# 明るさの履歴と合計明るさを保存するリスト
brightness_history = []
total_brightness = []

# グラフの設定
fig, ax = plt.subplots(figsize=(6, 6))
cmap = plt.cm.get_cmap('hot')
brightness = 1 - phases  # 初期の明るさ
scatter = ax.scatter(positions[:, 0], positions[:, 1], c=brightness, cmap=cmap, s=20)
scatter.set_clim(0, 1)
ax.set_xlim(-1, grid_size)
ax.set_ylim(-1, grid_size)
ax.set_xticks([])
ax.set_yticks([])
ax.set_aspect('equal')
ax.set_title('ホタルの同期発光シミュレーション')

def update(frame):
    global phases
    # 位相を更新
    phases = (phases + dt / T) % 1.0

    # 位相のコピーを作成
    new_phases = np.copy(phases)

    # 各ホタルについて同期処理を実行
    for i in range(num_fireflies):
        # 同期距離内にいるホタルのインデックスを取得
        neighbor_indices = np.where((distances[i] > 0) & (distances[i] <= sync_distance))[0]
        if len(neighbor_indices) > 0:
            # 同期数だけランダムにホタルを選択
            num_neighbors = min(sync_number, len(neighbor_indices))
            selected_neighbors = np.random.choice(neighbor_indices, num_neighbors, replace=False)
            for j in selected_neighbors:
                # 位相差を計算
                phase_diff = (phases[j] - phases[i] + 0.5) % 1.0 - 0.5
                # 位相を調整
                new_phases[i] += k * phase_diff

    # 位相を更新
    phases = new_phases % 1.0

    # 明るさを計算
    brightness = np.sin(np.pi * (1 - phases)) ** 2  # 明るさは0から1の間

    brightness_history.append(brightness)
    total_brightness.append(np.sum(brightness))

    # 散布図を更新
    scatter.set_array(brightness)
    return scatter,

# アニメーションの作成
ani = FuncAnimation(fig, update, frames=num_steps, interval=50, blit=True)

# GIFファイルとして保存
ani.save('firefly_simulation.gif', writer='pillow')

参考文献

コメントを残す

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