在这里插入图片描述

生命游戏 - 社会经济学复杂性实验室

项目概述

这是一个基于 康威生命游戏 的多学科复杂系统分析平台,将经典的细胞自动机模型应用于社会经济学、心理学和复杂系统理论的研究与可视化。


一、核心技术架构

1. 康威生命游戏规则

- 任何活细胞如果邻居少于2个,则死亡(孤独)
- 任何活细胞如果邻居多于3个,则死亡(拥挤)
- 任何死细胞如果恰好有3个活邻居,则复活(繁殖)
- 任何活细胞如果有2或3个活邻居,则存活

2. 技术栈

  • Streamlit: Web应用框架
  • NumPy: 高效数值计算
  • Matplotlib: 网格可视化
  • Plotly: 交互式图表
  • SciPy: 科学计算(信号处理、统计分析)
  • Pandas: 数据管理

3. 性能优化

  • 900x900 大规模网格(810,000个细胞)
  • 优化的基尼系数计算(O(n log n)而非O(n²))
  • 双端队列历史记录(限制内存使用)
  • 中文字体渲染优化

二、多维度分析体系

演化趋势分析(6个核心指标)

指标 计算方法 物理意义
细胞总数 活细胞计数 种群规模
稳定性 1 - |变化量|/当前值 系统动态平衡
复杂度 邻居数标准差/均值 结构复杂程度
不平等度 优化后的基尼系数 资源分配公平性
效率 适居细胞/总细胞 资源利用率
多样性 唯一3x3模式/总模式 行为丰富度

经济学分析(5个维度)

1. GDP(经济规模)
GDP = 活细胞数 × 100
  • 代表系统总体经济产出
  • 实时跟踪经济规模变化
2. 增长率
增长率 = (当前GDP - 前期GDP) / 前期GDP × 100%
  • 正增长:经济扩张期
  • 负增长:经济衰退期
  • 高波动:经济不稳定
3. 波动性
波动性 =10期GDP标准差 / 平均GDP
  • 衡量经济风险
  • 低波动性:经济稳定
  • 高波动性:经济脆弱
4. 经济周期
  • 扩张期:连续5期正增长
  • 衰退期:连续5期负增长
  • 波动期:单期变化>5%
5. 不平等程度
  • 使用优化基尼系数
  • 范围:0(完全平等)到1(完全不平等)

社会学分析(6个指标)

1. 社区结构
  • 检测方法:广度优先搜索(BFS)寻找连通区域
  • 社区定义:相互连接的活细胞集合
  • 社区大小:每个社区中的细胞数量
2. 社会凝聚力
凝聚力 = 平均社区规模 / 网格总细胞 × 100%
  • 高凝聚力:社区紧密、团结
  • 低凝聚力:社区分散、孤立
3. 社会稳定性
  • 基于系统稳定性指标
  • 反映社会结构的持久性
4. 社会流动性
流动性 = \|当前社区数 - 前期社区数\| / 前期社区数
  • 高流动性:社会结构变化快(机会多)
  • 低流动性:社会结构固化(阶层固化)
5. 多样性
  • 基于模式多样性指标
  • 反映社会行为的丰富程度
6. 社会网络可视化
  • 环形拓扑结构
  • 节点大小:代表社区规模
  • 边:基于距离和概率的连接

心理学分析(5个维度)

1. 群体压力水平
个体压力 = \|邻居数 - 2.5\| / 3.5
  • 最优邻居数:2-3(压力最低)
  • 极端邻居数:0或8(压力最高)
  • 压力范围:[0, 1]
2. 从众倾向
从众比例 = 邻居≥4的细胞数 / 总细胞数
  • 高从众:社会规范强、创新少
  • 低从众:个人主义强、创新多
3. 创新倾向
创新比例 = 邻居≤1的细胞数 / 总细胞数
  • 适合创新的条件:孤立或仅有少量邻居
  • 创新者特点:打破常规
4. 集体情绪
集体情绪 = 1 - 平均压力水平
  • 积极(>0.7):社会氛围好
  • 中性(0.3-0.7):正常状态
  • 消极(<0.3):社会焦虑
5. 社会影响力
影响力 = 压力水平与邻居数的相关系数
  • 正相关:压力大时行为趋同
  • 负相关:压力大时行为分散
6. 心理状态热图
  • 颜色映射:红色(高压力)→蓝色(低压力)
  • 空间分布:可视化压力热点区域

复杂系统分析(6个核心指标)

1. 分形维度
分形维度 = 盒子计数法拟合斜率
  • 方法:不同尺度下的盒子数量对数-对数尺度图
  • 解释
    • 1.5-2.0:高复杂度(类似自然界)
    • 1.0-1.5:中等复杂度
    • <1.0:低复杂度(规则模式)
2. 系统熵
= -Σ pᵢ × log₂(pᵢ)
  • 物理意义:系统无序程度
  • 3x3模式分析
    • 高熵:系统随机、不可预测
    • 低熵:系统有序、可预测
    • 最大熵:每个模式唯一
3. 自组织临界性
  • 检测方法:雪崩大小分布的幂律拟合
  • 幂律指数
    • 2.0-3.0:临界状态(最优化)
    • 1.5-2.0或3.0-3.5:近临界
    • 其他:远离临界
  • 物理意义:系统在临界点最具适应性
4. 涌现性
涌现性 = 全局复杂度 - 局部复杂度平均值
  • 强涌现(>0.1):整体大于部分之和
  • 弱涌现(0.05-0.1):有一定整体性
  • 无涌现(<0.05):还原论式
5. 适应性
适应性 = 稳定性 × 效率
  • 高适应性:系统既能保持稳定又高效
  • 反映系统的生存能力
6. 韧性
韧性 = 恢复增长期数 /10
  • 高韧性:系统受损后快速恢复
  • 低韧性:系统脆弱
7. 相空间分析
  • 延迟嵌入法:重建系统动力学的相空间
  • 应用:检测吸引子、周期性、混沌特征
  • τ参数:时间延迟(默认5)
8. 系统状态雷达图
  • 六维评估:分形、熵、临界性、涌现性、适应性、韧性
  • 归一化:每维度映射到[0, 1]范围

三、用户交互功能

控制面板

  1. 播放/暂停:控制模拟进程
  2. 重置:重新初始化网格
  3. 初始模式
    • 随机分布:30%密度均匀分布
    • 中心聚集:高密度中心区域
    • 滑翔机群:8个独立滑翔机
    • 多集群:5个随机分布的集群
  4. 初始密度:0.1-0.8可调
  5. 模拟速度:0.01-1.0秒/代

数据管理

  1. 导出CSV:一键导出所有历史数据
  2. 实时统计:代数、活细胞数、密度、稳定性、效率

可视化标签页

  1. 演化趋势:6指标时间序列图 + 统计卡片
  2. 经济学分析:GDP/增长率/波动性/不平等 + 周期分布饼图
  3. 社会学视角:社区结构/稳定性/流动性 + 规模分布直方图 + 网络图
  4. 心理学指标:压力/从众/创新/情绪/影响力 + 热图 + 直方图
  5. 复杂系统:分形/熵/临界性/涌现/适应性/韧性 + 相空间图 + 雷达图

四、创新点

1. 跨学科整合

  • 细胞自动机经济学:GDP、增长率、波动性
  • 细胞自动机社会学:社区、流动性、网络
  • 细胞自动机心理学:压力、情绪、从众
  • 细胞自动机复杂系统:熵、分形、涌现

2. 大规模计算优化

  • 内存优化:避免O(n²)外积,改用O(n log n)排序
  • 时间优化:高效邻居计算、批量处理
  • 存储优化:双端队列限制历史长度

3. 交互式可视化

  • 实时更新:自动rerun机制
  • 动态图表:Plotly交互式图表
  • 多维度:5个独立标签页,28+图表

4. 数据导出

  • 完整数据:所有指标的历史记录
  • 格式标准:CSV格式,便于后续分析
  • 时间戳:包含精确的数据更新时间

五、应用场景

学术研究

  1. 复杂系统理论:验证涌现性、自组织临界性
  2. 经济学建模:GDP波动、基尼系数、经济周期
  3. 社会网络分析:社区检测、流动性测量
  4. 计算心理学:群体行为、从众与创新

教育

  1. 复杂系统教学:直观展示涌现现象
  2. 跨学科教学:连接数学、物理、社会学
  3. 数据可视化教学:多维图表解读技巧

决策支持

  1. 政策模拟:测试不同初始条件下的演化
  2. 风险评估:通过不平等、波动性指标
  3. 资源配置:通过效率、稳定性指标优化

六、技术亮点

性能指标

  • 网格规模:900×900(810,000细胞)
  • 实时更新:<1秒/代(可调)
  • 历史容量:500代演化数据
  • 图表刷新:每代自动更新

代码质量

  • 模块化设计: GameState类封装状态和计算
  • 分离关注点:每个指标独立计算方法
  • 错误处理:空值、除零、边界条件
  • 可扩展性:易于添加新指标或维度

可访问性

  • 中文支持:完整的中文字体渲染
  • 响应式布局:宽屏适配
  • 无表情符号:纯文本界面,兼容性强

七、未来扩展方向

  1. 添加更多经济学模型:IS-LM、菲利普斯曲线
  2. 增强社会网络:真实图算法(PageRank、社群发现)
  3. 机器学习集成:预测演化趋势、异常检测
  4. 并行计算:GPU加速大规模网格
  5. 实时协作:多用户共享、竞争模式

代码

# -*- coding: utf-8 -*-
import streamlit as st
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import plotly.graph_objects as go
import plotly.express as px
from plotly.subplots import make_subplots
import time
import random
from collections import deque
import json
from datetime import datetime
import base64
from io import BytesIO
import scipy.signal
import scipy.stats
import warnings
warnings.filterwarnings('ignore')

# 设置中文字体
plt.rcParams['font.sans-serif'] = ['Microsoft YaHei', 'SimHei', 'Arial Unicode MS']
plt.rcParams['axes.unicode_minus'] = False  # 解决负号显示问题

# 页面配置
st.set_page_config(
    page_title="社会经济学复杂性推演计算仿真",
    page_icon="略",
    layout="wide",
    initial_sidebar_state="expanded"
)

# 自定义CSS样式
st.markdown("""
<style>
    .main-header {
        font-size: 2.5rem;
        color: #4CAF50;
        text-align: center;
        margin-bottom: 1rem;
    }
    .sub-header {
        font-size: 1.5rem;
        color: #2196F3;
        margin-top: 1.5rem;
        margin-bottom: 0.5rem;
    }
    .metric-card {
        background-color: #1E1E1E;
        border-radius: 10px;
        padding: 15px;
        margin: 10px 0;
        border-left: 5px solid #4CAF50;
    }
    .stButton button {
        width: 100%;
        background-color: #4CAF50;
        color: white;
    }
    .stButton button:hover {
        background-color: #45a049;
    }
    .chart-container {
        border: 1px solid #ddd;
        border-radius: 10px;
        padding: 15px;
        margin: 10px 0;
        background-color: white;
    }
</style>
""", unsafe_allow_html=True)

# 游戏状态类
class GameState:
    def __init__(self, rows=60, cols=60):
        self.rows = rows
        self.cols = cols
        self.grid = np.zeros((rows, cols), dtype=int)
        self.generation = 0
        self.paused = True
        self.speed = 0.1
        self.history = deque(maxlen=200)
        self.metrics_history = deque(maxlen=500)
        self.economic_history = deque(maxlen=200)
        self.sociology_history = deque(maxlen=200)
        self.psychology_history = deque(maxlen=200)
        self.system_history = deque(maxlen=200)
        self.initialize_grid()
        
    def initialize_grid(self, pattern="random", density=0.3):
        """初始化网格"""
        if pattern == "random":
            self.grid = np.random.choice([0, 1], size=(self.rows, self.cols), p=[1-density, density])
        elif pattern == "center":
            center_x, center_y = self.rows // 2, self.cols // 2
            radius = min(self.rows, self.cols) // 4
            for i in range(max(0, center_x-radius), min(self.rows, center_x+radius)):
                for j in range(max(0, center_y-radius), min(self.cols, center_y+radius)):
                    if np.random.random() < 0.6:
                        self.grid[i, j] = 1
        elif pattern == "gliders":
            self.grid = np.zeros((self.rows, self.cols), dtype=int)
            # 添加多个滑翔机
            for _ in range(8):
                x, y = random.randint(0, self.rows-4), random.randint(0, self.cols-4)
                glider = np.array([[0, 1, 0], [0, 0, 1], [1, 1, 1]])
                for i in range(3):
                    for j in range(3):
                        self.grid[x+i, y+j] = glider[i, j]
        elif pattern == "clusters":
            self.grid = np.zeros((self.rows, self.cols), dtype=int)
            # 创建多个集群
            for _ in range(5):
                cx, cy = random.randint(10, self.rows-10), random.randint(10, self.cols-10)
                for i in range(-4, 5):
                    for j in range(-4, 5):
                        if 0 <= cx+i < self.rows and 0 <= cy+j < self.cols:
                            if np.random.random() < 0.5:
                                self.grid[cx+i, cy+j] = 1
        self.generation = 0
        self.clear_history()
        
    def clear_history(self):
        """清空历史记录"""
        self.history.clear()
        self.metrics_history.clear()
        self.economic_history.clear()
        self.sociology_history.clear()
        self.psychology_history.clear()
        self.system_history.clear()
    
    def get_neighbors(self, x, y):
        """计算邻居数量"""
        total = 0
        for i in range(-1, 2):
            for j in range(-1, 2):
                if i == 0 and j == 0:
                    continue
                nx, ny = (x + i) % self.rows, (y + j) % self.cols
                total += self.grid[nx, ny]
        return total
    
    def update(self):
        """更新一代"""
        if not self.paused:
            new_grid = np.copy(self.grid)
            for i in range(self.rows):
                for j in range(self.cols):
                    neighbors = self.get_neighbors(i, j)
                    if self.grid[i, j] == 1:
                        if neighbors < 2 or neighbors > 3:
                            new_grid[i, j] = 0
                    else:
                        if neighbors == 3:
                            new_grid[i, j] = 1
            self.grid = new_grid
            self.generation += 1
            self.record_all_metrics()
    
    def record_all_metrics(self):
        """记录所有维度的指标"""
        # 基础指标
        total_cells = np.sum(self.grid)
        density = total_cells / (self.rows * self.cols)
        
        # 演化趋势指标
        evolution_metrics = {
            'generation': self.generation,
            'total_cells': total_cells,
            'density': density,
            'stability': self.calculate_stability(),
            'complexity': self.calculate_complexity(),
            'inequality': self.calculate_inequality(),
            'efficiency': self.calculate_efficiency(),
            'diversity': self.calculate_diversity()
        }
        self.metrics_history.append(evolution_metrics)
        
        # 经济学指标
        economic_metrics = self.calculate_economic_metrics()
        self.economic_history.append(economic_metrics)
        
        # 社会学指标
        sociology_metrics = self.calculate_sociology_metrics()
        self.sociology_history.append(sociology_metrics)
        
        # 心理学指标
        psychology_metrics = self.calculate_psychology_metrics()
        self.psychology_history.append(psychology_metrics)
        
        # 复杂系统指标
        system_metrics = self.calculate_system_metrics()
        self.system_history.append(system_metrics)
        
    def calculate_stability(self):
        """计算稳定性指标"""
        if len(self.metrics_history) < 2:
            return 0
        return 1 - abs(self.metrics_history[-1]['total_cells'] - 
                      self.metrics_history[-2]['total_cells']) / max(self.metrics_history[-1]['total_cells'], 1)
    
    def calculate_complexity(self):
        """计算系统复杂度"""
        neighbor_counts = []
        for i in range(self.rows):
            for j in range(self.cols):
                if self.grid[i, j] == 1:
                    neighbor_counts.append(self.get_neighbors(i, j))
        
        if len(neighbor_counts) == 0:
            return 0
        return np.std(neighbor_counts) / max(np.mean(neighbor_counts), 1)
    
    def calculate_inequality(self):
        """计算资源分配不均(基尼系数近似)"""
        if np.sum(self.grid) == 0:
            return 0

        neighbor_counts = []
        for i in range(self.rows):
            for j in range(self.cols):
                if self.grid[i, j] == 1:
                    neighbor_counts.append(self.get_neighbors(i, j))

        if not neighbor_counts:
            return 0

        counts = np.array(neighbor_counts)
        n = len(counts)

        # 优化计算:使用更高效的方式计算基尼系数
        # 使用排序方法而不是外积,避免内存爆炸
        sorted_counts = np.sort(counts)
        n_float = float(n)
        cumsum = np.cumsum(sorted_counts, dtype=float)
        mean_val = mean_abs_diff = np.mean(counts)

        if mean_val == 0:
            return 0

        # 基尼系数的优化计算公式
        gini = (2 * np.sum(np.arange(1, n + 1) * sorted_counts)) / (n * cumsum[-1]) - (n + 1) / n

        # 确保结果在[0, 1]范围内
        return max(0, min(1, gini))
    
    def calculate_efficiency(self):
        """计算系统效率"""
        total_cells = np.sum(self.grid)
        if total_cells == 0:
            return 0
            
        optimal_cells = 0
        for i in range(self.rows):
            for j in range(self.cols):
                if self.grid[i, j] == 1:
                    neighbors = self.get_neighbors(i, j)
                    if 2 <= neighbors <= 3:
                        optimal_cells += 1
        
        return optimal_cells / total_cells
    
    def calculate_diversity(self):
        """计算多样性指标"""
        patterns = []
        for i in range(self.rows-2):
            for j in range(self.cols-2):
                pattern = self.grid[i:i+3, j:j+3]
                patterns.append(pattern.tobytes())
        
        unique_patterns = len(set(patterns))
        total_patterns = len(patterns)
        
        return unique_patterns / max(total_patterns, 1)
    
    def calculate_economic_metrics(self):
        """计算经济学指标"""
        total_cells = np.sum(self.grid)
        
        # 模拟GDP
        gdp = total_cells * 100
        
        # 计算增长率
        growth_rate = 0
        if len(self.economic_history) > 0:
            prev_gdp = self.economic_history[-1].get('gdp', gdp)
            growth_rate = (gdp - prev_gdp) / max(prev_gdp, 1) * 100
        
        # 计算经济波动
        volatility = 0
        if len(self.economic_history) > 10:
            recent_gdp = [m.get('gdp', 0) for m in list(self.economic_history)[-10:]]
            volatility = np.std(recent_gdp) / max(np.mean(recent_gdp), 1)
        
        # 计算经济周期
        economic_cycle = "平稳"
        if len(self.economic_history) > 5:
            recent_growth = [m.get('growth_rate', 0) for m in list(self.economic_history)[-5:]]
            if all(g > 0 for g in recent_growth):
                economic_cycle = "扩张"
            elif all(g < 0 for g in recent_growth):
                economic_cycle = "衰退"
            elif any(abs(g) > 5 for g in recent_growth):
                economic_cycle = "波动"
        
        return {
            'gdp': gdp,
            'growth_rate': growth_rate,
            'volatility': volatility,
            'economic_cycle': economic_cycle,
            'inequality': self.calculate_inequality(),
            'efficiency': self.calculate_efficiency()
        }
    
    def calculate_sociology_metrics(self):
        """计算社会学指标"""
        # 计算社区结构
        communities = self.detect_communities()
        community_sizes = [len(c) for c in communities]
        
        # 社会凝聚力
        cohesion = 0
        if len(community_sizes) > 0:
            cohesion = np.mean(community_sizes) / (self.rows * self.cols) * 100
        
        # 社会稳定性
        stability = self.calculate_stability()
        
        # 社会流动性
        mobility = 0
        if len(self.sociology_history) > 1:
            prev_communities = self.sociology_history[-2].get('communities', 1)
            mobility = abs(len(communities) - prev_communities) / max(prev_communities, 1)
        
        return {
            'communities': len(communities),
            'community_sizes': community_sizes,
            'cohesion': cohesion,
            'stability': stability,
            'mobility': mobility,
            'diversity': self.calculate_diversity()
        }
    
    def detect_communities(self):
        """检测社区(连通区域)"""
        visited = np.zeros_like(self.grid, dtype=bool)
        communities = []
        
        for i in range(self.rows):
            for j in range(self.cols):
                if self.grid[i, j] == 1 and not visited[i, j]:
                    community = []
                    stack = [(i, j)]
                    
                    while stack:
                        x, y = stack.pop()
                        if not visited[x, y] and self.grid[x, y] == 1:
                            visited[x, y] = True
                            community.append((x, y))
                            
                            for dx in [-1, 0, 1]:
                                for dy in [-1, 0, 1]:
                                    if dx == 0 and dy == 0:
                                        continue
                                    nx, ny = (x + dx) % self.rows, (y + dy) % self.cols
                                    if not visited[nx, ny] and self.grid[nx, ny] == 1:
                                        stack.append((nx, ny))
                    
                    if community:
                        communities.append(community)
        
        return communities
    
    def calculate_psychology_metrics(self):
        """计算心理学指标"""
        stress_levels = []
        conformity_count = 0
        innovation_count = 0
        
        for i in range(self.rows):
            for j in range(self.cols):
                if self.grid[i, j] == 1:
                    neighbors = self.get_neighbors(i, j)
                    
                    # 个体压力
                    stress = abs(neighbors - 2.5) / 3.5
                    stress_levels.append(stress)
                    
                    # 从众倾向
                    if neighbors >= 4:
                        conformity_count += 1
                    
                    # 创新倾向
                    if neighbors <= 1:
                        innovation_count += 1
        
        total_cells = np.sum(self.grid)
        
        # 集体情绪
        collective_mood = 0
        if stress_levels:
            collective_mood = 1.0 - np.mean(stress_levels)
        
        return {
            'stress': np.mean(stress_levels) if stress_levels else 0,
            'conformity': conformity_count / max(total_cells, 1),
            'innovation': innovation_count / max(total_cells, 1),
            'collective_mood': collective_mood,
            'social_influence': self.calculate_social_influence()
        }
    
    def calculate_social_influence(self):
        """计算社会影响力"""
        neighbor_counts = []
        stress_levels = []
        
        for i in range(self.rows):
            for j in range(self.cols):
                if self.grid[i, j] == 1:
                    neighbors = self.get_neighbors(i, j)
                    neighbor_counts.append(neighbors)
                    stress_levels.append(abs(neighbors - 2.5) / 3.5)
        
        if len(neighbor_counts) > 1 and len(set(neighbor_counts)) > 1:
            return np.corrcoef(stress_levels, neighbor_counts)[0, 1]
        return 0
    
    def calculate_system_metrics(self):
        """计算复杂系统指标"""
        # 计算分形维度
        fractal_dim = self.calculate_fractal_dimension()
        
        # 计算系统熵
        entropy = self.calculate_entropy()
        
        # 计算自组织临界性
        criticality = self.calculate_criticality()
        
        # 计算涌现性指标
        emergence = self.calculate_emergence()
        
        return {
            'fractal_dim': fractal_dim,
            'entropy': entropy,
            'criticality': criticality,
            'emergence': emergence,
            'adaptability': self.calculate_adaptability(),
            'resilience': self.calculate_resilience()
        }
    
    def calculate_fractal_dimension(self):
        """计算分形维度(盒子计数法)"""
        if np.sum(self.grid) == 0:
            return 0
            
        box_sizes = [2, 4, 8, 16, 32]
        counts = []
        
        for box_size in box_sizes:
            if box_size > min(self.rows, self.cols):
                break
                
            count = 0
            for i in range(0, self.rows, box_size):
                for j in range(0, self.cols, box_size):
                    if np.any(self.grid[i:i+box_size, j:j+box_size] == 1):
                        count += 1
            counts.append(count)
        
        if len(counts) < 2 or all(c == 0 for c in counts):
            return 0
            
        # 线性拟合计算分形维度
        log_sizes = np.log([1/s for s in box_sizes[:len(counts)]])
        log_counts = np.log(counts)
        
        try:
            coeffs = np.polyfit(log_sizes, log_counts, 1)
            return coeffs[0]
        except:
            return 0
    
    def calculate_entropy(self):
        """计算系统熵"""
        if np.sum(self.grid) == 0:
            return 0
            
        # 计算3x3模式的熵
        patterns = []
        for i in range(self.rows-2):
            for j in range(self.cols-2):
                pattern = self.grid[i:i+3, j:j+3]
                patterns.append(pattern.tobytes())
        
        unique_patterns, counts = np.unique(patterns, return_counts=True)
        probs = counts / len(patterns)
        
        return -np.sum(probs * np.log2(probs))
    
    def calculate_criticality(self):
        """计算自组织临界性"""
        if len(self.metrics_history) < 10:
            return 0
            
        # 通过雪崩大小分布判断临界性
        avalanche_sizes = []
        current_size = 0
        
        for metrics in self.metrics_history:
            if metrics['total_cells'] > 0:
                current_size += 1
            else:
                if current_size > 0:
                    avalanche_sizes.append(current_size)
                    current_size = 0
        
        if current_size > 0:
            avalanche_sizes.append(current_size)
        
        if len(avalanche_sizes) < 3:
            return 0
            
        # 检查是否服从幂律分布
        try:
            # 简单的幂律拟合
            hist, bin_edges = np.histogram(avalanche_sizes, bins='auto')
            bin_centers = (bin_edges[:-1] + bin_edges[1:]) / 2
            
            # 移除零值
            mask = hist > 0
            if np.sum(mask) < 3:
                return 0
                
            log_bins = np.log(bin_centers[mask])
            log_hist = np.log(hist[mask])
            
            coeffs = np.polyfit(log_bins, log_hist, 1)
            exponent = -coeffs[0]
            
            # 幂律指数在2-3之间表示临界性
            if 2 <= exponent <= 3:
                return 0.8
            elif 1.5 <= exponent <= 3.5:
                return 0.5
            else:
                return 0.2
        except:
            return 0
    
    def calculate_emergence(self):
        """计算涌现性指标"""
        if len(self.metrics_history) < 5:
            return 0
            
        # 涌现性 = 整体复杂度 - 局部复杂度
        global_complexity = self.calculate_complexity()
        
        # 计算局部复杂度平均值
        local_complexities = []
        for i in range(0, self.rows, 10):
            for j in range(0, self.cols, 10):
                subgrid = self.grid[i:min(i+10, self.rows), j:min(j+10, self.cols)]
                if np.sum(subgrid) > 0:
                    # 简化计算局部复杂度
                    local_complexity = np.std(subgrid) / max(np.mean(subgrid), 1)
                    local_complexities.append(local_complexity)
        
        if not local_complexities:
            return 0
            
        local_complexity_avg = np.mean(local_complexities)
        
        return max(0, global_complexity - local_complexity_avg)
    
    def calculate_adaptability(self):
        """计算系统适应性"""
        if len(self.metrics_history) < 3:
            return 0
            
        # 适应性 = 稳定性 * 效率
        stability = self.calculate_stability()
        efficiency = self.calculate_efficiency()
        
        return stability * efficiency
    
    def calculate_resilience(self):
        """计算系统韧性"""
        if len(self.metrics_history) < 10:
            return 0
            
        # 通过恢复速度衡量韧性
        recent_cells = [m['total_cells'] for m in list(self.metrics_history)[-10:]]
        recovery_speed = 0
        
        for i in range(1, len(recent_cells)):
            if recent_cells[i] > recent_cells[i-1]:
                recovery_speed += 1
        
        return recovery_speed / 9

# 初始化游戏状态
if 'game_state' not in st.session_state:
    st.session_state.game_state = GameState(900, 900)

game_state = st.session_state.game_state

# 标题
st.markdown('<h1 class="main-header">社会经济学复杂性仿真计算推演</h1>', unsafe_allow_html=True)
st.markdown("""
    <div style='text-align: center; color: #666; margin-bottom: 2rem;'>
        实时可视化多维度复杂系统分析平台 | 每 {speed:.2f} 秒更新一代
    </div>
""".format(speed=game_state.speed), unsafe_allow_html=True)

# 侧边栏控制面板
with st.sidebar:
    st.markdown('<h3 class="sub-header">面板</h3>', unsafe_allow_html=True)
    
    col1, col2 = st.columns(2)
    with col1:
        if st.button("开始" if game_state.paused else "暂停", use_container_width=True):
            game_state.paused = not game_state.paused
    with col2:
        if st.button("重置", use_container_width=True):
            game_state.initialize_grid("random", 0.3)
    
    st.markdown("---")
    
    # 网格设置
    st.markdown('<h4>网格</h4>', unsafe_allow_html=True)
    
    pattern = st.selectbox(
        "初始模式",
        ["random", "center", "gliders", "clusters"],
        format_func=lambda x: {
            "random": "随机分布",
            "center": "中心聚集", 
            "gliders": "滑翔机群",
            "clusters": "多集群"
        }[x]
    )
    
    density = st.slider("初始密度", 0.1, 0.8, 0.3, 0.05)
    
    if st.button("应用模式设置", width='stretch'):
        game_state.initialize_grid(pattern, density)
    
    st.markdown("---")
    
    # 模拟参数
    st.markdown('<h4>参数</h4>', unsafe_allow_html=True)
    game_state.speed = st.slider("模拟速度", 0.01, 1.0, 0.1, 0.01, format="%.2f秒/代")
    
    st.markdown("---")
    
    # 数据管理
    st.markdown('<h4>数据</h4>', unsafe_allow_html=True)
    
    if st.button("导出", use_container_width=True):
        # 创建数据框
        all_data = []
        for i, metrics in enumerate(game_state.metrics_history):
            row = {'generation': metrics['generation']}
            
            # 演化趋势
            row.update({f'evolution_{k}': v for k, v in metrics.items() if k != 'generation'})
            
            # 经济学
            if i < len(game_state.economic_history):
                row.update({f'economics_{k}': v for k, v in list(game_state.economic_history)[i].items()})
            
            # 社会学
            if i < len(game_state.sociology_history):
                row.update({f'sociology_{k}': v for k, v in list(game_state.sociology_history)[i].items()})
            
            # 心理学
            if i < len(game_state.psychology_history):
                row.update({f'psychology_{k}': v for k, v in list(game_state.psychology_history)[i].items()})
            
            # 复杂系统
            if i < len(game_state.system_history):
                row.update({f'system_{k}': v for k, v in list(game_state.system_history)[i].items()})
            
            all_data.append(row)
        
        df = pd.DataFrame(all_data)
        
        # 转换为CSV
        csv = df.to_csv(index=False)
        b64 = base64.b64encode(csv.encode()).decode()
        href = f'<a href="data:file/csv;base64,{b64}" download="life_game_complete_data.csv">点击下载完整数据 CSV 文件</a>'
        st.markdown(href, unsafe_allow_html=True)
    
    st.markdown("---")
    
    # 实时统计
    st.markdown('<h4>实时统计</h4>', unsafe_allow_html=True)
    
    st.metric("当前代数", f"{game_state.generation}")
    st.metric("活跃细胞", f"{np.sum(game_state.grid):,}")
    st.metric("细胞密度", f"{np.sum(game_state.grid) / (game_state.rows * game_state.cols):.2%}")
    
    if len(game_state.metrics_history) > 0:
        latest = game_state.metrics_history[-1]
        st.metric("系统稳定性", f"{latest['stability']:.3f}")
        st.metric("配置效率", f"{latest['efficiency']:.3f}")

# 主区域 - 顶部指标和网格
col1, col2, col3, col4 = st.columns(4)

with col1:
    st.markdown("### 基础指标")
    st.metric("网格大小", f"{game_state.rows}×{game_state.cols}")
    st.metric("模拟状态", "运行中" if not game_state.paused else "已暂停")
    
with col2:
    st.markdown("### 经济学")
    if len(game_state.economic_history) > 0:
        econ = game_state.economic_history[-1]
        st.metric("经济规模", f"{econ['gdp']:,.0f}")
        st.metric("增长率", f"{econ['growth_rate']:+.2f}%")
    
with col3:
    st.markdown("### 社会学")
    if len(game_state.sociology_history) > 0:
        soc = game_state.sociology_history[-1]
        st.metric("社区数量", f"{soc['communities']}")
        st.metric("社会凝聚力", f"{soc['cohesion']:.1f}%")
    
with col4:
    st.markdown("### 心理学")
    if len(game_state.psychology_history) > 0:
        psych = game_state.psychology_history[-1]
        st.metric("集体情绪", f"{psych['collective_mood']:.3f}")
        st.metric("从众倾向", f"{psych['conformity']:.2%}")

# 网格可视化
st.markdown('<h3 class="sub-header">实时网格状态</h3>', unsafe_allow_html=True)

# 设置绘图参数
fig_grid, ax_grid = plt.subplots(figsize=(15, 9))
ax_grid.imshow(game_state.grid, cmap='viridis', interpolation='nearest')
ax_grid.set_xticks([])
ax_grid.set_yticks([])
ax_grid.set_title(f'第 {game_state.generation} 代 | 活跃细胞: {np.sum(game_state.grid)}', fontsize=18, pad=20, fontname='Microsoft YaHei')

# 添加网格线
ax_grid.set_xticks(np.arange(-0.5, game_state.cols, 1), minor=True)
ax_grid.set_yticks(np.arange(-0.5, game_state.rows, 1), minor=True)
ax_grid.grid(which='minor', color='gray', linestyle='-', linewidth=0.5, alpha=0.3)

st.pyplot(fig_grid)

# 创建标签页
tab1, tab2, tab3, tab4, tab5 = st.tabs([
    "演化趋势",
    "经济学分析",
    "社会学视角",
    "心理学指标",
    "复杂系统"
])

with tab1:
    # 演化趋势分析
    st.markdown('<h3 class="sub-header">演化趋势实时分析</h3>', unsafe_allow_html=True)
    
    if len(game_state.metrics_history) > 1:
        df = pd.DataFrame(list(game_state.metrics_history))
        
        # 创建演化趋势图表
        fig = make_subplots(
            rows=2, cols=3,
            subplot_titles=('细胞总数演化', '系统稳定性', '配置效率', 
                          '资源分配不均', '系统复杂度', '模式多样性'),
            vertical_spacing=0.15,
            horizontal_spacing=0.1
        )
        
        # 细胞总数
        fig.add_trace(
            go.Scatter(x=df['generation'], y=df['total_cells'], 
                      mode='lines', name='细胞总数',
                      line=dict(color='blue', width=2)),
            row=1, col=1
        )
        
        # 系统稳定性
        fig.add_trace(
            go.Scatter(x=df['generation'], y=df['stability'], 
                      mode='lines', name='稳定性',
                      line=dict(color='green', width=2)),
            row=1, col=2
        )
        
        # 配置效率
        fig.add_trace(
            go.Scatter(x=df['generation'], y=df['efficiency'], 
                      mode='lines', name='效率',
                      line=dict(color='red', width=2)),
            row=1, col=3
        )
        
        # 资源分配不均
        fig.add_trace(
            go.Scatter(x=df['generation'], y=df['inequality'], 
                      mode='lines', name='不均度',
                      line=dict(color='orange', width=2)),
            row=2, col=1
        )
        
        # 系统复杂度
        fig.add_trace(
            go.Scatter(x=df['generation'], y=df['complexity'], 
                      mode='lines', name='复杂度',
                      line=dict(color='purple', width=2)),
            row=2, col=2
        )
        
        # 模式多样性
        fig.add_trace(
            go.Scatter(x=df['generation'], y=df['diversity'], 
                      mode='lines', name='多样性',
                      line=dict(color='brown', width=2)),
            row=2, col=3
        )
        
        fig.update_layout(height=700, showlegend=True, legend=dict(orientation="h", yanchor="bottom", y=1.02, xanchor="right", x=1))
        st.plotly_chart(fig, use_container_width=True)
        
        # 统计卡片
        col1, col2, col3, col4 = st.columns(4)
        with col1:
            st.metric("平均细胞数", f"{df['total_cells'].mean():.0f}")
        with col2:
            st.metric("最大细胞数", f"{df['total_cells'].max():.0f}")
        with col3:
            st.metric("平均稳定性", f"{df['stability'].mean():.3f}")
        with col4:
            st.metric("平均效率", f"{df['efficiency'].mean():.3f}")
    
    else:
        st.info("请开始模拟以查看演化趋势数据")

with tab2:
    # 经济学分析
    st.markdown('<h3 class="sub-header">经济学实时分析</h3>', unsafe_allow_html=True)

    if len(game_state.economic_history) > 1:
        df_econ = pd.DataFrame(list(game_state.economic_history))

        # 创建经济学分析图表
        fig = make_subplots(
            rows=2, cols=2,
            subplot_titles=('经济规模(GDP)趋势', '经济增长率',
                          '经济波动性', '经济不平等程度'),
            specs=[[{'secondary_y': True}, {}],
                   [{}, {}]],
            vertical_spacing=0.15
        )

        # 经济规模
        fig.add_trace(
            go.Scatter(x=list(range(len(df_econ))), y=df_econ['gdp'],
                      mode='lines', name='GDP',
                      line=dict(color='green', width=3)),
            row=1, col=1
        )

        # 经济增长率
        fig.add_trace(
            go.Bar(x=list(range(len(df_econ))), y=df_econ['growth_rate'],
                  name='增长率',
                  marker_color=['green' if x > 0 else 'red' for x in df_econ['growth_rate']]),
            row=1, col=2
        )

        # 经济波动性
        fig.add_trace(
            go.Scatter(x=list(range(len(df_econ))), y=df_econ['volatility'],
                      mode='lines', name='波动性',
                      line=dict(color='orange', width=2),
                      fill='tozeroy'),
            row=2, col=1
        )

        # 经济不平等
        fig.add_trace(
            go.Scatter(x=list(range(len(df_econ))), y=df_econ['inequality'],
                      mode='lines', name='不平等',
                      line=dict(color='red', width=2)),
            row=2, col=2
        )
        
        # 添加经济周期区域
        if 'economic_cycle' in df_econ.columns:
            for i, cycle in enumerate(df_econ['economic_cycle']):
                if cycle == "扩张":
                    fig.add_vrect(x0=i-0.5, x1=i+0.5, 
                                 fillcolor="green", opacity=0.1, 
                                 line_width=0, row=1, col=1)
                elif cycle == "衰退":
                    fig.add_vrect(x0=i-0.5, x1=i+0.5, 
                                 fillcolor="red", opacity=0.1, 
                                 line_width=0, row=1, col=1)
        
        fig.update_layout(height=700, showlegend=True)
        st.plotly_chart(fig, use_container_width=True)
        
        # 经济学指标卡片
        col1, col2, col3 = st.columns(3)
        with col1:
            current_gdp = df_econ['gdp'].iloc[-1] if len(df_econ) > 0 else 0
            st.metric("当前GDP", f"{current_gdp:,.0f}")
        with col2:
            avg_growth = df_econ['growth_rate'].mean() if len(df_econ) > 0 else 0
            st.metric("平均增长率", f"{avg_growth:+.2f}%")
        with col3:
            current_inequality = df_econ['inequality'].iloc[-1] if len(df_econ) > 0 else 0
            inequality_status = "高度不平等" if current_inequality > 0.4 else "中度不平等" if current_inequality > 0.3 else "相对平等"
            st.metric("不平等状态", inequality_status, f"{current_inequality:.3f}")
        
        # 经济周期分析
        st.markdown("##### 经济周期分析")
        if len(df_econ) > 5:
            recent_cycles = df_econ['economic_cycle'].tail(5).tolist()
            
            cycle_counts = pd.Series(recent_cycles).value_counts()
            
            fig_cycle = go.Figure(data=[
                go.Pie(labels=cycle_counts.index, 
                      values=cycle_counts.values,
                      hole=0.3)
            ])
            
            fig_cycle.update_layout(
                title="近期经济周期分布",
                height=300
            )
            
            st.plotly_chart(fig_cycle, use_container_width=True)
    
    else:
        st.info("请开始模拟以查看经济学分析数据")

with tab3:
    # 社会学视角
    st.markdown('<h3 class="sub-header">社会学实时分析</h3>', unsafe_allow_html=True)

    if len(game_state.sociology_history) > 1:
        df_soc = pd.DataFrame(list(game_state.sociology_history))

        # 创建社会学分析图表
        col1, col2 = st.columns(2)

        with col1:
            # 社区结构演化
            fig1 = go.Figure()

            fig1.add_trace(go.Scatter(
                x=list(range(len(df_soc))),
                y=df_soc['communities'],
                mode='lines+markers',
                name='社区数量',
                line=dict(color='blue', width=3),
                marker=dict(size=8)
            ))

            fig1.add_trace(go.Scatter(
                x=list(range(len(df_soc))),
                y=df_soc['cohesion'],
                mode='lines',
                name='社会凝聚力',
                line=dict(color='green', width=2, dash='dash'),
                yaxis='y2'
            ))
            
            fig1.update_layout(
                title='社区数量与社会凝聚力',
                yaxis=dict(title='社区数量'),
                yaxis2=dict(title='社会凝聚力(%)', overlaying='y', side='right'),
                height=400
            )
            
            st.plotly_chart(fig1, use_container_width=True)
        
        with col2:
            # 社会稳定性与流动性
            fig2 = go.Figure()

            fig2.add_trace(go.Scatter(
                x=list(range(len(df_soc))),
                y=df_soc['stability'],
                mode='lines',
                name='社会稳定性',
                line=dict(color='red', width=3)
            ))

            fig2.add_trace(go.Scatter(
                x=list(range(len(df_soc))),
                y=df_soc['mobility'],
                mode='lines',
                name='社会流动性',
                line=dict(color='orange', width=2, dash='dash'),
                yaxis='y2'
            ))
            
            fig2.update_layout(
                title='社会稳定性与流动性',
                yaxis=dict(title='稳定性'),
                yaxis2=dict(title='流动性', overlaying='y', side='right'),
                height=400
            )
            
            st.plotly_chart(fig2, use_container_width=True)
        
        # 社区规模分布
        st.markdown("##### 社区规模分布")
        
        if len(game_state.sociology_history) > 0:
            latest_soc = game_state.sociology_history[-1]
            community_sizes = latest_soc.get('community_sizes', [])
            
            if community_sizes:
                fig3 = go.Figure()
                
                fig3.add_trace(go.Histogram(
                    x=community_sizes,
                    nbinsx=10,
                    name='社区规模分布',
                    marker_color='lightblue',
                    opacity=0.7
                ))
                
                fig3.update_layout(
                    title=f'社区规模分布(共{len(community_sizes)}个社区)',
                    xaxis_title='社区规模(细胞数量)',
                    yaxis_title='社区数量',
                    height=400
                )
                
                st.plotly_chart(fig3, use_container_width=True)
                
                # 社区统计
                col1, col2, col3 = st.columns(3)
                with col1:
                    st.metric("最大社区", f"{max(community_sizes) if community_sizes else 0}")
                with col2:
                    st.metric("平均社区规模", f"{np.mean(community_sizes):.1f}")
                with col3:
                    st.metric("社区规模标准差", f"{np.std(community_sizes):.1f}")
        
        # 社会网络可视化
        st.markdown("##### 社会网络结构")
        
        # 生成简化的社会网络可视化
        if len(game_state.sociology_history) > 0:
            # 创建模拟社会网络
            np.random.seed(game_state.generation)
            
            n_nodes = min(15, len(game_state.sociology_history[-1].get('community_sizes', [1])) * 3)
            if n_nodes < 3:
                n_nodes = 3
            
            # 生成节点位置
            theta = np.linspace(0, 2*np.pi, n_nodes, endpoint=False)
            radius = 0.8
            node_x = radius * np.cos(theta)
            node_y = radius * np.sin(theta)
            
            # 随机生成节点大小(基于社区规模)
            node_sizes = np.random.randint(10, 30, n_nodes)
            
            # 生成边(连接)
            edges = []
            for i in range(n_nodes):
                for j in range(i+1, n_nodes):
                    # 连接概率与距离成反比
                    distance = np.sqrt((node_x[i]-node_x[j])**2 + (node_y[i]-node_y[j])**2)
                    if np.random.random() < 0.7 * np.exp(-distance):
                        edges.append((i, j))
            
            fig_network = go.Figure()
            
            # 添加边
            for edge in edges:
                fig_network.add_trace(go.Scatter(
                    x=[node_x[edge[0]], node_x[edge[1]], None],
                    y=[node_y[edge[0]], node_y[edge[1]], None],
                    mode='lines',
                    line=dict(width=1, color='gray'),
                    hoverinfo='none',
                    showlegend=False
                ))
            
            # 添加节点
            fig_network.add_trace(go.Scatter(
                x=node_x, y=node_y,
                mode='markers',
                marker=dict(
                    size=node_sizes,
                    color=np.random.rand(n_nodes),
                    colorscale='Viridis',
                    line=dict(width=2, color='white')
                ),
                text=[f'节点 {i+1}' for i in range(n_nodes)],
                hoverinfo='text',
                name='社会节点'
            ))
            
            fig_network.update_layout(
                title='社会网络结构模拟',
                xaxis=dict(showgrid=False, zeroline=False, showticklabels=False, range=[-1, 1]),
                yaxis=dict(showgrid=False, zeroline=False, showticklabels=False, range=[-1, 1]),
                height=400,
                showlegend=False
            )
            
            st.plotly_chart(fig_network, use_container_width=True)
    
    else:
        st.info("请开始模拟以查看社会学分析数据")

with tab4:
    # 心理学指标
    st.markdown('<h3 class="sub-header">心理学实时分析</h3>', unsafe_allow_html=True)

    if len(game_state.psychology_history) > 1:
        df_psych = pd.DataFrame(list(game_state.psychology_history))

        # 创建心理学分析图表
        fig = make_subplots(
            rows=2, cols=2,
            subplot_titles=('群体压力水平', '从众与创新倾向',
                          '集体情绪演化', '社会影响力'),
            vertical_spacing=0.15
        )

        # 群体压力水平
        fig.add_trace(
            go.Scatter(x=list(range(len(df_psych))), y=df_psych['stress'],
                      mode='lines', name='压力水平',
                      line=dict(color='red', width=3),
                      fill='tozeroy'),
            row=1, col=1
        )

        # 从众与创新倾向
        fig.add_trace(
            go.Scatter(x=list(range(len(df_psych))), y=df_psych['conformity'],
                      mode='lines', name='从众倾向',
                      line=dict(color='blue', width=2)),
            row=1, col=2
        )

        fig.add_trace(
            go.Scatter(x=list(range(len(df_psych))), y=df_psych['innovation'],
                      mode='lines', name='创新倾向',
                      line=dict(color='green', width=2, dash='dash')),
            row=1, col=2
        )

        # 集体情绪
        fig.add_trace(
            go.Scatter(x=list(range(len(df_psych))), y=df_psych['collective_mood'],
                      mode='lines+markers', name='集体情绪',
                      line=dict(color='orange', width=3),
                      marker=dict(size=6)),
            row=2, col=1
        )
        
        # 添加情绪区域
        fig.add_hrect(y0=0.7, y1=1.0, row=2, col=1,
                     fillcolor="green", opacity=0.1, line_width=0,
                     annotation_text="积极", annotation_position="top right")
        fig.add_hrect(y0=0.3, y1=0.7, row=2, col=1,
                     fillcolor="yellow", opacity=0.1, line_width=0,
                     annotation_text="中性", annotation_position="top right")
        fig.add_hrect(y0=0, y1=0.3, row=2, col=1,
                     fillcolor="red", opacity=0.1, line_width=0,
                     annotation_text="消极", annotation_position="top right")
        
        # 社会影响力
        fig.add_trace(
            go.Scatter(x=list(range(len(df_psych))), y=df_psych['social_influence'],
                      mode='lines', name='社会影响力',
                      line=dict(color='purple', width=2)),
            row=2, col=2
        )
        
        fig.update_layout(height=700, showlegend=True)
        st.plotly_chart(fig, use_container_width=True)
        
        # 心理学指标卡片
        col1, col2, col3, col4 = st.columns(4)
        with col1:
            current_stress = df_psych['stress'].iloc[-1] if len(df_psych) > 0 else 0
            stress_level = "高压力" if current_stress > 0.6 else "中等压力" if current_stress > 0.3 else "低压力"
            st.metric("压力水平", stress_level, f"{current_stress:.3f}")
        
        with col2:
            current_mood = df_psych['collective_mood'].iloc[-1] if len(df_psych) > 0 else 0
            mood_status = "积极" if current_mood > 0.7 else "中性" if current_mood > 0.3 else "消极"
            st.metric("集体情绪", mood_status, f"{current_mood:.3f}")
        
        with col3:
            conformity = df_psych['conformity'].iloc[-1] if len(df_psych) > 0 else 0
            st.metric("从众倾向", f"{conformity:.1%}")
        
        with col4:
            innovation = df_psych['innovation'].iloc[-1] if len(df_psych) > 0 else 0
            st.metric("创新倾向", f"{innovation:.1%}")
        
        # 压力分布热图
        st.markdown("##### 心理状态热图")
        
        # 计算每个细胞的压力水平
        stress_grid = np.zeros((game_state.rows, game_state.cols))
        for i in range(game_state.rows):
            for j in range(game_state.cols):
                if game_state.grid[i, j] == 1:
                    neighbors = game_state.get_neighbors(i, j)
                    stress = abs(neighbors - 2.5) / 3.5
                    stress_grid[i, j] = stress
        
        fig_heatmap = go.Figure(data=go.Heatmap(
            z=stress_grid,
            colorscale='RdBu',
            zmid=0.5,
            showscale=True,
            colorbar=dict(title="压力水平")
        ))
        
        fig_heatmap.update_layout(
            title='个体压力水平分布(红色=高压力,蓝色=低压力)',
            height=400,
            xaxis=dict(showgrid=False, showticklabels=False),
            yaxis=dict(showgrid=False, showticklabels=False)
        )
        
        st.plotly_chart(fig_heatmap, use_container_width=True)
        
        # 心理状态统计
        if np.sum(stress_grid) > 0:
            stress_values = stress_grid[stress_grid > 0].flatten()
            
            col1, col2 = st.columns(2)
            with col1:
                fig_hist = go.Figure(data=[go.Histogram(
                    x=stress_values,
                    nbinsx=10,
                    marker_color='lightcoral',
                    opacity=0.7
                )])
                
                fig_hist.update_layout(
                    title='压力水平分布直方图',
                    xaxis_title='压力水平',
                    yaxis_title='细胞数量',
                    height=300
                )
                
                st.plotly_chart(fig_hist, use_container_width=True)
            
            with col2:
                # 压力水平统计
                stress_stats = {
                    '平均压力': np.mean(stress_values),
                    '压力标准差': np.std(stress_values),
                    '最大压力': np.max(stress_values),
                    '最小压力': np.min(stress_values)
                }
                
                for stat_name, stat_value in stress_stats.items():
                    st.metric(stat_name, f"{stat_value:.3f}")
    
    else:
        st.info("请开始模拟以查看心理学分析数据")

with tab5:
    # 复杂系统分析
    st.markdown('<h3 class="sub-header">复杂系统实时分析</h3>', unsafe_allow_html=True)

    if len(game_state.system_history) > 1:
        df_system = pd.DataFrame(list(game_state.system_history))

        # 创建复杂系统分析图表
        col1, col2 = st.columns(2)

        with col1:
            # 分形维度与熵
            fig1 = go.Figure()

            fig1.add_trace(go.Scatter(
                x=list(range(len(df_system))),
                y=df_system['fractal_dim'],
                mode='lines+markers',
                name='分形维度',
                line=dict(color='blue', width=3),
                marker=dict(size=6)
            ))

            fig1.add_trace(go.Scatter(
                x=list(range(len(df_system))),
                y=df_system['entropy'],
                mode='lines',
                name='系统熵',
                line=dict(color='green', width=2, dash='dash'),
                yaxis='y2'
            ))
            
            fig1.update_layout(
                title='分形维度与系统熵',
                yaxis=dict(title='分形维度'),
                yaxis2=dict(title='系统熵', overlaying='y', side='right'),
                height=400
            )
            
            st.plotly_chart(fig1, use_container_width=True)
        
        with col2:
            # 自组织临界性与涌现性
            fig2 = go.Figure()

            fig2.add_trace(go.Scatter(
                x=list(range(len(df_system))),
                y=df_system['criticality'],
                mode='lines',
                name='自组织临界性',
                line=dict(color='red', width=3)
            ))

            fig2.add_trace(go.Scatter(
                x=list(range(len(df_system))),
                y=df_system['emergence'],
                mode='lines',
                name='涌现性',
                line=dict(color='orange', width=2, dash='dash'),
                yaxis='y2'
            ))
            
            fig2.update_layout(
                title='自组织临界性与涌现性',
                yaxis=dict(title='临界性'),
                yaxis2=dict(title='涌现性', overlaying='y', side='right'),
                height=400
            )
            
            st.plotly_chart(fig2, use_container_width=True)
        
        # 系统适应性与韧性
        st.markdown("##### 系统适应性与韧性")

        fig3 = go.Figure()

        fig3.add_trace(go.Scatter(
            x=list(range(len(df_system))),
            y=df_system['adaptability'],
            mode='lines',
            name='适应性',
            line=dict(color='green', width=3)
        ))

        fig3.add_trace(go.Scatter(
            x=list(range(len(df_system))),
            y=df_system['resilience'],
            mode='lines',
            name='韧性',
            line=dict(color='purple', width=2, dash='dash')
        ))
        
        fig3.update_layout(
            title='系统适应性与韧性演化',
            height=400
        )
        
        st.plotly_chart(fig3, use_container_width=True)
        
        # 复杂系统指标卡片
        col1, col2, col3, col4 = st.columns(4)
        with col1:
            current_fractal = df_system['fractal_dim'].iloc[-1] if len(df_system) > 0 else 0
            fractal_status = "高复杂度" if current_fractal > 1.5 else "中等复杂度" if current_fractal > 1.0 else "低复杂度"
            st.metric("分形维度", fractal_status, f"{current_fractal:.3f}")
        
        with col2:
            current_entropy = df_system['entropy'].iloc[-1] if len(df_system) > 0 else 0
            st.metric("系统熵", f"{current_entropy:.3f}")
        
        with col3:
            current_criticality = df_system['criticality'].iloc[-1] if len(df_system) > 0 else 0
            critical_status = "临界状态" if current_criticality > 0.5 else "非临界状态"
            st.metric("自组织临界性", critical_status, f"{current_criticality:.3f}")
        
        with col4:
            current_emergence = df_system['emergence'].iloc[-1] if len(df_system) > 0 else 0
            emergence_status = "强涌现" if current_emergence > 0.1 else "弱涌现" if current_emergence > 0.05 else "无涌现"
            st.metric("涌现性", emergence_status, f"{current_emergence:.3f}")
        
        # 相空间分析
        st.markdown("##### 相空间分析")
        
        if len(df_system) > 10:
            # 创建延迟嵌入(相空间重建)
            tau = 5  # 延迟
            if len(df_system) > tau * 2:
                x = df_system['fractal_dim'].values
                
                if len(x) > tau:
                    x_t = x[:-tau]
                    x_t_tau = x[tau:]
                    
                    fig_phase = go.Figure()
                    
                    fig_phase.add_trace(go.Scatter(
                        x=x_t, y=x_t_tau,
                        mode='markers+lines',
                        marker=dict(
                            size=8,
                            color=list(range(len(x_t))),
                            colorscale='Viridis',
                            showscale=True,
                            colorbar=dict(title="时间步")
                        ),
                        line=dict(width=1, color='gray'),
                        name='相空间轨迹'
                    ))
                    
                    # 添加起点和终点
                    fig_phase.add_trace(go.Scatter(
                        x=[x_t[0]], y=[x_t_tau[0]],
                        mode='markers',
                        marker=dict(size=12, color='green', symbol='circle'),
                        name='起点'
                    ))
                    
                    fig_phase.add_trace(go.Scatter(
                        x=[x_t[-1]], y=[x_t_tau[-1]],
                        mode='markers',
                        marker=dict(size=12, color='red', symbol='x'),
                        name='终点'
                    ))
                    
                    fig_phase.update_layout(
                        title=f'相空间图(延迟τ={tau})',
                        xaxis_title='D(t)',
                        yaxis_title=f'D(t+{tau})',
                        height=500
                    )

                    st.plotly_chart(fig_phase, width='stretch')
        
        # 系统状态雷达图
        st.markdown("##### 系统状态雷达图")
        
        if len(df_system) > 0:
            latest_system = df_system.iloc[-1]
            
            categories = ['分形维度', '系统熵', '自组织临界性', '涌现性', '适应性', '韧性']
            values = [
                latest_system.get('fractal_dim', 0),
                latest_system.get('entropy', 0),
                latest_system.get('criticality', 0),
                latest_system.get('emergence', 0),
                latest_system.get('adaptability', 0),
                latest_system.get('resilience', 0)
            ]
            
            # 归一化到0-1范围
            max_vals = [2.0, 5.0, 1.0, 0.2, 1.0, 1.0]
            normalized_values = [v / m for v, m in zip(values, max_vals)]
            
            fig_radar = go.Figure(data=go.Scatterpolar(
                r=normalized_values + [normalized_values[0]],  # 闭合多边形
                theta=categories + [categories[0]],
                fill='toself',
                line=dict(color='blue', width=2),
                name='当前状态'
            ))
            
            fig_radar.update_layout(
                polar=dict(
                    radialaxis=dict(
                        visible=True,
                        range=[0, 1]
                    )
                ),
                title="复杂系统状态雷达图",
                height=500
            )
            
            st.plotly_chart(fig_radar, use_container_width=True)
    
    else:
        st.info("请开始模拟以查看复杂系统分析数据")

# 实时更新
if not game_state.paused:
    game_state.update()
    time.sleep(game_state.speed)
    st.rerun()

# 页脚
st.markdown("---")
st.markdown("""
<div style='text-align: center; color: #666; font-size: 0.9rem;'>
    生命游戏社会经济学复杂性实验室 | 多学科复杂系统实时可视化分析平台 |
    数据更新时间: {time} | 当前代数: {generation}
</div>
""".format(time=datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
           generation=game_state.generation), unsafe_allow_html=True)

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐