当前位置: 首页 > article >正文

从Python代码到动态仿真:手把手教你用SimPy搭建第一个系统动力学模型

从Python代码到动态仿真手把手教你用SimPy搭建第一个系统动力学模型在数据分析与人工智能项目中系统动力学System Dynamics正逐渐成为分析复杂系统行为的重要工具。与传统的Vensim等专用软件不同Python开发者可以通过SimPy等库直接在熟悉的编程环境中实现系统动力学建模。本文将从一个产品用户增长与流失的案例出发完整展示如何用代码构建包含反馈回路的动态模型。1. 环境准备与基础概念系统动力学的核心在于捕捉系统中的存量Stock和流量Flow关系。以用户增长模型为例存量当前总用户数随时间积累的变量流量新增用户速率和流失用户速率改变存量的变量首先安装必要的Python包pip install simpy numpy matplotlibSimPy虽然是一个离散事件仿真库但其面向过程的编程范式非常适合实现系统动力学模型。我们还需要明确几个关键概念概念数学表示代码对应状态变量L(t) L(t₀) ∫[Rin - Rout]dt类属性或全局变量速率方程Rin f(L,辅助变量)生成器函数中的yield逻辑辅助变量中间计算量普通Python函数提示系统动力学中的速率与物理学中的速度不同它表示的是单位时间内状态变量的变化量。2. 构建基础用户增长模型让我们从一个最简单的指数增长模型开始。假设产品没有用户流失且新增用户与现有用户数成正比口碑传播效应。import simpy import numpy as np import matplotlib.pyplot as plt class UserGrowthModel: def __init__(self, env): self.env env self.user_count 100 # 初始用户数 self.growth_rate 0.1 # 增长系数 # 启动仿真过程 env.process(self.update_user_count()) def update_user_count(self): while True: # 计算新增用户 (速率方程) new_users self.user_count * self.growth_rate # 更新用户数 (状态方程) self.user_count new_users # 记录当前状态 print(fTime {env.now}: Users {self.user_count:.0f}) # 等待下一个时间步 yield env.timeout(1) # 运行仿真 env simpy.Environment() model UserGrowthModel(env) env.run(until20) # 可视化结果 times np.arange(0, 21) users [100 * (1.1)**t for t in times] plt.plot(times, users, b-, labelUser Growth) plt.xlabel(Time (months)) plt.ylabel(Number of Users) plt.title(Exponential User Growth Model) plt.legend() plt.grid(True) plt.show()这个模型展示了典型的正反馈回路更多用户带来更多增长形成指数曲线。但现实中用户增长总会遇到限制因素。3. 引入负反馈用户流失机制更真实的模型应该考虑用户流失。我们增加以下要素流失率每月固定比例的用户流失市场容量产品可服务的最大用户数class ImprovedUserModel: def __init__(self, env): self.env env self.user_count 100 self.growth_rate 0.15 self.churn_rate 0.05 self.market_capacity 10000 env.process(self.simulate()) def simulate(self): while True: # 计算增长和流失 growth self.growth_rate * self.user_count * (1 - self.user_count/self.market_capacity) churn self.churn_rate * self.user_count # 更新用户数 self.user_count (growth - churn) yield env.timeout(1) # 运行并可视化 env simpy.Environment() model ImprovedUserModel(env) # 收集数据 history [] def monitor(env, model): while True: history.append((env.now, model.user_count)) yield env.timeout(1) env.process(monitor(env, model)) env.run(until60) # 绘制结果 times, users zip(*history) plt.plot(times, users, r-, labelUser Dynamics) plt.xlabel(Time (months)) plt.ylabel(Number of Users) plt.title(User Growth with Market Limits) plt.legend() plt.grid(True) plt.show()这个改进模型展示了典型的S型增长曲线包含两个阶段早期正反馈主导近似指数增长后期负反馈主导增长趋缓4. 完整系统动力学模型实现现在我们将模型扩展为完整的系统动力学结构明确分离状态变量和速率变量class SystemDynamicsModel: def __init__(self, env): self.env env # 状态变量 self.users 100 # 参数 self.growth_factor 0.2 self.churn_factor 0.08 self.capacity 5000 # 启动仿真过程 env.process(self.record_state()) env.process(self.user_acquisition()) env.process(self.user_churn()) def user_acquisition(self): 用户获取速率 while True: # 速率方程受当前用户数和市场饱和度影响 potential_users self.capacity - self.users acquisition_rate self.growth_factor * self.users * (potential_users/self.capacity) # 更新状态 self.users acquisition_rate yield env.timeout(1) def user_churn(self): 用户流失速率 while True: # 速率方程与当前用户数成正比 churn_rate self.churn_factor * self.users # 更新状态 self.users - churn_rate yield env.timeout(1) def record_state(self): 记录系统状态 while True: print(f{env.now}: Users{self.users:.1f}) yield env.timeout(1) # 运行仿真 env simpy.Environment() model SystemDynamicsModel(env) env.run(until50)这种结构更符合系统动力学的建模范式其中user_acquisition和user_churn是两个独立的速率过程状态变量users由这两个速率共同决定5. 高级应用多回路系统与策略测试实际业务场景往往涉及多个相互影响的反馈回路。例如考虑营销投入对用户增长的影响class MarketingModel: def __init__(self, env): self.env env # 状态变量 self.users 100 self.budget 100000 self.market_awareness 0.1 # 参数 self.cpa 50 # 获客成本 self.revenue_per_user 10 self.organic_growth 0.05 self.depreciation 0.02 env.process(self.simulate()) def simulate(self): while True: # 计算各速率 paid_acquisition min(self.budget/self.cpa, 1000*(1-self.market_awareness)) organic_growth self.organic_growth * self.users * self.market_awareness churn 0.03 * self.users revenue self.revenue_per_user * self.users awareness_growth 0.001 * self.users - self.depreciation * self.market_awareness # 更新状态 self.users (paid_acquisition organic_growth - churn) self.budget (revenue - paid_acquisition*self.cpa) self.market_awareness max(0, min(1, self.market_awareness awareness_growth)) yield env.timeout(1) # 测试不同策略 def run_simulation(initial_budget): env simpy.Environment() model MarketingModel(env) model.budget initial_budget history [] def monitor(): while True: history.append((env.now, model.users, model.budget, model.market_awareness)) yield env.timeout(1) env.process(monitor()) env.run(until36) return history # 比较三种预算策略 results { low: run_simulation(50000), medium: run_simulation(100000), high: run_simulation(200000) } # 可视化比较 plt.figure(figsize(12, 4)) for i, key in enumerate([users, budget, market_awareness]): plt.subplot(1, 3, i1) for strategy in results: data results[strategy] values [item[i1] for item in data] plt.plot(range(37), values, labelstrategy) plt.title(key.replace(_, ).title()) plt.legend() plt.tight_layout() plt.show()这个扩展模型包含了三个主要反馈回路营销预算回路预算→获客→收入→预算口碑传播回路用户数→市场认知度→自然增长→用户数流失抑制回路用户数→流失量→用户数6. 模型验证与敏感性分析构建模型后我们需要验证其合理性并理解关键参数的影响def sensitivity_analysis(param_name, values, runs5): 参数敏感性分析 results {} for value in values: user_counts [] for _ in range(runs): env simpy.Environment() model ImprovedUserModel(env) setattr(model, param_name, value) # 设置参数值 history [] def monitor(): while True: history.append(model.user_count) yield env.timeout(1) env.process(monitor()) env.run(until60) user_counts.append(history) # 计算平均曲线 avg_curve np.mean(user_counts, axis0) results[value] avg_curve # 绘制结果 plt.figure(figsize(10, 6)) for value, curve in results.items(): plt.plot(range(61), curve, labelf{param_name}{value}) plt.xlabel(Time (months)) plt.ylabel(User Count) plt.title(fSensitivity to {param_name}) plt.legend() plt.grid(True) plt.show() # 测试增长率的敏感性 sensitivity_analysis(growth_rate, [0.1, 0.15, 0.2, 0.25]) # 测试市场容量的敏感性 sensitivity_analysis(market_capacity, [5000, 7500, 10000, 15000])这种分析可以帮助我们识别对系统行为影响最大的关键参数验证模型是否产生合理的动态模式确定参数的合理取值范围7. 与多主体仿真的对比虽然我们用系统动力学方法建模但有时也需要考虑个体差异。下面是两种方法的对比特性系统动力学多主体仿真建模层次宏观群体层面微观个体层面用户表示同质化群体异质化个体交互方式通过速率方程直接个体间交互计算复杂度相对较低可能很高适用场景长期趋势分析突发行为研究在Python中我们可以结合两种方法。例如用SimPy实现系统动力学框架同时为某些关键组件创建个体Agentclass UserAgent: def __init__(self, user_id, retention_prob): self.id user_id self.retention_prob retention_prob self.active True def decide_churn(self): if random.random() self.retention_prob: self.active False return True return False class HybridModel: def __init__(self, env, num_users100): self.env env self.users [UserAgent(i, 0.9) for i in range(num_users)] self.growth_rate 0.1 env.process(self.simulate()) def simulate(self): while True: # 系统动力学方式处理增长 new_users int(len(self.users) * self.growth_rate) self.users.extend([UserAgent(len(self.users)i, 0.9) for i in range(new_users)]) # 多主体方式处理流失 churn_count sum(1 for u in self.users if u.decide_churn()) self.users [u for u in self.users if u.active] yield env.timeout(1)这种混合方法既保持了系统动力学的宏观视角又能捕捉重要的微观行为特征。

相关文章:

从Python代码到动态仿真:手把手教你用SimPy搭建第一个系统动力学模型

从Python代码到动态仿真:手把手教你用SimPy搭建第一个系统动力学模型 在数据分析与人工智能项目中,系统动力学(System Dynamics)正逐渐成为分析复杂系统行为的重要工具。与传统的Vensim等专用软件不同,Python开发者可以…...

图像去雾新突破:DEConv和CGA如何提升自动驾驶视觉系统性能

图像去雾新突破:DEConv和CGA如何提升自动驾驶视觉系统性能 清晨的浓雾中,一辆自动驾驶汽车缓缓驶过十字路口。车载摄像头捕捉到的画面本该模糊不清,但屏幕上却清晰地显示着行人、信号灯和障碍物——这背后是DEA-Net图像去雾技术创造的奇迹。在…...

HALCON开发避坑指南:解决SetWindowParam报错#5190的3种方法(附hcanvas.dll文件)

HALCON开发实战:彻底解决SetWindowParam报错#5190的深度解析 在工业视觉开发领域,HALCON作为行业标杆工具链,其窗口管理系统一直是实现高效图像处理的关键组件。但当你在Visual Studio中满怀信心地调用SetWindowParam进行窗口参数配置时&…...

Matlab处理遥感影像必看:地理坐标和投影坐标的GeoTIFF读写,别再搞混了!

Matlab遥感影像处理实战:地理坐标与投影坐标的GeoTIFF读写全解析 遥感影像处理中,坐标系的选择与正确读写是许多初学者容易踩坑的环节。今天我们就来深入探讨Matlab环境下如何处理这两种不同坐标系的GeoTIFF文件,从原理到实践,帮你…...

微信小程序物流查询插件接入全攻略:从资质申请到waybill_token获取(附完整代码)

微信小程序物流查询插件深度接入指南:全流程解析与实战代码 最近在帮一个电商客户优化小程序时,发现物流查询功能直接影响了30%的用户留存率。微信官方提供的物流查询插件确实能解决这个问题,但接入过程中遇到的坑比想象中多得多。今天就把完…...

树莓派5硬件PWM驱动舵机实战:从设备树编译到精准角度控制

树莓派5硬件PWM驱动舵机实战:从设备树编译到精准角度控制 树莓派5作为一款高性能的单板计算机,其硬件PWM功能在机器人、机械臂和模型制作等领域具有广泛的应用前景。与软件PWM相比,硬件PWM能够提供更稳定、更精确的控制信号,特别是…...

别再瞎调参了!HuggingFace Trainer微调BERT/ViT的保姆级避坑指南(附ArcFace实战代码)

HuggingFace Trainer微调实战:从参数陷阱到模型优化的深度拆解 当你第5次看到验证集准确率在0.85附近震荡不前,而训练损失仍在持续下降时,是否开始怀疑自己选择的优化器、学习率或损失函数?这不是个例——超过60%的NLP工程师在使用…...

FPGA图像处理避坑指南:实现CLAHE时,你的直方图统计与插值模块可能踩的这些雷

FPGA图像处理避坑指南:CLAHE实现中的直方图统计与插值模块陷阱解析 第一次在FPGA上实现CLAHE算法时,我盯着屏幕上那些奇怪的边界伪影和忽明忽暗的色块,整整三天没想明白问题出在哪。直到把示波器接到开发板上,才发现直方图统计模块…...

星图GPU云体验OpenClaw:免安装调试Phi-3-mini-128k-instruct镜像

星图GPU云体验OpenClaw:免安装调试Phi-3-mini-128k-instruct镜像 1. 为什么选择云端体验OpenClaw 上周我尝试在本地笔记本上部署OpenClaw时,被各种环境依赖和权限问题折磨得够呛。正当我准备放弃时,偶然发现星图平台提供了预装OpenClaw的GP…...

从零开始:手把手教你用UML绘制状态图(附实战案例)

从零开始:手把手教你用UML绘制状态图(附实战案例) 在软件开发的世界里,UML(统一建模语言)就像工程师的通用语言,而状态图则是其中最强大的工具之一。想象一下,当你需要清晰地描述一个…...

如何利用Lv值实现三级降帧

目录 一、核心逻辑( 二、5 种帧率 → 精简为 3 级 三、LV 阈值划分 四、代码实现 一、核心逻辑 亮度越暗 → LV 越小 → 帧率越低亮度越亮 → LV 越大 → 帧率越高 三级降帧就是: 高亮度:高帧率(30fps)中亮度&am…...

OpenClaw技能市场探秘:Phi-3-vision支持的十大实用插件

OpenClaw技能市场探秘:Phi-3-vision支持的十大实用插件 1. 为什么需要关注OpenClaw技能市场? 作为一个长期在自动化工具领域折腾的技术爱好者,我最初接触OpenClaw时,最吸引我的不是它的基础框架,而是它那个充满可能性…...

CSS如何实现不同尺寸的卡片网格_利用Grid跨行跨列设置

Grid卡片跨行跨列需用grid-row: span 2等语法避免线号计算错误;auto-fit需容器有明确宽度;高度不一致时宜用嵌套布局或grid-auto-rows: auto;IE11不支持现代Grid跨行,应降级方案。Grid卡片跨行跨列时,grid-row和grid-c…...

【安全心法】别用定时器喂狗!撕碎看门狗的伪安全面具,直面“僵尸系统”的物理绞肉机

摘要:在硬实时控制系统中,硬件看门狗被奉为防止系统死机的终极神明。但无数软硬件工程师出于偷懒或对底层架构的无知,将“喂狗”动作外包给了高频的定时器中断或最高优先级的独立任务。本文将彻底摒弃代码,纯粹从系统架构的安全哲…...

【时域心法】别用“平滑”谋杀你的闭环!撕碎软件滤波的视觉骗局,直视“相位延迟”的物理死刑

摘要:纯软件思维有着一种对“平滑数据”的病态迷恋。当他们看到夹杂着毛刺和电磁噪声的 ADC 信号时,最本能的反应就是砸下极其粗暴的“滑动平均滤波”或“低通滤波”。他们在上位机屏幕上画出了绝美的平滑曲线,却不知道自己已经亲手切断了系统…...

QW_Sensors嵌入式传感器驱动库详解

1. QW_Sensors 库概述QW_Sensors 是一个面向硬件开发者的轻量级嵌入式传感器驱动库,专为 QW Shield 硬件平台设计。该库并非通用型多平台抽象层,而是深度耦合于 QW Shield 的物理布局、供电逻辑、通信拓扑与固件约束,其核心价值在于将底层硬件…...

BUCK变换器断续模式实战:从公式推导到MATLAB仿真验证(附代码)

BUCK变换器断续模式实战:从公式推导到MATLAB仿真验证(附代码) 在电力电子领域,BUCK变换器作为最基础的降压型拓扑结构,其工作模式的理解直接影响着电源设计的可靠性。许多初学者往往对断续模式(DCM)的特性感到困惑——…...

1985-2025年全国省/市/区县土地利用分类面积及占比统计数据

数据介绍 全国土地利用分类面积统计数据(1985-2025) 数据简介 本数据集基于1985-2025年30米分辨率土地利用分类数据,结合行政区划边界,提供全国省、市、县三级行政单元的土地利用分类面积及占比统计,为土地利用变化…...

ANDON系统赋能自行车制造实现异常闭环管理

传统自行车制造业面临着多工位协同效率低、异常响应滞后等痛点。以某自行车制造工厂为例,其生产线涵盖车架组装、轮组调试、整车检测等多环节,传统异常管理存在响应滞后、协同混乱、数据缺失三大瓶颈。引入ANDON系统后,通过构建“工位触发-网…...

SEO排名推广软件有哪些技巧

SEO排名推广软件有哪些技巧 在当今互联网时代,搜索引擎优化(SEO)已经成为了各种企业和个人网站提升流量和业务的重要手段。其中,SEO排名推广软件能够帮助用户更加高效地实现网站的优化和推广。SEO排名推广软件有哪些技巧呢&#…...

Telemetrix4UnoR4:Arduino Uno R4的轻量级双向固件框架

1. 项目概述Telemetrix4UnoR4 是专为 Arduino Uno R4 系列开发板设计的嵌入式固件服务器框架,其核心目标是构建一个轻量、可靠、可扩展的双向通信桥梁,使 Python 主机端(运行telemetrix_uno_r4或telemetrix_uno_r4-aio库)能够以类…...

ArcGIS Pro新手必看:用‘按掩膜提取’和‘裁剪’工具搞定栅格与矢量数据范围限定(附详细步骤图)

ArcGIS Pro数据范围限定实战:从工具选择到避坑指南 刚接触ArcGIS Pro的研究人员常常会遇到这样的困惑:手头收集了研究区域的各种数据,却不知道如何精确限定到自己的研究范围。面对"裁剪"和"按掩膜提取"两个看似相似的工具…...

PyTorch 3.0静态图分布式训练落地实录:从torch.compile到DistributedGraphExecutor的7个关键配置节点

第一章:PyTorch 3.0静态图分布式训练全景概览PyTorch 3.0 引入了原生静态图编译能力(TorchDynamo Inductor 后端深度集成),结合 torch.distributed 的增强型 API,构建出面向大规模集群的高性能分布式训练范式。与传统…...

numpy+pandas核心操作全总结:详细代码注释(数组/Series/DataFrame完整指南)

📢 更多数据分析干货,关注公众号:船长Talk,每天分享 Python/SQL 实战技巧!两个重要的包:numpy、pandas,是数据分析师的必备基础。本文做全面总结,每段代码都有详细注释,建…...

【STM32HAL库实战】从零构建外部中断:按键唤醒与事件响应

1. 外部中断基础与STM32应用场景 第一次接触STM32外部中断时,我盯着原理图上的按键发呆了半小时——明明GPIO轮询检测就能实现的功能,为什么非要大费周章配置中断?直到某个深夜调试项目时,才真正体会到中断机制的精妙之处。当时我…...

鸿子铭:电脑上录视频后出现这个电流声得怎么处理?

大家好,我是鸿子铭。可能我们在电脑上做视频的时候可能会电流声,或者说我们在录视频之后,它也会出现这个沙沙这个声音。出现这个问题,我们该如何去解决呢?其实解决的方法有两点,在电脑上只要调试这两点的话…...

保姆级教程:在Ubuntu 20.04上跑通ORB-SLAM3双目模式(EuRoC MH04数据集实测)

从零到一:Ubuntu 20.04下ORB-SLAM3双目模式实战全记录(EuRoC MH04数据集篇) 当第一次在实验室的显示器上看到ORB-SLAM3成功重建出MH04数据集的完整三维环境时,那种成就感至今难忘。作为视觉SLAM领域的标杆算法,ORB-SL…...

OpenClaw硬件推荐:流畅运行Kimi-VL-A3B-Thinking的配置清单

OpenClaw硬件推荐:流畅运行Kimi-VL-A3B-Thinking的配置清单 1. 为什么需要关注硬件配置? 去年冬天,当我第一次尝试在MacBook Pro上运行Kimi-VL-A3B-Thinking模型时,风扇的呼啸声让我意识到——多模态模型的硬件需求远比想象中苛…...

从电解到瓷片:不同材质去耦电容在电路设计中的最佳应用场景对比

从电解到瓷片:不同材质去耦电容在电路设计中的最佳应用场景对比 当你在设计一块电路板时,是否曾经为电源引脚旁那个小小的电容而犹豫不决?是选择便宜的电解电容,还是性能稳定的瓷片电容,亦或是价格不菲的钽电容&#x…...

Android内存泄漏排查实战:如何用dma_buf揪出Low Memory的元凶

Android内存泄漏排查实战:如何用dma_buf揪出Low Memory的元凶 当你的Android设备开始频繁弹出"内存不足"的警告,甚至出现应用闪退、系统卡顿等问题时,作为开发者需要立即警觉——这很可能不是简单的内存紧张,而是潜伏着…...