使用python构建的社会经济学复杂性仿真计算推演
·

生命游戏 - 社会经济学复杂性实验室
项目概述
这是一个基于 康威生命游戏 的多学科复杂系统分析平台,将经典的细胞自动机模型应用于社会经济学、心理学和复杂系统理论的研究与可视化。
一、核心技术架构
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]范围
三、用户交互功能
控制面板
- 播放/暂停:控制模拟进程
- 重置:重新初始化网格
- 初始模式:
- 随机分布:30%密度均匀分布
- 中心聚集:高密度中心区域
- 滑翔机群:8个独立滑翔机
- 多集群:5个随机分布的集群
- 初始密度:0.1-0.8可调
- 模拟速度:0.01-1.0秒/代
数据管理
- 导出CSV:一键导出所有历史数据
- 实时统计:代数、活细胞数、密度、稳定性、效率
可视化标签页
- 演化趋势:6指标时间序列图 + 统计卡片
- 经济学分析:GDP/增长率/波动性/不平等 + 周期分布饼图
- 社会学视角:社区结构/稳定性/流动性 + 规模分布直方图 + 网络图
- 心理学指标:压力/从众/创新/情绪/影响力 + 热图 + 直方图
- 复杂系统:分形/熵/临界性/涌现/适应性/韧性 + 相空间图 + 雷达图
四、创新点
1. 跨学科整合
- 细胞自动机 → 经济学:GDP、增长率、波动性
- 细胞自动机 → 社会学:社区、流动性、网络
- 细胞自动机 → 心理学:压力、情绪、从众
- 细胞自动机 → 复杂系统:熵、分形、涌现
2. 大规模计算优化
- 内存优化:避免O(n²)外积,改用O(n log n)排序
- 时间优化:高效邻居计算、批量处理
- 存储优化:双端队列限制历史长度
3. 交互式可视化
- 实时更新:自动rerun机制
- 动态图表:Plotly交互式图表
- 多维度:5个独立标签页,28+图表
4. 数据导出
- 完整数据:所有指标的历史记录
- 格式标准:CSV格式,便于后续分析
- 时间戳:包含精确的数据更新时间
五、应用场景
学术研究
- 复杂系统理论:验证涌现性、自组织临界性
- 经济学建模:GDP波动、基尼系数、经济周期
- 社会网络分析:社区检测、流动性测量
- 计算心理学:群体行为、从众与创新
教育
- 复杂系统教学:直观展示涌现现象
- 跨学科教学:连接数学、物理、社会学
- 数据可视化教学:多维图表解读技巧
决策支持
- 政策模拟:测试不同初始条件下的演化
- 风险评估:通过不平等、波动性指标
- 资源配置:通过效率、稳定性指标优化
六、技术亮点
性能指标
- 网格规模:900×900(810,000细胞)
- 实时更新:<1秒/代(可调)
- 历史容量:500代演化数据
- 图表刷新:每代自动更新
代码质量
- 模块化设计: GameState类封装状态和计算
- 分离关注点:每个指标独立计算方法
- 错误处理:空值、除零、边界条件
- 可扩展性:易于添加新指标或维度
可访问性
- 中文支持:完整的中文字体渲染
- 响应式布局:宽屏适配
- 无表情符号:纯文本界面,兼容性强
七、未来扩展方向
- 添加更多经济学模型:IS-LM、菲利普斯曲线
- 增强社会网络:真实图算法(PageRank、社群发现)
- 机器学习集成:预测演化趋势、异常检测
- 并行计算:GPU加速大规模网格
- 实时协作:多用户共享、竞争模式
代码
# -*- 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)
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐



所有评论(0)