Repast仿真建模实战:从调度器到参数扫描的ABM完整教程

简介:面向社会科学、经济学与复杂系统建模初学者的Repast完整英文教程与实例包,适合希望系统掌握多Agent仿真平台的读者。资源共72个文件,以38个htm和28个html教程页面为主体,搭配CSS样式表、界面位图、JavaDoc索引及内嵌示例压缩包,覆盖安装设置、Agent定义、模型构建、脚本控制、可视化与数据收集等模块,方便离线阅读与对照实践。包体仅303KB,轻量精炼,目前已有730人学习。教程内含HowTo系列32个操作主题、Eclipse环境配置说明以及H2R完整案例,从环境搭建到结果分析均配有实例,既可深化对Repast原理的理解,也可直接参考代码开展仿真实验,适合不同基础的研究者和开发者使用。

1. 完整教程不等于能跑起来的仿真:Repast 实例到底该怎么选

不少仿真方向的新手拿到 repast 教程和实例包之后,都以为把代码导入 IDE、启动模型、看到网格动起来就算学会了,实际上这只是 GUI 演示的幻觉。真正的 repast 学习曲线藏在两个地方:一是理解 Context 与 Agent 的双重构建逻辑,二是搞明白 Schedule 调度器里的 tick 控制和时间单位换算。这两点不看实例源码永远想不通,而多数资源包恰恰把源码折叠在 lib 里,没有配套讲解。

这份 repast 完整教程和实例资源,适合两类人:一类是有 Java 基础、想用 ABM(基于智能体建模)做仓储配送、物资分配、人员流动仿真的从业者;另一类是被官方文档英文术语劝退的初学者。资源的核心价值不是演示 Demo 的视觉效果,而是把仿真建模的完整流程——环境构建、行为调度、参数扫描、数据导出——串成了一条能动手照做的链路。我会按拆项目的习惯,把里面的模板工程拆开讲,重点说清楚编辑器的边界、调度器的坑、以及批量仿真时最容易翻车的那几步。

2. Repast 的核心机制:双构建、调度器与单位换算

2.1 双重构建:Context 与 Agent 谁先谁后

很多第一次接触 Repast Simphony(下文简称 Repast S)的人会把它当成普通的 Java 库,上来就 new 一个 Agent 丢进去跑,结果发现网格上没有实体、行为列表空白。原因在于 Repast S 的运行模型不是“类驱动”,而是“上下文驱动”。

一个模型必须包含两个层面的构建:先是数据层面,也就是用 Context 去承载 Agent 所在的空间环境(网格、GIS 或连续空间);然后是行为层面,用 Schedule 去安排每个 tick 该执行哪些方法。最常见的报错是项目里只有 XmlContext 文件,却没有对应的 ContextBuilder 实现类,这样模型加载时连 context 都不会生成。

public class WarehouseContext implements ContextBuilder<Object> { @Override public Context<Object> build(Context<Object> context) { context.setId("warehouse_sim"); // 创建连续空间,坐标范围 0-100,单位是“米” Geography<Object> geography = new Geography<Object>( new ContinuousSpace("floor_space", 100, 100)); context.addProjection(geography); // 创建网格投影,用于示意货架的位置 Grid<Object> grid = new Grid<Object>( new Grid2D("shelf_grid", 50, 50)); context.addProjection(grid); // 创建随机数种子,保证实验可复现 context.add(new RandomHelper()); for (int i = 0; i < 20; i++) { Agent worker = new WorkerAgent(i, geography, grid); context.add(worker); } return context; } }

这段代码里最容易忽视的是ContinuousSpace和Grid2D的坐标系关系。Geography管理连续坐标,而Grid是离散坐标,两者通过MoveTo方法联动。初学者若只添加其中一种投影,后面的路径规划、碰撞检测都会失效,因为 Agent 在 Repast S 里必须至少属于一个 projection 才能被调度器感知。逻辑上的顺序是:先建空间和网格,再建智能体,最后把智能体放入投影——顺序反了会导致 Agent 虽然存在,却不在任何空间内。

参数说明上,ContinuousSpace构造函数的两个 100 表示空间宽高,单位取决于你的业务建模。这里的“米”是我在代码中自定的逻辑单位,Repast 本身不感知物理单位,所有数值都只是 double。如果你想做的是线边库位布局仿真,建议把单位改成“库位格”,这样在后面的参数扫描中更容易解释结果。

2.2 调度器 Schedule:从 tick 到行为执行

设计好 Context 后,问题紧接着出现:Agent 放进了空间,但谁来驱动它动起来?答案是 Schedule。Repast S 的调度器采用“时间步”机制,每个 tick 会遍历用户注册的 TickAction,执行相应的行为方法。这有点像离散事件仿真里的“步进时钟”,但它没有严格的事件队,队里只有行为列表。

public class WarehouseSchedule { public static void main(String[] args) { Schedule schedule = new Schedule(); schedule.scheduleActionStarting(1, () -> { // 每 1 tick 执行一次上架任务分配 Context<Object> context = Contexts.getContext("warehouse_sim"); for (Object obj : context) { if (obj instanceof WorkerAgent worker) { worker.pickNextTask(); } } }); schedule.scheduleActionAtInterval(10, () -> { // 每 10 tick 记录一次库存数据,用于后期统计 System.out.println("tick " + schedule.getTickCount() + " data"); }); } }

调度器的核心参数有三个。第一个是起始时间,scheduleActionStarting(1, ...)表示从第 1 tick 开始执行;第二个是间隔,scheduleActionAtInterval(10, ...)表示每隔 10 tick 执行一次;第三个是优先级,可以在方法末尾追加ScheduleParameters.LAST或FIRST来指定先后顺序。常见误用是调度普通方法时直接传方法引用,却忘了该方法必须在 Agent 内部且被 Context 管理,否则调度器会因找不到类而抛出ClassNotFound运行时异常。

在真实项目中,我一般会把调度逻辑从主类里抽出来,统一挂在WarehouseSchedule里管理,因为 Repast S 的 GUI 界面和批处理模式都需要通过这个类去控制行为时序。如果调度器里写法混乱,后面做参数扫描时,不同实验之间会互相污染——最典型的现象是上一轮的 Agent 还在跑,下一轮又 new 一批出来,结果每个 tick 的实体数量翻倍。

2.3 SimClock 与时间单位换算

另一个新手看不见的坑是时间单位。Repast S 内置了SimClock工具,允许把 tick 映射成现实时间,比如 1 tick = 1 分钟,60 tick = 1 小时。这个映射必须在模型初始化时设定,而不是在调度器里写死。

SimClock clock = SimClock.getInstance(); clock.setUnitPerTick(1.0, TimeUnit.MINUTES);

举一个真实场景:某仓库模拟昼间 8 小时作业,每 1 tick 表示 1 分钟,则整个仿真需要跑 480 tick。如果你没做单位设定,后期读输出时就会分不清 tick 500 到底是哪天的数据。这类问题在单次运行中不易察觉,但一旦做多周实验,时间轴就乱套了。规范做法是每做一个模型,先在初始化方法里打印clock.getCurrentTime(),确认 tick 与业务时间比例无误后再跑正式实验。

3. 动手做一个仓储模型实例:环境搭建到行为实现

3.1 实例背景:仓库货物调配仿真

网络检索到的项目资料里,有一类资源和 repast 匹配度最高——仓库配送系统仿真。这恰好也是 ABM 建模的典型应用:工人(Agent)从收货区领取货物,按订单需求搬运到相应货架区,期间要避免碰撞、等待队列堆积、超时未完成。

在这份资源包中,源码组织比很多网上零碎代码规范得多:src/main/java下分出model、agent、behavior、analysis四个包。其中behavior包里的TaskScheduler.java是仿真核心,它把任务的生成、分配、移动分成了三个独立的调度方法。我觉得这种拆分值得保留,因为后续调参时,你只需要改taskGenRate参数,不需要动移动逻辑。

3.2 核心类实现:搬运工 Agent 的行为控制

资源包里的WorkerAgent.java是一个标准 ReLogo 风格 Agent 类,继承Agent基类。它的核心行为不是移动本身,而是“决策 + 移动”两段式设计:决策阶段判断最近的任务点、当前货物数量;移动阶段通过连续空间里的moveByVector逐步逼近目标坐标。下面是从资源中整理出的核心模板,去掉了无关的窗口样式代码。

public class WorkerAgent extends Agent { private Geography<Object> geography; private double x, y; private int carryingAmount; private static final double SPEED = 1.5; // 每 tick 移动距离 @ScheduleMethod(start = 1, interval = 1, priority = ScheduleParameters.LAST) public void step() { // 1. 查找可用任务列表(由市场对象 push 到共享队列) Task task = TaskBoard.getNearestTask(x, y); if (task == null || carryingAmount > 0) { // 没有任务或已满载时去暂存区卸货 moveToDropZone(); return; } // 2. 移动到任务取货点 double[] target = task.getPickupLocation(); double distX = target[0] - x; double distY = target[1] - y; double len = Math.sqrt(distX * distX + distY * distY); if (len < 0.1) { // 到达取货点,装载 carryingAmount = Math.min(5, task.getAmount()); task.consume(carryingAmount); } else { // 按实际距离移动,而不是直接跳到目标 x += (distX / len) * SPEED; y += (distY / len) * SPEED; geography.move(this, new ContinuousPoint(x, y)); } } }

这个类写法上有两个细节值得说明。第一,@ScheduleMethod注解里用了priority = ScheduleParameters.LAST,目的是先让环境更新(比如订单生成)在优先级为FIRST的方法里执行,随后智能体再读取环境状态。顺序不对时,通常会出现“货物还没生成、工人已经取完”的荒谬结果。第二,move到ContinuousPoint时没有用geography.moveTo直接指定绝对位置,而是用累积式x += ...,因为moveTo在每 tick 只能执行一次,配合连续空间才能形成连续动画效果。

这段代码在各种教程资源中几乎都能见到,但真正理解的人不多。我在初次运行时就翻过车:把geography.move与x/y坐标更新写成了两个分支,导致模型界面里 Agent 在网格上“原地抽搐”,实际坐标却没有变化。后来看了源码里ContinuousSpace的边界实现才明白,x+=之后还必须显式调用geography.move(),否则空间投影不会感知坐标变化。

3.3 运行模型与观察输出

运行 Repast S 模型有两种方式:一种是直接 Run 项目,会弹出 REPAST 自带的 2D 界面,左侧有模型树,右侧是空间画面;另一种是无头批处理模式,适合跑大量参数组合。

配置批处理模式的关键文件是model.score里的参数定义。以资源包为例,它定义了三个可变参数:工人数量worker_count(默认 10)、任务生成间隔taskGenGap(默认 20 tick)、最大携带量maxCarry(默认 5)。

<sweepParameter name="worker_count" type="int" defaultValue="10" /> <sweepParameter name="taskGenGap" type="int" defaultValue="20" /> <sweepParameter name="maxCarry" type="int" defaultValue="5" />

这里有一个使用误区:很多人以为在 Java 类里直接声明static int worker_count = 10就能被批处理识别。实际上,必须通过@Parameter注解或在.score文件中显式声明,Repast 的批处理引擎才有权在每一轮实验前替换参数值。如果你没有定义这些参数项,参数扫描窗口会一直是空的,而单个实验跑得再顺,批量做不了就等于把你的时间浪费在人工调参上。

我习惯在开发初期,先手动跑一次单模型,确认 UI 上实体数量正确、tick 推进流畅,再去配置批处理。不然一次扫描十几组参数,结果异常时,很难判断是业务逻辑问题还是参数声明问题。

4. 多实验批量仿真:参数扫描与数据导出的完整做法

4.1 数据采集:DataSet 设置

做仿真如果不采集数据,那跑出来的动画只是“看个热闹”。对于仓储项目,最重要的指标是每一 tick 的“未完成订单数量”和“空闲工人比率”。要拿到这些数据,需要在一个定时执行的方法里方法化地刷新数据集。

DataSet<Integer> ds = new DataSet<Integer>( "warehouse_stats", "tick", "pendingOrders", "idleWorkers"); // 注册数据源 ds.addSource( () -> (double) TaskBoard.getPendingOrderCount(), "pendingOrders", "订单未完成数量");

这里的DataSet会在每个 tick 结束时刷新,底层数据绑定在analysis包里的ChartCreator类。有一个细节容易被忽略:addSource传递的 Lambda 返回值类型必须为 Double,如果你从业务方法里拿到的是 Integer,就手动转一下。否则运行时会在数据源绑定处抛ClassCastException,而且这个异常只在 GUI 模式右下角日志小窗里一闪而过,批处理模式下根本看不到。

4.2 使用 ParameterSweep 跑多组实验

Repast S 的批处理实验由RepastBatchRunner驱动,通过在 main 方法里传入实验配置.xml来执行。以下是一份可以直接跑起来的批处理主类模板:

public class BatchLauncher { public static void main(String[] args) { RepastBatchRunner runner = new RepastBatchRunner("batch_params.xml"); runner.setRunCount(10); // 每个参数组合重复 10 次,消除随机性 runner.run(); runner.cleanUp(); } }

参数文件batch_params.xml里可以这样写:

<batch> <parameter name="worker_count" value="[10, 15, 20]"/> <parameter name="taskGenGap" value="[5, 10, 20]"/> </batch>

运行完后,输出目录下会有名为ModelOutput.txt的数据文件。这个文件每行对应一列数据,列顺序与DataSet中注册的顺序一致。为了后续直接用 Python 或 Excel 分析,我通常会在BatchLauncher中手动把ModelOutput.txt复制一份并重命名,同时附带上对应轮的参数值。

参数扫描最大的价值是把“玄学调参”变成“网格搜参”。你不需要反复在 GUI 里手动拖动滑块,而是提前把全部组合一次性跑掉,再根据曲线选点。这一步是 repast 区别于其他教学 Demo 的核心竞争力——它让仿真真正变成可重复实验。

4.3 数据导出的注意事项

批处理模式下数据导出有三个坑,都是从血泪经验里来的。

第一,DataSet注册的数据源和writeToFile方法被调用时,DataSet 对象必须被显式flush,否则最后一 tick 的数据可能不落盘。

第二,批量实验的随机种子若没有手动设置,同一组参数跑多轮得到的数据波动会很大。建议在ContextBuilder里手动设置种子为固定值,比如 42,再配合runCount = 10做方差分析。

第三,写 CSV 时列分隔符默认是 tab 而不是逗号,如果你用 Excel 打开乱成一行,就把后缀改成.txt看,或者用文本编辑器打开。这一点在官方文档里写得很隐晦,很多初学者在这里浪费了大半天。

5. 避坑指南:Repast 实例实战中容易翻车的四个点

现象一:界面项目能正常运行,但参数扫描窗口是空的。原因:.score文件里没有声明sweepParameter,或声明名称与 Java 类属性名不一致。解决:检查.score文件中sweepParameter的name属性,确保与@Parameter注解名称完全一致,注意大小写。如果还是空白,把model.score用纯文本打开,确认 XML 结构没有折叠注释。

现象二:Agent 在网格上移动,但坐标从未更新。原因:调用move方法没有使用ContinuousPoint,或者坐标更新逻辑放在了不存在geography投影的 Context 里。解决:在移动前打印geography.isHosted(agent)检查 Agent 是否已放入投影。未放入时,先context.add(agent)再移动。

现象三:重载模型后,旧的 Agent 还在界面上。原因:Repast S 的重载机制不会自动清空 Context 中的实体,问题是旧的 Context 没有销毁。解决:在ContextBuilder的build方法开头调用context.setId(...)强制清空;或者在重载方法中手动遍历旧 Context 里的对象并逐个remove。

现象四:批处理跑出来的数据文件,和 GUI 模式下的结果不一样。原因:两种模式使用的随机种子不同,且 GUI 模式有显示渲染开销,会影响调度节奏。解决:为两种模式分别指定随机种子,为与批处理模式区分,在ContextBuilder的初始化逻辑里增加系统属性判断。

这些坑每一条我都自己踩过。尤其第二条,当时界面里的工人原地打转,看起来像是在疯狂转向,实际上是因为我漏了geography.move(),而坐标的 x/y 已更新,动画回调拉取了错误的旧位置。后来我习惯性在每次x += ...后加一行System.out.println(agent.getX())验证状态,才彻底解决。

6. 进阶用法:把单次仿真演成可重复实验的工程化习惯

一份好的 repast 教程不只是教怎么点按钮,而是教你如何把仿真过程变得可检查、可复用。资源包末尾有一个analysis模块,里面封装了三个我觉得非常值得借鉴的工程化技巧。

第一个技巧是结果自动汇总:批处理跑完后不是直接看ModelOutput.txt,而是用一个ResultParser类自动读取数据目录下的所有文本,生成均值、最大最小值,并输出成一个简洁的 CSV 表。这样当你跑完 30 组实验时,不用手动复制粘贴数据。

# 外部脚本处理 repast 输出的多组数据 import pandas as pd files = ["model_output_%d.txt" % i for i in range(1, 31)] frames = [] for f in files: data = pd.read_csv(f, sep="\t", header=None) frames.append(data) summary = pd.concat(frames).groupby(level=0).mean() summary.to_csv("summary.csv")

第二个技巧是时间比例校正。在做完第一轮实验回看数据时,如果发现“未完成订单量”曲线在 50 秒内持续上升,先不要急着改参数,而是检查时间单位映射。很多仿真结果失真并不是因为逻辑错,而是时间尺度与业务时间尺度对不上——这在多智能体仿真里是最隐蔽的坑。

第三个技巧是可视化对比。Repast S 内置的 2D 图可以同时打开多个运行窗口,但窗口切换会拖慢模拟。更合理的做法是使用ChartCreator在批处理模式下输出图表,再导出为图片,把不同参数曲线叠在一张图上对比。资源包里的示例自带了一个line_chart.py,我通常直接用这个脚本打开数据表对比。

总的来说,从头到尾把这个仓库配送模型跑通、跑熟、跑透之后,你会发现 repast 实例的真正价值不在演示动画,而在于给了你一套针对“随机性、时序、空间交互”的完整处理框架。从那以后我每次接新仿真项目,都会强制自己先走一遍这样的流程:定义 Context、确定调度顺序、设定随机种子、跑通批处理、再调参。整个流程走通后,数据质量和可解释性完全不一样。希望这段拆解和踩坑记录能帮到你,让你的仿真项目少走几周弯路。

本文还有配套的精品资源,点击获取

相关新闻

当AI写了八成代码,程序员真正该练的判断力与工作流

当AI写了八成代码,程序员真正该练的判断力与工作流

最近那篇流传很广、署名某位图灵奖得主的论文&#xff0c;在程序员圈子里算是彻底刷了屏。刷屏的核心是一个数字&#xff1a;AI生成的代码占比已经超过八成。我刷完评论区&#xff0c;感觉大家自动分成两派&#xff1a;一派像看到了预言&#xff0c;说这是给程序员发的预警&…

2026/10/20 13:08:00 阅读更多 →
AI辅助教材编写:高效产出与低查重降重技巧全解析

AI辅助教材编写:高效产出与低查重降重技巧全解析

写教材这件事&#xff0c;听起来是老师或培训师的基本功&#xff0c;但真正做过的人都明白它有多熬人。在高校、职业院校和培训机构里&#xff0c;教材编写往往是压在教师身上的隐形大山&#xff1a;既要搭框架、找素材、写案例&#xff0c;又要排版配图、设计练习&#xff0c;…

2026/10/20 13:08:00 阅读更多 →
Flutter开发鸿蒙应用:从零搭建药品服药记录器全流程教程

Flutter开发鸿蒙应用:从零搭建药品服药记录器全流程教程

做跨平台开发这几年&#xff0c;我用 Flutter 写过不少工具类应用&#xff0c;最近刚把一个药品服用记录器顺利跑到了鸿蒙手机上。这个项目从零开始做&#xff0c;覆盖了环境配置、数据表设计、服药计划、本地通知、真机联调这一整条链路&#xff0c;中间踩了不少坑&#xff0c…

2026/10/20 13:06:59 阅读更多 →

最新新闻

SecureCRT免安装版配置指南:离线串口调试与SSH便携部署

SecureCRT免安装版配置指南:离线串口调试与SSH便携部署

简介&#xff1a;本资源为SecureCRT绿色便携版免安装包&#xff0c;面向系统管理员、运维工程师及开发人员&#xff0c;解决多平台快速部署安全终端连接工具的需求&#xff0c;尤其适用于需在不同电脑间频繁切换、无管理员权限或追求轻量使用的场景。压缩包共137个文件&#xf…

2026/10/20 14:00:00 阅读更多 →
防火墙规则集时序配置:顺序、生效时间与安全空窗排查

防火墙规则集时序配置:顺序、生效时间与安全空窗排查

防火墙规则集里的时序配置&#xff0c;是我这几年排查安全事件时最常踩的隐形坑。规则明明写对了&#xff0c;但因为顺序放错、时间对象失效、批量下发存在中间态&#xff0c;导致规则的实际生效时间和预期完全对不上&#xff0c;轻则策略空转半个月没人发现&#xff0c;重则直…

2026/10/20 14:00:00 阅读更多 →
Python Pygame核心机制与实战:从零构建接苹果小游戏

Python Pygame核心机制与实战:从零构建接苹果小游戏

很多人在命令行里写过一阵Python脚本之后&#xff0c;总想搞点“能动的、看得见的东西”。Python Pygame模块就是你会碰到的第一块敲门砖&#xff1a;一个基于SDL封装、专门用来做2D图形和游戏的原生库。我第一次用它做窗口程序的时候&#xff0c;印象最深的不是那种“我能控制…

2026/10/20 14:00:00 阅读更多 →
100套可配置ECharts大数据大屏模板工程包

100套可配置ECharts大数据大屏模板工程包

简介&#xff1a;本资源是一套面向数据可视化工程师、前端开发人员及政企数字化项目实施者的专业级大屏模板集合&#xff0c;覆盖社区治理、智慧物业、数字政务、智能交通、金融银行等十余个高需求行业场景&#xff0c;有效解决业务数据实时监控与决策看板快速搭建难题。压缩包…

2026/10/20 14:00:00 阅读更多 →
AI加速剪辑工作流:字幕、粗剪与卡点自动化实战

AI加速剪辑工作流:字幕、粗剪与卡点自动化实战

我见过太多人剪视频&#xff0c;剪到怀疑人生。明明素材拍得挺好&#xff0c;脚本也没什么大问题&#xff0c;但就是一剪一整夜&#xff0c;导出前还在逐帧删吸气声、给字幕换行、把片尾黑场拖到精确位置。你以为是效率问题&#xff0c;其实是你把80%的时间花在了AI 10秒就能搞…

2026/10/20 14:00:00 阅读更多 →
深度学习训练调参实战:梯度、激活函数、学习率与优化器的链路

深度学习训练调参实战:梯度、激活函数、学习率与优化器的链路

入门深度学习时&#xff0c;很多人会被一连串名词劝退&#xff1a;激活函数、优化器、学习率、梯度。我第一次跑模型的时候也觉得它们是四个独立的调参项&#xff0c;今天调一下学习率&#xff0c;明天换一个激活函数&#xff0c;最后模型loss曲线像心电图一样乱跳&#xff0c;…

2026/10/20 13:59:00 阅读更多 →

日新闻

CLRC663芯片Pin-to-Pin替代实战:从评估到量产全记录

CLRC663芯片Pin-to-Pin替代实战:从评估到量产全记录

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 1:01:30 阅读更多 →
ESP32舵机控制指南:原理、多路驱动与避坑实战

ESP32舵机控制指南:原理、多路驱动与避坑实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 1:01:30 阅读更多 →
位移法实现一阶低通滤波:单片机ADC采样降噪实战

位移法实现一阶低通滤波:单片机ADC采样降噪实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 1:01:30 阅读更多 →

周新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型&#xff08;GMM&#xff09;的语音识别系统&#xff0c;很多人第一反应就是一堆数学公式&#xff0c;觉得门槛很高。但如果你真的在MATLAB里把它落地跑通&#xff0c;会发现核心其实就是三件事&#xff1a;把声音变成特征向量&#xff0c;用GMM给每个类别…

2026/10/20 10:02:13 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人&#xff0c;但落到具体操作上&#xff0c;无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程&#xff1a;对图像做反白、改调色板、彩色转灰度&#xff0c;最后把像素数据导出成txt文件。单看每一…

2026/10/19 17:32:41 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词&#xff0c;你会发现一个很有意思的现象&#xff1a;每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型&#xff0c;有人指的是运动控制系统&#xff0c;还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/20 2:50:50 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 10:02:08 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 9:50:17 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 9:50:45 阅读更多 →