Releases: anticipate218/math-modeling-skill
Release list
math-modeling-skill v1.11.0
math-modeling-skill v1.11.0
面向数学建模竞赛的 AI 助手技能包。这一版把重心放在算法层:公开函数从 222 个扩到 260 个(净增 38 个),自测断言键从 875 条增至 1361 条,并对 17 个算法模块做了一轮逐函数对抗性复核,修掉 20 处真实缺陷。当一个"看着能跑"的实现和一个"能被独立复算"的实现冲突时,本版一律选后者。
新增:38 个公开算法函数(222 → 260)
| 模块 | 新增 |
|---|---|
optimization |
lp_sensitivity(影子价格 + 基不变区间)、interior_point_lp(原始-对偶内点法,带对偶变量与间隙历史) |
graphs |
bellman_ford(含负环检出)、topological_sort、critical_path(CPM 关键路径 + 松弛时间) |
heuristics |
benchmark_functions(7 个标准测试函数 + 解析最优点/最优值/标准搜索盒)、benchmark_optimizers(同预算同种子横向对比协议)、artificial_bee_colony(ABC) |
statistics |
mann_whitney_u、wilcoxon_signed_rank、kruskal_wallis、anova_oneway、newey_west_se(HAC 标准误)、bca_bootstrap_ci(偏差校正加速自助区间) |
evaluation |
rsr_evaluation(秩和比 + 概率单位分档)、promethee_ii_ranking、kendall_w_concordance(含并列修正) |
clustering |
kmedoids(PAM BUILD + 精确 SWAP) |
differential |
euler_maruyama(批量向量化的 SDE 路径模拟) |
stochastic |
mmck_metrics(M/M/c/K 有限容量排队)、geometric_brownian_motion(对数增量精确抽样) |
geometry |
sutherland_hodgman_clip |
game |
iterated_elimination、ess_check、correlated_equilibrium_lp |
timeseries |
kalman_smoother_linear(RTS 平滑器) |
ml |
pca_fit / pca_transform、pr_curve、average_precision_score |
multicriteria |
electre_ii |
multiobjective |
moead、igd_metric、spacing_metric、knee_points |
sensitivity |
sobol_second_order、impute_mice |
spatial |
moran_i(空间自相关,含置换检验) |
另外 forecasting.adf_test / mackinnon_crit 新增 regression="ctt"(含常数项与趋势项)。
修复:20 处真实缺陷
高危 branch_and_bound_ilp 把「松弛无界」误判为 infeasible;interior_point_lp 对偶残差符号写反导致不收敛甚至发散;bellman_ford 遇负自环时 has_negative_cycle=True 却返回 negative_cycle=None;simulated_annealing 几何降温下溢成精确 0.0 后 exp(-delta / T) 抛 ZeroDivisionError;garch11_forecast 均值回复指数 off-by-one。
中危 ml._pairwise_sq_dist 用 ‖a‖²+‖b‖²-2a·b 展开,同点自距离出现灾难性抵消而变成正数;multiobjective.crowding_distance 在退化目标上把并列点误标边界 inf;_parse_box / _parse_bounds 的一维简写 (lo, hi) 绕过全部校验((5, 3)、(nan, 5) 都当合法盒);mann_whitney_u 两个单侧尾共用同一个连续性修正量;rank_sum_ratio 文档写「并列取平均秩」而实现用竞赛名次;_spearman 声称支持并列却直接对原值做 Pearson;benchmark_functions 的最优值自测只在 dim=3 点测、容差又用相对口径(在 schwefel 处宽到 4.2e-7,而实测偏差仅 4.5e-13),断言近乎不设防且 bm_opt_dev 会被误当成上界——本版改为绝对容差 1e-9 · dim 并扫遍 dim=2..6 全部 35 个组合。
低危与其他 rank_consensus 复杂度、ml.confusion_matrix / roc_auc / decision_tree_fit、multiobjective.knee_points 的 scores 下标对齐、tsp_two_opt 文档、ant_colony_tsp 单城市路径 history 长度,以及若干文档/自测守卫口径问题。同时纠正一批「声明与实现不符」(不改变任何数值)。
heuristics 有 1 处故意不修:tabu 在既有测试权重下的最优回路长度牵动黄金键,按"黄金基线冻结"的验收规则保留,改法与影响已写在模块注释里,留待下一次大版本。
文档
README.md新增**「提示词模板」板块**:T0–T8 共 9 个可直接套用的实战提示词样例(从开局赛题解读、模型选型与算法落地、数据清洗与检验,到论文写作自检与评委视角挑刺),每个都写清适用场景、可直接粘贴的正文与预期产出。references/algorithm-details.md按__all__顺序补齐 38 个函数的六段式条目(数学形式 / 步骤 / 复杂度 / 参数 / 陷阱 / 怎么检验),条目里的"怎么检验"都给出可独立复算的对拍方案。references/algorithm-implementations.md分族速查表随新增函数扩写。- 工程修复:
examples/run_algorithms.py --update-golden补newline="\n",Windows 上重建基线不再把整个 JSON 写成 CRLF。
验证
python examples/run_algorithms.py:17 个模块 / 1361 个断言键,失败 0 个模块;每个模块跑两遍结果逐位一致,黄金值比对rtol=atol=1e-09。- 每个模块都有模块外的独立参照:
scipy.stats(非参数检验、分布尾概率、Spearman/PPF)、sklearn(PCA、PR 曲线、树/森林)、statsmodels(Newey-West、logit 插补)、networkx(最短路、负环、拓扑序)、fractions.Fraction(精确有理参照)等;数值本身另有手算闭式解或文献常数对拍。 - CI:
validate_skill.py . --strict、check_paper.py --self-test、install_skill.py --self-test、导入白名单 AST 扫描、反向路径扫描、check_palette.py --quiet、make_figures.py --self-test、LaTeX 模板编译检查。
诚实的边界
- 「黄金值零漂移」只证明以后的改动不会悄悄改变结果,不证明数值本身正确;正确性由那些独立断言负责。
- 实现是教学透明版:优先可读、可手算复核与零重依赖,不与生产级数值库比性能。
ml模块有 12 个公开函数(random_forest_*/gradient_boosting_*/gaussian_nb_*/lda_*/permutation_importance/class_weight_balanced/decision_tree_predict)缺少仓库外的交叉核对,仅由不变量与手算小例覆盖。impute_mice默认max_iter=10, tol=1e-6在多数数据上会如实返回converged=False,这是收敛状态的诚实报告而非静默错误。- 博弈论部分仍有已知缺口:
iterated_elimination不做混合策略占优、ess_check的|B|>14分支未端到端跑过、correlated_equilibrium_lp.n_constraints未经独立核对、退化 Nash 均衡集不完整。
安装
对助手说一句话即可(详见 INSTALL.md):
把 https://raw.githubusercontent.com/anticipate218/math-modeling-skill/main/INSTALL.md 读一下,然后按里面的说明把 math-modeling-skill 装好。
或直接下载下方的 math-modeling-skill-v1.11.0.zip 解压到你的技能目录。四个 LaTeX 模板压缩包供手动下载使用。
完整变更:见 CHANGELOG.md。
math-modeling-skill v1.10.0
v1.10.0
一句话
新增第四套完整文档类模板:2026 华为杯「严格格式版」full/hwcup2026/。 现有的国赛 / 研赛 / 美赛三套模板一个字节都没动,full/gmcm/ 那 43.7 MiB 随包字体也原封不动——华为杯现在两套并存,按需取用。
为什么会有这一套
full/gmcm/ 是通用的华为杯模板:字号、页边距、页眉页脚都按往届通行的做法排,好处是灵活、能套各种论文结构。但每年官方会随赛题发一份 Word 附件模板(2026 年那份在「附件 3」),把封面、编号、摘要页、页边距、章节字号全部钉死。用通用模板去套,格式上总有几处对不上,而研赛对格式的判罚是机械执行的。
full/hwcup2026/ 就是把那份附件逐项复刻成 LaTeX:
\LoadClass[UTF8,zihao=-4,a4paper,fontset=none]{ctexart},XeLaTeX 专用(非 XeTeX 会直接\ClassError报错,而不是编出一份错的 PDF);- 页边距
top=30.02mm, bottom=18.49mm, left=22.51mm, right=22.47mm——不是整数毫米,因为照抄的是 Word 里那些 twip 换算出来的值; - 封面和摘要页的标题排版直接以图片形式固定。原因很直接:官方那几块是 Word 艺术字 / 特定字体的固定版式,任何「用字体凑」的做法在不同机器上都会漂,索性用官方原件截图,所见即所得;
- 页脚是居中的阿拉伯数字页码(
fancypagestyle{hwmain}),无页眉; - 章节标题居中、四号黑体(
\titleformat{\section}{\centering\hwhei\zihao{4}}); - 提供
hwabstract(摘要环境)与notation(符号说明)两个环境,\makehwcover出封面; - 参考文献用内联
thebibliography,不依赖 bibtex——和另外三套一致,编译就是「引擎跑三遍」。
⚠️ 这套不是官方模板。 它是本仓库作者对官方 Word 附件版式的手工复刻,官方从未发布过 LaTeX 版本。请以当年官方下发的原文件为最终依据。
华为杯两套怎么选
| 你的情况 | 用哪套 |
|---|---|
| 想严格贴官方附件 3 的版式,不在意模板是否可改 | full/hwcup2026/ |
| 想按自己习惯调版面,或要复用往届结构 | full/gmcm/ |
| 就想交一份格式不出错的 | 两套都能过;hwcup2026 更省心 |
hwcup2026 不随包字体(所以只有约 1.1 MB);gmcm 随包 5 个 .ttf(约 43.7 MiB),所以体积差两个数量级,这是预期的。
字体:两套模板的回落目标不是一回事
这是本版最容易踩的坑,CI 里现在有专门的断言守着:
| 模板 | 首选字体 | 回落目标 | 需要装的系统字体 |
|---|---|---|---|
hwcup2026 |
SimSun / SimHei / Times New Roman | Noto Serif CJK SC / Noto Sans CJK SC / Liberation Serif | fonts-noto-cjk + fonts-liberation |
gmcm / cumcm |
随包 .ttf / fandol |
fandol + TeX Gyre | 无(随包或 TeX Live 自带) |
hwcup2026.cls 里用 \IfFontExistsTF{SimSun} / \IfFontExistsTF{Times New Roman} 做探测:Windows 上直接命中系统字体,Linux 上回落到 Noto CJK 与 Liberation。两族字体名字完全不同,所以 CI 的 Ubuntu 作业里新增了 fonts-noto-cjk、fonts-liberation 两个包,并在 kpsewhich 预检后面加了三条 fc-list 断言——少一个家族,CI 直接红。
验证记录
本版在 Windows + MiKTeX 25.12 上对四套模板做了真编译(xelatex ×3,美赛 pdflatex ×3),并额外模拟了「无 Windows 字体」的 Linux 环境:
| 模板 | 原样编译 | 模拟无 Windows 字体 | 页数 | Overfull/Underfull |
|---|---|---|---|---|
hwcup2026 |
662 371 B | 652 715 B | 3 | 0 / 0 |
gmcm |
395 954 B | 391 121 B | 8 | 1 / 1(既有,见下) |
cumcm |
452 166 B | 538 968 B | 12 | 1 / 0(既有) |
mcm |
279 394 B | 不适用(纯英文) | 11 | 0 / 1(既有) |
hwcup2026 唯一的警告是 LaTeX Warning: You have requested release '2026/06/01' of LaTeX(TeX Live 版本比要求的新,无害)。CI 上因发行版差异,PDF 字节数与本地不同属正常,判据是页数与体积容差。
本版资产
| 文件 | 大小(字节) | SHA-256 |
|---|---|---|
math-modeling-skill-v1.10.0.zip |
31 246 859 | 77268b2da2d23c4fec3eac81a76b6bfb13acae6cf5497096fb339fe29effccf8 |
hwcup2026-template.zip |
1 145 850 | 9cc250eec302ff6a411badeb23398e39f3c91e7a2b99946ab52ed52052d86b0f |
gmcm-template.zip |
25 688 648 | 209f94c6b0625081b29d1ce5aaeef63f42b1340363832fddddba37e52ff0d4c7 |
cumcm-template.zip |
841 300 | 752e03d4e2f804e1e885223b5267b3bc128db5181f5c0b14d813040a1e1382d5 |
mcm-template.zip |
602 952 | fa568cf1ca53426e02f8d3d4c0ace29d7c19629ce207d14a96bc814e43aea784 |
源码层面的差异只有 mcm/README.md 一处(把「唯一有自由许可的模板」这个说法写准)。gmcm-template.zip 与 cumcm-template.zip 的内容与 v1.9.1 完全一致,但 sha256 仍然不同——--mtime 跟着提交时间走,这是刻意的(保证出包可重现)。
SHA-256 同样不写进仓库里的任何追踪文件:写了就成自引用,提交一变哈希即失效。只放在本页。
⚠️ hwcup2026-template.zip里的 5 张assets/*.png是官方附件 3 版式的渲染件,版权归竞赛主办方所有,不在本仓库 MIT 授权范围内;和研赛随包的那 5 个商用.ttf是同一种情况。
四套模板的溯源与授权(只陈述来源)
| 模板 | 来源 | 许可证情况 |
|---|---|---|
华为杯 2026 hwcup2026 |
本仓库作者自己构建:对 2026 年官方附件 3 Word 模板的严格复刻(官方未发布过 LaTeX 版) | 代码部分随本仓库 MIT;封面/摘要的 5 张 PNG 为官方版式渲染件,版权归主办方,不在 MIT 范围内 |
华为杯(研赛)gmcm |
本仓库作者自己构建(参考谱系 springli07/GMCM_LaTeX_overleaf → zhanwen/MathModel) |
两处参考上游均未附 LICENSE;随包 5 个 .ttf 为商用字体,不在 MIT 范围内 |
国赛 cumcm |
latexstudio/CUMCMThesis @ 38d1f21,文档类 cumcmthesis.cls v2.9 |
上游无 LICENSE,未收录 CTAN |
美赛 mcm |
latexstudio-org/mcmthesis @ 8ac05e2,文档类 mcmthesis.cls v6.3.3 |
LPPL 1.3c or later |
美赛是 LPPL,因此随包保留了 mcmthesis.dtx / mcmthesis.ins(LPPL 要求分发以「原始源文件同属一份分发」为前提)。美赛模板本身未作任何改动。
校验
| 项目 | 结果 |
|---|---|
| CI(本版提交) | check + latex 两个作业全绿 |
真编译(check_latex_full.py --require) |
7/7 通过(四套模板 × 原样/模拟) |
ZIP 条目 vs git cat-file blob |
技能包 134/134 相同,CRLF 转换 0 个 |
| 出包可重现性 | 连编两次字节完全相同 |
check_latex_full.py --self-test |
29/29 通过(新增 3 条:模板表覆盖 full/ 全部目录、模拟字体族分两类的断言、\IfFontExistsTF{SimSun.ttf} 不被误伤) |
validate_skill.py . --strict |
0 错误 / 0 警告 |
install_skill.py --self-test / --from-zip / --into |
25/25 / 装上并 validate_skill --strict 通过 / 技能根自动补层正确 |
check_paper / check_latex / run_algorithms 自检 |
3 套骨架 FAIL=0 / 26/26 / 17 模块 875 键 0 失败 |
已知的无害警告(沿用,未修)
gmcmthesis.cls:\ClassError{mcmthesis}类名写错(不影响编译);\newif\if@gmcm@preface缺\fi。gmcm1 个 Overfull + 1 个 Underfull hbox;cumcm1 个 Overfull hbox +multiply-defined labels;mcm1 个 Underfull hbox。均为既有上游问题。
要更新吗
- 只要新模板:直接下
hwcup2026-template.zip,解压cd hwcup2026 && xelatex main.tex(跑三遍)。 - 只想刷新技能包:下
math-modeling-skill-v1.10.0.zip,或git pull后重跑python scripts/install_skill.py --target auto --force。 - 已经在用
full/gmcm/的:不用换。 两套并存,gmcm没动。
完整改动见 CHANGELOG.md;
四套模板怎么选、怎么在 Overleaf 上跑、Ubuntu 依赖怎么装,见 assets/latex/full/README.md。
math-modeling-skill v1.9.1
v1.9.1
一句话
纯补丁版:模板源码一个字节都没改。 修掉 v1.9.0 发布后才暴露的两个问题——CI 在 Ubuntu 上编译不过(两轮才修完),以及 v1.9.0 打出的 ZIP 有 97/125 个文本条目被换行符转换污染。已经在用 1.9.0 的人不更新也不影响使用。
为什么会有这个版本
v1.9.0 的 Release 发出去之后,CI 才在 Ubuntu 上跑到 latex 任务,红了。查下来两批原因,一批比一批深:
| 轮次 | 报错 | 真因 | 修法 |
|---|---|---|---|
| 第一轮 | ! LaTeX Error: File 'ulem.sty' not found. / 'berasans.sty' not found. |
Ubuntu 的 TeX Live 是按 Debian 包切分的,texlive-latex-extra 并不含这两个文件 |
补 texlive-plain-generic、texlive-fonts-extra、fonts-texgyre,并加 kpsewhich 预检 |
| 第二轮 | ! Font TS1/ntxtlf/m/n/12=ts1-qtmr at 12.0pt not loadable: Metric (TFM) file not found (只有美赛 pdflatex 挂) |
newtxtext 把 TS1 编码映射到 TeX Gyre Termes 的度量(TFM)文件,而 fonts-texgyre 装的是 OTF 字体,不含 TFM |
补 tex-gyre |
第二轮这个坑值得单说:fonts-texgyre 和 tex-gyre 是两个毫不相干的 Debian 包。前者给 /usr/share/fonts/ 下的 .otf;后者给 /usr/share/texmf/fonts/tfm/public/tex-gyre/ 下的 .tfm。装了前者最容易让人以为字体齐了,实际 pdflatex 到 ts1-qtmr 就断。
这五条包名不是猜的,是反查出来的:把 Ubuntu noble 的 dists/noble/Contents-amd64.gz(51 301 092 B)下下来,按文件名反查归属包:
| 缺的文件 | 归属包 | 备注 |
|---|---|---|
ulem.sty |
texlive-plain-generic |
TDS 路径在 tex/generic/,所以不在 latex-extra |
berasans.sty |
texlive-fonts-extra |
|
newtxtext.sty |
texlive-fonts-extra |
|
texgyretermes-regular.otf |
fonts-texgyre |
OTF |
ts1-qtmr.tfm |
tex-gyre |
TFM,全索引仅 1 处命中,确认无 texlive-* 包携带 |
lmodern.sty |
lmodern |
CI 的 <!-- 漏了就红 --> 注释里现在逐条写着这五条映射,kpsewhich 预检清单也扩到 6 个文件名。再少一个,CI 立刻红给你看,不会再等到用户那边才发现。
第二个修复:ZIP 是「从 git blob 出的包」
v1.9.0 的 ZIP 里,125 个跟踪文件中有 97 个被写成了 CRLF——本机 core.autocrlf=true,git archive 老老实实按这个设置做了换行转换,而 blob 里存的是 LF。
这不是"看起来一样"的问题:validate_skill.py 之类的脚本、以及任何做哈希比对的安装链路都会对不上。
本版出包时显式关掉:
git -c core.autocrlf=false -c core.eol=lf archive --format=zip --prefix=<name>/ --mtime=<HEAD 提交时间> HEAD:assets/latex/full/<name>顺手还发现并消掉了另一个不确定性:git archive --format=zip 不传 --mtime 时会用墙上时钟给每个条目盖时间戳(实测两次构建相隔 3 秒,ZIP 里有 72 个字节不同)。现在时间戳固定成 HEAD 的提交时间,连编两次字节完全相同。
出包脚本现在会断言三件事,任一不成立就直接失败:
- ZIP 条目清单 ==
git ls-tree -r HEAD:<dir>; - 每一个条目都与
git cat-file取出的 blob 逐字节相同; - 连编两次结果字节一致。
顺带解释一个会让人困惑的现象:v1.9.1 的三个模板 ZIP 和 v1.9.0 的 sha256 必然不同,哪怕模板源码没改——因为 --mtime 跟着提交时间走,而且 v1.9.0 那份本来就被换行符污染了。源码层面的差异只有 gmcm/README.md 和 cumcm/README.md 两个文件,且都是这次的文档修正。
也因此,SHA-256 故意不写进仓库里的任何文件:写了就等于自己引用自己,提交一变哈希就失效。校验值只放在本 Release 页上。
还改了两处「说得太满」的说法
- 原文写编译产物 PDF "与样张逐字节相同"。复核后:
gmcm/mcm确实逐字节相同;cumcm前 444 862 字节相同,末尾的元数据对象流差 1 字节(/Length 3866vs3867,XMP/Info 元数据)。已在文档里写明。 - README 里的 Release 链接原本钉死版本号,改成
latest,不然每次发版都得改一次文档。
本版资产
| 文件 | 大小(字节) | SHA-256 |
|---|---|---|
math-modeling-skill-v1.9.1.zip |
30 090 644 | 707398b78e6f48a38edce4dca3c10d93ffd1bf558e2697ec3395136e78b7f44a |
gmcm-template.zip |
25 688 648 | 11d719a54bc3f7f18107ff7d05d6a1fd15f0ed20ad05e1b7d7dd3c9f19f32156 |
cumcm-template.zip |
841 300 | e2586710efd1901a7673e559f80a9d30600cd92a3206a714c51ef94ed72eff63 |
mcm-template.zip |
602 926 | cf1221532d0ea4ed550045dd2a2f2643a64cc740d09c6ac12142952f63db1097 |
三个模板 ZIP 的哈希与 v1.9.0 那份不同是预期的(原因见上)。gmcm-template.zip 之所以大,是因为里面带了 5 个 .ttf(约 43.7 MiB 未压缩)。
三套模板的溯源与授权(只陈述来源)
| 模板 | 来源 | 许可证情况 |
|---|---|---|
华为杯(研赛)gmcm |
本仓库作者自己构建(参考谱系 springli07/GMCM_LaTeX_overleaf → zhanwen/MathModel) |
两处参考上游均未附 LICENSE |
国赛 cumcm |
latexstudio/CUMCMThesis @ 38d1f21,文档类 cumcmthesis.cls v2.9 |
上游无 LICENSE,未收录 CTAN |
美赛 mcm |
latexstudio-org/mcmthesis @ 8ac05e2,文档类 mcmthesis.cls v6.3.3 |
LPPL 1.3c or later |
美赛是 LPPL,因此随包保留了 mcmthesis.dtx / mcmthesis.ins(LPPL 要求分发以"原始源文件同属一份分发"为前提)。美赛模板本身未作任何改动。
研赛随包的 5 个 .ttf(SimSun / SimHei / KaiTi / LiSu / STXinwei)是中易 / 华文的商用字体,不在本仓库 MIT 授权范围内,仅为字形与 Word 一致而附带;删掉即可,\IfFontExistsTF 会回落到 fandol 继续编过。
校验
| 项目 | 结果 |
|---|---|
| CI(本版提交) | check + latex 两个作业全绿 |
ZIP 条目 vs git cat-file blob |
技能包 125/125 相同,CRLF 转换 0 个 |
| 出包可重现性 | 连编两次字节完全相同 |
install_skill.py --self-test / --from-zip / --into |
25/25 / 装上并 validate_skill --strict 通过 |
validate_skill.py . --strict |
0 错误 / 0 警告 |
check_latex_full.py --require(真编译) |
5/5 通过 |
check_paper / check_latex / run_algorithms 自检 |
26/26 / 26/26 / 17 模块 875 键 0 失败 |
要更新吗
模板内容完全没变,只动了文档、CI 配置和出包方式。
- 只想拿模板:不用更新,直接下
gmcm-template.zip/cumcm-template.zip/mcm-template.zip。 - 想刷新技能包:下
math-modeling-skill-v1.9.1.zip,或git pull后重跑python scripts/install_skill.py --target auto --force。
完整改动见 CHANGELOG.md;
模板怎么选、怎么在 Overleaf 上跑见 assets/latex/full/README.md。
math-modeling-skill v1.9.0
一句话
把三套竞赛的原版文档类模板整套收进技能包,改掉两处「没装 Windows 字体就编不过」的字体加载——现在华为杯(研赛)/ 国赛 / 美赛的官方 LaTeX 模板在 Overleaf 和 Linux 上也能直接编,不用再自己配字体。三套模板的 ZIP 随本 Release 一起发布。
装什么,用什么
技能包现在是两层,用途不同:
| 层 | 位置 | 干什么用 |
|---|---|---|
| 轻量自包含版 | assets/latex/{cumcm,yjs,mcm}/main.tex |
自写的入口文件,用来跑 check_latex.py 的合规自检(页数、AI 声明、盲审匿名) |
| 完整文档类版(新) | assets/latex/full/{gmcm,cumcm,mcm}/ |
原版 *.cls 全套,直接拿来写论文、直接交 |
完整版三套:
| 赛事 | 目录 | 主文件 | 引擎 |
|---|---|---|---|
| 华为杯(研赛) | full/gmcm/ |
MathModel.tex |
XeLaTeX |
| 国赛(CUMCM) | full/cumcm/ |
example.tex |
XeLaTeX |
| 美赛(MCM/ICM) | full/mcm/ |
mcmthesis-demo.tex |
pdfLaTeX |
注意:三套都是「引擎跑 3 遍」,不需要 bibtex。 参考文献是内联 thebibliography。
为什么要改上游的字体加载
模板原样在「Windows + Word 字体齐备」的机器上没问题,换到 Overleaf / Linux / macOS 会直接失败:
-
gmcmthesis.cls(研赛):上游写\ifx\lishu\undefined \setCJKfamilyfont{zhli}{LiSu.ttf} ... \fi。可ctex宏包早就定义过\lishu,这个条件永远不成立,随包的LiSu.ttf从未被注册——编译到封面「摘 要」那一行必然:! Package fontspec Error: The font "LiSu" cannot be found已改成「先
\providecommand*兜底、再\renewcommand*绑到随包字体」,\xinwei同样处理。 -
gmcmthesis.cls/cumcmthesis.cls:\setmainfont{Times New Roman}这类调用是无条件的,缺字体就报错。改成\IfFontExistsTF{...}:有就用,没有回落到 TeX Gyre Termes / Heros / Cursor——Times / Arial / Courier 的度量兼容开源克隆,随 TeX Live 与 MiKTeX 分发,任何平台都有。
除此之外没有别的改动。 example.tex、mcmthesis-demo.tex、mcmthesis.dtx、cumcm2026.sty、figures/* 都与上游逐字节一致;美赛模板完全未改。
真机编译结果(Windows + MiKTeX 25.12,引擎各跑 3 遍)
| 模板 | 引擎 | 原样(随包字体 / 系统 Windows 字体) | 模拟无 Windows 字体 |
|---|---|---|---|
gmcm |
xelatex |
8 页 / 395 954 B | 8 页 / 391 121 B |
cumcm |
xelatex |
12 页 / 452 166 B | 12 页 / 538 970 B |
mcm |
pdflatex |
11 页 / 279 394 B | 不适用(不含中文) |
5/5 通过:每次退出码 0、0 条硬错误、0 个缺字形、0 处未解析引用。两列页数完全一致——换字体只改字形与嵌入体积,不改分页。
「模拟无 Windows 字体」不是碰运气:脚本把临时副本的 ctex 字体集钉成 fandol、把探测的字体名换成一定不存在的名字、并删掉随包 .ttf,所以在任何平台上这一遍走的都是真实的回落分支。顺带一个佐证:cumcm 两列体积差 86 804 B,正是 TeX Gyre 替掉 Times New Roman / Arial 后嵌入字体变大的量。
字体:研赛随包带 5 个 .ttf(约 44 MB)
full/gmcm/ 带 SimSun.ttf / SimHei.ttf / KaiTi.ttf / LiSu.ttf / STXinwei.ttf,目的是让字形和 Word 里看到的完全一致。
- 可以删掉,删了照样编得过——
\IfFontExistsTF会检测到文件不在,自动回落到ctex字体集(Windows 用系统字体,Linux / Overleaf 用自由的fandol),只是字形变了。 ⚠️ 但千万别把它们挪进fonts/子目录。文档类是按裸文件名引用的,挪走后fontspec只警告不报错,整篇中文被悄悄排成西文字体(实测丢 1503 个字形),而编译照样退出码 0、PDF 照样 8 页——极其隐蔽。留在原地,或者直接删掉。
授权提示:这 5 个是中易 / 华文的商用字体,不是自由字体。随包携带只为让你零配置编译。要再分发或商用请自行确认授权,或删掉改用
fandol。
三套模板的溯源与授权
| 模板 | 上游 | 许可证 |
|---|---|---|
gmcm |
本仓库作者自制(参考谱系 springli07/GMCM_LaTeX_overleaf → zhanwen/MathModel) |
上游均未附 LICENSE |
cumcm |
latexstudio/CUMCMThesis @ 38d1f21 |
上游无 LICENSE、未收录 CTAN |
mcm |
latexstudio-org/mcmthesis @ 8ac05e2 |
LPPL 1.3c or later |
美赛是 LPPL,所以随包保留了 mcmthesis.dtx(LPPL 要求分发以「原始源文件属于同一分发」为前提);要定制请另存为别的文件名。逐套详情见 assets/latex/full/THIRD-PARTY.md。
新增 scripts/check_latex_full.py(544 行,仅标准库)
python scripts/check_latex_full.py # 编全部:模板 ×(原样 + 无 Windows 字体)
python scripts/check_latex_full.py --only gmcm # 只编研赛
python scripts/check_latex_full.py --no-simulate # 只按原样编
python scripts/check_latex_full.py --keep # 保留临时目录,方便翻 .log / .pdf
python scripts/check_latex_full.py --self-test # 不需要装 TeX,只测改写逻辑它把整个模板目录拷到系统临时目录再编译(不在仓库内产生 .aux/.log/.pdf),并先删掉预编译的样张 PDF——否则编译失败时旧 PDF 还在,体检就被骗过去了。然后核对硬错误、未解析引用、Font "…" cannot be found、页数下限,以及 cumcm / mcm 的「AI 声明 vs 参考文献」顺序合规。--require = 没装引擎就报错退出,不允许静默跳过。
CI 的 latex 任务加了两步:先跑 --self-test(不依赖 TeX),装好 TeX Live 后再跑 --require。Ubuntu 上没有 Windows 字体,那一遍天然就是回落路径。
修了一个会被这三个新 ZIP 触发的坑(install_skill.py,1089 → 1164 行)
原来 --download 取 releases/latest 里的第一个 .zip。这个 Release 要挂 gmcm-template.zip / cumcm-template.zip / mcm-template.zip,谁排在前面谁就会劫持 --download——用户想装技能,结果装进来一个模板。
新增 pick_release_asset():只认文件名以 math-modeling-skill 开头的 ZIP;一个都不匹配时列出实际资产名并提示改用 --from-zip,绝不瞎猜。自检 21 → 25 项。
换句话说:Release 页上那几个
*-template.zip是给人手动下载的,--download不会碰它们。
校验
| 项目 | 结果 |
|---|---|
validate_skill.py . --strict |
0 错误 / 0 警告 |
check_latex_full.py --require |
5/5 通过(真编译,含无 Windows 字体回落路径) |
check_latex_full.py --self-test |
26/26 通过(不需要 TeX) |
install_skill.py --self-test |
25/25 通过 |
check_latex.py --self-test / download_templates.py --self-test |
26/26 / 26/26 |
check_paper.py --self-test / check_palette.py --quiet |
全过 / 通过 |
run_algorithms.py |
17 模块 / 875 断言键 / 0 失败 |
| ZIP 条目集合 vs git 跟踪集合 | 0 缺 0 多;.ttf 与 git blob 逐字节一致 |
CI(check + latex) |
全绿 |
下载
- 技能包:
math-modeling-skill-v1.9.0.zip(下面的 Assets 里,用它配--from-zip) - 三套模板单独下载:
gmcm-template.zip/cumcm-template.zip/mcm-template.zip - 一句话安装见 README;面向助手的安装流程见 INSTALL.md
- 模板怎么选、怎么用、怎么在 Overleaf 上跑:
assets/latex/full/README.md
完整改动见 CHANGELOG.md。
math-modeling-skill v1.8.3
一句话
--download(安装脚本里唯一联网的动作)以前是一次性请求,遇到 GitHub 的偶发 TLS 断流就整条命令失败;现在它会自动退避重试 4 次,并把"连上了但传到一半断掉"也算进去——因为那才是实测里最常见的那种失败。
怎么发现的
不是猜的。发布 v1.8.2 之后我用 --download 做端到端复验,现场撞上:
错误:下载 math-modeling-skill-v1.8.2.zip 失败:
<urlopen error [SSL: UNEXPECTED_EOF_WHILE_READING] EOF occurred in violation of protocol>
留下一个空目录。而报错给的出路是"改用 --from-zip"——可用户选 --download,恰恰是因为手上没有包。
修了什么
--download全流程重试:查releases/latest与下载 ZIP 两步都带指数退避(4 次,退避 1.5s / 3s / 6s),重试时打印…第 2/4 次尝试(1.5s 后重试,上次失败:…),让你看得见它在自救。- 重试的是整个下载动作(连接 + 读响应体 + 写文件),不只是建立连接;写盘用覆盖模式,不会把两次的部分内容拼成坏 ZIP。另有 0 字节兜底检查。
- 失败信息给两条出路:① 这是网络问题,原样重跑一次通常就好;② 到 Releases 页手工下载 ZIP,再用
--from-zip。
真机验证
| 项目 | 结果 |
|---|---|
| 修复前 | [SSL: UNEXPECTED_EOF_WHILE_READING],目标目录为空 |
| 修复后 | 同一条命令下载 2,915,975 字节(与 v1.8.2 资产字节数一致),装完 validate_skill.py --strict 通过,读出的 metadata.version 是 1.8.2 |
顺带
--self-test由 18 项扩到 21 项:新增「联网动作重试后成功」(注入假 opener/假 sleeper,断言退避时长正是 1.5s / 3s)、「一直失败时报可执行的错」、「重试次数必须为正」——全程不联网、不碰真实技能目录。--from-zip示例里的版本号不再写死(v1.8.0→vX.Y.Z),免得每次发版都变成过期示例。
校验
| 项目 | 结果 |
|---|---|
validate_skill.py --strict |
0 错误 / 0 警告 |
install_skill.py --self-test |
21/21 通过 |
check_paper.py --self-test / check_latex.py --self-test |
全过 / 26 项全过 |
run_algorithms.py |
17 模块 / 875 断言键 / 0 失败 |
check_palette.py --quiet / make_figures.py --self-test |
全部达标 / 退出码 0 |
CI(check + latex) |
全绿 |
| ZIP 条目集合 vs git 跟踪集合 | 84 文件,0 缺 0 多 |
配套文档:一句话安装说明见 README;面向助手的安装流程见 INSTALL.md。
完整改动见 CHANGELOG.md。
math-modeling-skill v1.8.2
一句话
没有任何运行时代码变化——scripts/、references/、examples/、templates/ 与 v1.8.1 逐字节相同(scripts/install_skill.py 的 SHA-256 两版一致)。本版只是把 main、标签、Release 资产重新对齐到一个 CI 两个任务全绿的提交上。
为什么会有这一版
v1.8.1 的 Release 资产是在提交 3426e28 上打的,而那次推送的 CI 是红的——红的原因不在代码、也不在文档里的路径,而是我在 CHANGELOG 的验证记录里逐字抄了「Windows 风格路径」检查用的那条正则:判据文本本身命中了判据(受管目录名后面紧跟一个反斜杠),文档把自己举报了。修法记录在 1.8.1 的 CHANGELOG 末尾「一条自曝」里。
f5e8468 改掉措辞、并在 ci.yml 里加了注释提醒别再逐字引用;CI 随即全绿。本版在它之上只动版本号与 CHANGELOG。
没有为了让 CI 变绿而放宽检查:判据、扫描范围(全部 *.md)、失败行为全部原样。
已经装了 1.8.1?不用重装
技能内容与 1.8.2 完全一致。想严格对齐 Release 包的话,覆盖一次即可:
python scripts/install_skill.py --force --target auto本版包含的安装器行为(与 1.8.1 相同)
--into给技能根(如~/.agents/skills)时自动补一层math-modeling-skill,不再把技能平铺进技能根;--into指向别人的技能目录时直接拒绝,一个字节都不写;- 自校验失败时给出最常见原因(技能目录名不是
math-modeling-skill); SKILL.md带 UTF-8 BOM 时也能正确识别,--force不再莫名失效。
校验
| 项目 | 结果 |
|---|---|
validate_skill.py --strict |
0 错误 / 0 警告 |
install_skill.py --self-test |
18/18 通过 |
check_paper.py --self-test / check_latex.py --self-test |
全过 / 26 项全过 |
run_algorithms.py |
17 模块 / 875 断言键 / 0 失败 |
check_palette.py --quiet / make_figures.py --self-test |
全部达标 / 退出码 0 |
CI(check + latex) |
全绿 |
| ZIP 条目集合 vs git 跟踪集合 | 84 文件,0 缺 0 多 |
配套文档:一句话安装说明见 README;面向助手的安装流程见 INSTALL.md。
完整改动见 CHANGELOG.md。
math-modeling-skill v1.8.1
math-modeling-skill v1.8.1
一句话就能装。 把这句话发给你正在用的 AI 助手,它会自己下载、找到技能目录、装好,再向你汇报:
请阅读并按 https://raw.githubusercontent.com/anticipate218/math-modeling-skill/main/INSTALL.md 的说明,把
math-modeling-skill这个技能安装到我当前使用的助手环境里;装完告诉我装到了哪个路径、是哪个版本、以及怎么开始用。
English:
Read and follow https://raw.githubusercontent.com/anticipate218/math-modeling-skill/main/INSTALL.md to install the
math-modeling-skillagent skill into the environment I'm using. When done, tell me the install path, the version, and how to start using it.
不想用助手也行——下载本页的 math-modeling-skill-v1.8.1.zip,解压后把里面的 math-modeling-skill 整个文件夹放进你的技能目录(目录名不要改)。各宿主技能目录与更多装法见 README 的「下载与安装」。
本版修了什么
v1.8.0 上线后我实机复验安装器,踩到一个自己挖的坑:
--into 给"技能根"时会把技能平铺进去。 旧行为是"原样使用、不追加技能名",而用户(或助手)很自然会写成 --into ~/.agents/skills——于是 SKILL.md、references/、scripts/ 等二十多个条目被直接倒进技能根。宿主按 <技能根>/<name>/SKILL.md 扫描,结果是扫不到;技能根还被污染。更糟的是随后那条自校验只说"技能可能不完整",把真实原因(目录名不是 math-modeling-skill)藏住了。
现在:
--into两种写法都对。 给技能根 → 自动补一层math-modeling-skill;给技能目录本身 → 原样使用。动手前会把真实安装路径打印出来。- 指向别人的技能目录时直接拒绝。 那个目录里若已有
SKILL.md且name不是本技能,复制前报错并给出正确写法,一个字节都不写。 - 自校验失败说人话。 补上最常见的原因:目录名不是
math-modeling-skill。 - 顺手修掉一个会让
--force莫名失效的隐患:UTF-8 BOM。 Windows 记事本/部分 IDE 会给文件加 BOM,带着 BOM 时 frontmatter 整块读不出来,安装器会把你自己的旧安装误判成"别人的技能",于是更新时被安全闸门拒之门外。现在解析前先剥 BOM。
变更清单
| 文件 | 变化 |
|---|---|
scripts/install_skill.py |
860 → 962 行;新增 resolve_into();read_frontmatter() 增加 BOM 容错;提示语与 --help 同步 |
--self-test |
13 → 18 项(新增 --into 四种情形 + BOM 识别) |
INSTALL.md |
第 2C 节改为"两种写法都对",新增常见问题「校验报 name…必须与技能目录名…一致」 |
README.md |
第 3 节补 --into 说明与示例,第 7 节自检期望值改 18/18,「质量保障」表同步 |
本版验证记录
| 项目 | 方式 | 结果 |
|---|---|---|
| 安装器固件测试 | install_skill.py --self-test |
18/18 通过(不联网、不碰真实技能目录) |
--into 给技能根 |
指向一个空目录 | 目标自动变成 <空目录>/math-modeling-skill,校验通过,退出码 0 |
| 覆盖约定 | 同一位置再跑一次 / 加 --force |
第二次拒绝并退出码 1;--force 后覆盖成功 + 校验通过 |
--into 指向别人的技能 |
放入 name: other-skill 的 SKILL.md |
复制前报错、退出码 1,该目录内容未被改动 |
| BOM 容错(端到端) | 给已安装副本的 SKILL.md 加 BOM 再 --force |
正确识别为本技能旧安装并覆盖成功(修复前会被拒绝) |
| 技能结构 | validate_skill.py . --strict |
0 个错误,0 个警告 |
| 算法回归 | examples/run_algorithms.py |
17 个模块 / 875 个断言键,失败 0 |
| 随包自检 | check_paper.py / download_templates.py / check_latex.py / check_palette.py / make_figures.py |
全部通过 |
| 发布包自检 | 用本页 ZIP 走一遍 --from-zip 安装 |
安装成功、结构校验通过、无 .git/ |
| CI | GitHub Actions(check + LaTeX 真编译) | 两个作业全绿 |
怎么升级
# 从仓库升级(推荐)
cd math-modeling-skill && git pull
python scripts/install_skill.py --target auto --force
# 或者用本页的 ZIP
python scripts/install_skill.py --from-zip math-modeling-skill-v1.8.1.zip --target auto --force--force 只会覆盖本技能的旧安装(目标目录里必须有 name: math-modeling-skill 的 SKILL.md),别的目录它一律不动。
已经装了 v1.8.0 的话建议升到本版:v1.8.0 的安装器里还是旧行为。用 v1.8.0 安装器时请把
--into写成<技能根>/math-modeling-skill。
技能遵循 Agent Skills 开放标准:目录名必须与 SKILL.md 里的 name 一致;纯文件、无后台进程、不写注册表。卸载就是删掉那个目录。
math-modeling-skill v1.8.0
这一版只做一件事:把「怎么装」从"用户读说明书、照着敲命令"改成"用户对助手说一句话,助手自己装"。
前几版把内容、算法、模板都补齐了,但安装这一步一直假定用户会读 README、会判断自己的技能根目录在哪、会敲对路径——而这恰恰是最容易劝退、也最容易装错的一环。
一句话安装(本版的主入口)
把下面这句话连同链接一起发给你正在用的 AI 助手,它会自己下载、找到技能目录、装好、再向你汇报:
请阅读并按 https://raw.githubusercontent.com/anticipate218/math-modeling-skill/main/INSTALL.md 的说明,把
math-modeling-skill这个技能安装到我当前使用的助手环境里;装完告诉我装到了哪个路径、是哪个版本、以及怎么开始用。
English:
Read and follow https://raw.githubusercontent.com/anticipate218/math-modeling-skill/main/INSTALL.md to install the
math-modeling-skillagent skill into the environment I'm using. When done, tell me the install path, the version, and how to start using it.
那条 raw 链接现在是 CI 的一部分:INSTALL.md 必须存在、README 里这行链接必须逐字符正确、SKILL.md 必须提到它——链接写错或文件没推上去就会在 CI 红掉。本版发布时实测该链接返回 HTTP 200 / 10,158 字节。
新增
INSTALL.md(277 行)——写给 AI 助手看,不是写给用户看
- 第 1 步:拿到技能包,按"有 shell / 用户已下载 ZIP / 只能读网页"分三种情况。第三种明确不要硬装,改为把话术交给用户。
- 第 2 步:确定技能根目录,给三条路——跑脚本探测(推荐)/ 自己找(查宿主配置、看已有技能的父目录、直接问用户)/
--into精确指定,并列一张只包含可核实路径的宿主-技能目录对照表。 - 第 3 步:安装,脚本安装与纯手工复制(含"记得删
.git/")各一版,Windows/NT 分开。 - 第 4 步:校验,三条独立命令与期望输出,
SKILL.md只有一层、目录名与name必须一致。 - 第 5 步:汇报,规定必须包含五项(装到哪个绝对路径、哪个版本、校验结果、怎么开始用、目录名不要改)。
- 另有「不要做」清单(不要改目录名、不要覆盖别人的技能、不要装进
references/这类子目录、不要为了"验证装好没"去跑算法或下载模板、不要编造宿主路径、不要git clone进技能目录),以及 Troubleshooting / 更新 / 卸载。
scripts/install_skill.py(860 行,纯标准库,非交互)
python scripts/install_skill.py --list-targets # 每个候选根的绝对路径 / 是否已存在 / 已装版本
python scripts/install_skill.py --target auto # 自动挑位置
python scripts/install_skill.py --dry-run # 只看会做什么,不动磁盘
python scripts/install_skill.py --from-zip math-modeling-skill-v1.8.0.zip
python scripts/install_skill.py --download # 拉最新 Release 的 ZIP 再装(唯一联网的动作)
python scripts/install_skill.py --self-test # 13 项固件测试,不联网、不碰真实技能目录--target auto 按 项目级 DSH → 项目级 Agent Skills → 用户级 DSH → 用户级 Agent Skills 取第一个已存在的技能根;都不存在时落到 ~/.agents/skills。
三条安全约定(都有固件测试兜住):
- 默认拒绝覆盖已存在的技能目录;
--force只肯删"确实是本技能"的目录(目标里必须有name: math-modeling-skill的SKILL.md)——这道闸门是防--into手滑指到家目录的;- 复制时丢掉
.git/与各种缓存,装完自动跑包内的validate_skill.py --strict,不通过就报错退出。
变更
README.md(471 → 575 行):「快速开始」第 0 步改为先给中英两版一句话提示词,再给git clone与安装器两条备选;「下载与安装」由 5 小节重排为 9 小节,新增「最省事:一句话让你的 AI 助手自己装」「装到哪里(各宿主的技能目录)」「用自带安装器装(推荐)」「怎么更新、怎么卸载」「装完没生效?按这个顺序查」。「质量保障」表加一行「安装器」,结构树补INSTALL.md与scripts/install_skill.py。- 改掉一条不准确的说明:旧 README 的排查清单写着"③ 宿主是否需要重启或重新扫描"。DSH 会持续监视技能根目录,新增/改名/删除技能在下一个技能目录快照就生效,不需要重启。已按此改写,并把排查扩成单列的一节。
- 不猜路径:README 只列能核实的六个位置(DSH 项目级/用户级、Agent Skills 通用约定的项目级/用户级、Claude Code 项目级/用户级)。Codex、Cursor、Gemini CLI、OpenCode 等的技能目录各不相同,本仓库故意不写死猜测值——猜错的代价是"装成功了但永远不会被扫描",比装不上更难查。
SKILL.md升1.8.0,索引加一行"用户要装/更新/换宿主重装时读INSTALL.md";compatibility把install_skill.py并入"仅用标准库"的脚本清单。CITATION.cff同步1.8.0。- CI 新增两步:
install_skill.py --self-test;以及"安装入口文档存在且被 README 引用"。
本版验证记录
| 项目 | 方式 | 结果 |
|---|---|---|
| 安装器固件测试 | install_skill.py --self-test |
13/13 通过 |
| 真装一遍 | --into <临时目录> / 再装一次 / 加 --force |
首次"安装完成"+ 校验通过;第二次拒绝、退出码 1;--force 后"覆盖完成"+ 校验通过;装出 97 个条目、无 .git/ |
| 从发布包装 | --from-zip |
自动剥掉 math-modeling-skill/ 前缀,装完校验通过 |
| 联网取包 | --download |
查到最新 Release 并下载成功(2,887,266 字节,与附件记录一致) |
| 技能结构 | validate_skill.py . --strict |
0 个错误,0 个警告(30 个文件引用) |
| 全量算法回归 | examples/run_algorithms.py |
17 个模块 / 875 个断言键 / 失败 0 个模块 |
| 其余随包自检 | check_paper / download_templates / check_latex / check_palette / make_figures |
全部通过 |
| 文档路径风格 | 扫全部 23 个 *.md 找反斜杠路径 |
命中 0 |
本版的 ZIP 附件是从提交 bdd272e 用 git archive 打出来的,并且把解压后的副本完整跑了一遍:结构校验、安装器固件测试、模板清单、论文自检、LaTeX 检查逻辑、全量算法回归,再从那个 ZIP 用 --from-zip 真装一次。附件与仓库内容一一对应(84 个文件,缺 0 多 0)。
怎么升级
git pull
python scripts/install_skill.py --target auto --force或者下载本页的 ZIP 附件后:
python scripts/install_skill.py --from-zip math-modeling-skill-v1.8.0.zip --target auto --force--force 只会覆盖本技能的旧安装,别的目录一律不动。
math-modeling-skill v1.7.0
math-modeling-skill v1.7.0
数学建模竞赛全流程技能包 · 算法补全 + 创新手册 + 模板下载 + 安装体验
本版回应四件事:README 里要能查到"LaTeX 模板怎么下载"、算法要做到"每个类别的每个算法都有详细实现"、要讲清"怎么创新、哪些参数可以动"、以及下载之后怎么把这个技能跑起来要顺。前两件是内容缺口(仓库里有模板但不讲怎么拿;算法只覆盖 11 个模块、部分函数只有名字没有细节),第三件是知识缺口,第四件是体验缺口。
这一版做了什么
| 项 | v1.6.0 | v1.7.0 |
|---|---|---|
| 算法模块 | 11 | 17 |
| 公开名称(函数 + 常量) | 97 | 224(函数 222 + 常量 2) |
| 黄金值断言键 | 324 | 875 |
| 逐算法详解文档 | 无 | references/algorithm-details.md(2332 行,223 个条目) |
| 参数创新手册 | 无 | references/innovation-playbook.md(371 行,17 族) |
| LaTeX 模板获取 | 手动复制文件 | scripts/download_templates.py 一条命令 + 可选 zip |
| README 安装指引 | 散在各处 | 「下载与安装」专章(5 小节) |
一、怎么把它装起来(本版重点优化过)
技能遵循 Agent Skills 开放标准:一个目录 + 一个 SKILL.md,目录名必须等于 frontmatter 里的 name(本仓库已满足)。所以安装动作就是"把目录放对地方",没有构建、没有安装器、不联网。
方式 A:下载本页的 Release ZIP(推荐给不想装 git 的人)
本 Release 附带 math-modeling-skill-v1.7.0.zip(2,887,266 字节 ≈ 2.8 MB,含完整技能包 + 三套 LaTeX 模板)。
-
下载并解压,解压出来的顶层目录就叫
math-modeling-skill/——不用改名,这正是宿主需要的目录名。 -
把整个
math-modeling-skill/丢进你的技能根目录(见下表)。 -
核验完整性:解压后在该目录里跑
python scripts/validate_skill.py . --strict期望输出
0 个错误,0 个警告。
方式 B:git clone(推荐给想跟更新的人)
# 通用 Agent Skills 目录(跨工具)
git clone https://github.com/anticipate218/math-modeling-skill.git ~/.agents/skills/math-modeling-skill
# Claude Code
git clone https://github.com/anticipate218/math-modeling-skill.git ~/.claude/skills/math-modeling-skill# DeepSeek Harness —— 用户级(所有项目可用)
git clone https://github.com/anticipate218/math-modeling-skill.git "$env:USERPROFILE/.dsh/skills/math-modeling-skill"
# DeepSeek Harness —— 项目级(只对当前仓库生效)
git clone https://github.com/anticipate218/math-modeling-skill.git .dsh/skills/math-modeling-skill装完的正确形态是 <技能根目录>/math-modeling-skill/SKILL.md 存在。宿主重启或重新扫描技能目录后,用一句中文触发,例如"帮我看看这道数学建模题该怎么建模"。
依赖
| 用途 | 需要什么 |
|---|---|
文档、自检脚本(scripts/、references/、assets/) |
只有 Python 3.9+,纯标准库 |
跑自带算法(examples/algorithms/) |
额外 numpy;不需要 scipy / sklearn / pandas / statsmodels |
| 真编译 LaTeX 模板(可选) | 本机 TeX 发行版(MiKTeX / TeX Live)+ xelatex / pdflatex / bibtex |
拿到 LaTeX 模板(本版新增)
仓库自带三套可直接编译的自包含模板,每套只有 main.tex + refs.bib:
| 竞赛 | 模板目录 | 引擎 | 特点 |
|---|---|---|---|
| 国赛 CUMCM | assets/latex/cumcm/ |
xelatex |
中文;摘要页起排;AI 使用声明排在参考文献之前 |
| 研赛(华为杯) | assets/latex/yjs/ |
xelatex |
中文;摘要页即第 1 页;无承诺书/编号页;禁止页眉 |
| 美赛 MCM/ICM | assets/latex/mcm/ |
pdflatex |
英文;Summary Sheet 独占第 1 页;含 Report on Use of AI |
python scripts/download_templates.py --contest cumcm --out my_paper # 拷出国赛模板
python scripts/download_templates.py --contest all --out papers --zip p.zip # 三套一起,并打包
python scripts/download_templates.py --list # 只看清单会连编译命令和注意事项一起打印给你。目标文件已存在时默认拒绝覆盖(要覆盖加 --force)。中文模板默认写 fontset=windows,脚本在非 Windows 平台会自动改写成 fontset=fandol(Overleaf/Linux 用它),可用 --fontset {auto,keep,fandol} 控制。
二、算法:从"点到为止"补成"逐个交代"
新增 6 个模块(公开名称 +70),原有 11 个模块全部扩写(+57):
| 模块 | 名称数 | 关键内容 |
|---|---|---|
optimization.py |
9 | 单纯形、对偶、整数/0-1 规划、指派、运输、最短路网络流 |
graphs.py |
20 | 最短路、最小生成树、最大流/最小割、二部匹配、着色、PageRank |
heuristics.py |
8 | 模拟退火、遗传、禁忌搜索、粒子群、蚁群、贪心/局部搜索 |
forecasting.py |
19 | 移动平均/指数平滑、回归、灰色、组合预测、误差度量 |
statistics.py |
23 | 描述统计、区间估计、假设检验、方差分析、相关、回归诊断、bootstrap |
evaluation.py |
11 | 熵权、AHP、TOPSIS、灰色关联、模糊综合、秩和比 |
clustering.py |
12 | K-means、层次聚类、DBSCAN、GMM、轮廓系数、手肘法 |
differential.py |
15 | Euler/RK4、隐式、刚性、边值问题、SIR、Lotka-Volterra |
stochastic.py |
16 | 蒙特卡洛、MCMC、排队论、随机游走、期权定价、置信区间 |
geometry.py |
13 | 凸包、Haversine、多边形面积、IDW、克里金、泰森多边形 |
game.py |
8 | 纳什均衡、混合策略、零和、演化博弈、Shapley 值 |
timeseries.py |
12 | GM(1,1)+后验差、差分、ARIMA 定阶/拟合/预测、SARIMA、GARCH、卡尔曼滤波、Ljung-Box |
ml.py |
23 | 划分/标准化/混淆矩阵/ROC-AUC/K 折、KNN、决策树、随机森林、梯度提升、高斯 NB、LDA、置换重要性、SMOTE、类别权重 |
multicriteria.py |
8 | PROMETHEE II、ELECTRE I/III、秩和比、Borda、Copeland、排序一致性 |
multiobjective.py |
9 | Pareto 支配/快速非支配排序/拥挤距离、加权和、ε 约束、NSGA-II、2D 超体积、理想点距离 |
sensitivity.py |
11 | OAT、弹性系数、Morris 筛选、Sobol 一阶/总效应、均值/KNN/回归插补、Z 分数/IQR/MAD 异常检测 |
spatial.py |
7 | 一维热传导(显式/隐式)、二维 Poisson SOR、森林火灾元胞自动机、NaSch 交通流、Buckingham π、相似缩放 |
约束仍然只有 numpy + 标准库(CI 用 AST 扫描禁止 scipy/sklearn/pandas/statsmodels/torch/tensorflow/cvxpy/pulp/sympy/matplotlib),Python 3.9+,无交互、无网络、随机种子显式。
每个算法的细节都写进了 references/algorithm-details.md:数学形式 → 步骤 → 复杂度 → 参数表 → 陷阱 → 怎么检验。最后一栏给的是独立于本实现的检验手段(闭式解、与独立实现对拍、极限行为),可以直接搬进论文的"模型检验"一节。文档条目顺序与代码 __all__ 一致,分节 §3.1–§3.17 与 algorithm-implementations.md、innovation-playbook.md 完全对齐。
三、怎么创新:哪些参数能动
新增 references/innovation-playbook.md。核心观点是改数值 ≠ 创新,并把"调参"分成三个层级:
- ⚪ 调参:只在别人给的取值附近试数——审稿人不会认为是创新;
- 🔶 结构化:改参数的形式(把常数换成函数、把标量换成向量/矩阵、把固定权重换成数据驱动的权重)——能写成创新点;
- 🔴 假设层:改模型假设本身(放宽独立性、加入时变/空间相关、改目标函数族)——最有分量。
手册给 17 个算法族逐族列出:可动参数、常规取值、创新方向、创新度分档;再给出把"改参数"升级成真创新的四步法(机制假设 → 可辨识化 → 消融实验 → 结论边界)、实验设计速查、论文写法三件套、12 条伪创新反面模式和定稿自查清单。手册里每个反引号标识符都能落到代码上(发布时用脚本核对了 795 个函数名/形参名白名单,未解析项 0)。
实现说明(几个真踩到的点)
- CI 抓到一个本机永远碰不到的 numpy 兼容性缺陷。 工作流装的是
numpy>=1.24(即最新版),本机是 2.1.3。timeseries.py的卡尔曼平滑里写了float(H @ cov @ H.T),结果是(1, 1)数组;numpy 2.1 允许"单元素数组转标量",numpy 2.5 直接报TypeError: only 0-dimensional arrays can be converted to Python scalars。改成显式取[0, 0]后本机与 CI 双双全绿。教训:本地跑通 ≠ CI 跑通,声明"依赖 numpy"就必须在最新 numpy 上再跑一遍。 - 长程迭代的连续指标不能当黄金值。 NSGA-II 跑 150 代后与 ZDT1 解析前沿的最大偏差,本机 0.005040、Linux CI 0.005923。先排除了版本与随机性:本机 numpy 2.1.3 与 2.5.3 结果逐位相同(
front_size 60、history_len 151、偏差 0.005039580307475866),rng(seed)比特流相同,代码里没有字符串哈希依赖的排序、argsort用kind="stable"。当时判断是混沌放大,于是先把这两个键降级成"分档到 2% 的布尔指纹"——结果第二轮 CI 立刻把这个折中方案也否掉了:同一个提交在两次 Linux 运行里g_max分别是 1.008497 与 (1.02, 1.05],分档键直接翻档。真正的推手是不同 runner 的 CPU 指令集/BLAS 让np.sum的成对求和差几个 ULP,换成同一平台的另一台机器就会漂。最终做法是彻底不碰连续量:删掉分档指纹键,也删掉模块内dev <= 0.05、g_max <= 1.05这两条绝对阈值断言(后者在实测已到 1.02 时只剩 1.5 倍余量,本身就是潜伏的脆弱断言),改为断言四类结构/相对性质:① 数学不变量g >= 1;② 前沿内部两两互不支配(独立于本模块pareto_dominates的手写比较);③history长度恒为n_gen + 1且取值落在[1, pop_size](顺带纠正一处想当然:history记的是"当前种群内的第一前沿规模",并不单调,实测 ZDT1 出现过下降,原计划的单调性断言已撤掉);④ 相对改进——与同一 RNG 产生的随机初始种群相比,最终前沿偏差小一个量级以上(实测比值 7.0e-4,判据 0.1;随机基线自己会随平台一起漂,比的是比值,不是绝对值)。黄金值只留front_size/history_len这类整数结构量,键数仍是 875。教训:能用相对判据就别用绝对阈值;能让随平台漂移的量同时出现在比值两边,就别让它单独站在阈值一边。 这条经验已写进algorithm-details.md的 NSGA-II 条目和CHANGELOG.md。 - 逐算法文档的覆盖率必须能被脚本判定。 文档里的函数名是手写的,很容易"文档有、代码没有"。发布时把
#### \名字(...)`标题与 17 个模块的all双向比对,得到 224 个公开名称 / 223 个条目(含Z95` 一个常量条目)/ 缺失 0 / 多余 0 / 重复标题 0。 - 模块头 docstring 会和
__all__对不上。 扩写时新增了函数,但模块开头的"本模块包含……"还停在旧清单(例如optimization.py头只列 5 个、实际 9 个)。本版把 17/17 个模块的头部清单补全为分组枚举并写明条数。 - 文档里的数字必须与实测一致。
spatial.py里 Poisson 截断误差一处写 ≈2.8e-3、一处写 ≈2.9e-3;实算(n=16, h=1/17:最大误差 2.826e-3,解析量级 π²h²/12 = 2.846e-3)确认 2.8e-3 才对,已统一。
变更
README.md:新增「下载与安装」专章;「算法与代码」由 11 个模块改为 17 个算法模块、222 个公开函数并指向algorithm-details.md;几何与空间一行改成两个模块的真实内容;「怎么做出创新点」改为引用创新手册;质量保障表算法回归一行改为 17 个算法模块、875 个断言键;结构树补三行。SKILL.md:版本升至1.7.0;索引新增algorithm-details.md、innovation-playbook.md、download_templates.py;compatibility补上依赖口径。CITATION.cff同步version: 1.7.0与date-released: 2026-09-19。examples/algorithms_golden.json:键数 324 → 875。其中multiobjective里两轮 CI 反复证明不可复现的zdt1_dev_le_2pct、zdt1_g_le_2pct两个分档指纹键已删除(相对 v1.6.0 仍是纯新增:changed 0 / removed 0 / added 551)。examples/algorithms/{multiobjective,timeseries,spatial}.py:CI 逼出来的三处修正(见上)。multiobjective.py的 ZDT1 自测段整体重写为"不变量 + 互不支配 + 结构计数 + 相对改进"四类断言。references/algorithm-details.md:NSGA-II 的「怎么检验」一条按上述结论重写,明确写出"长程迭代量不要做黄金值/绝对阈值"。references/algorithm-implementations.md:§2 速查表补 6 行,§3 扩到 §3.17。
验证记录
| 项目 | 方式 | 结果 |
|---|---|---|
| 全量算法回归 | python examples/run_algorithms.py |
17 个模块 / 875 个断言键,失败 0 个模块;每模块跑两遍比对确定性 |
| 跨 numpy 版本 | numpy 2.1.3 与隔离环境 numpy 2.5.3 各跑一遍全量回归 | 两边都是 17 模块 / 875 键 / 0 失败 |
| 黄金值是否夹带回归 | v1.6.0 提交态 vs 1.7.0 逐键比对 |
changed=0、removed=0、added=551(纯新增,原有键一个没动) |
| ZDT1 断言是否脆弱 | 同一提交连跑两轮 Linux CI + 本机 numpy 2.1.3/2.5.3 | 旧连续键与分档指纹键两轮均翻档(已删);决定性旁证:算法内容完全相同的 7b08141 失败、dbc488a 成功,两次只差一个 README 提交 |
| 逐算法文档覆盖 | 文档标题 vs 17 个模块 __all__ 双向比对 |
公开名称 224 / 条目 223;缺失 0、多余 0、重复标题 0 |
| 创新手册引用完整性 | 反引号标识符 vs 函数名/形参名白名单(795 个) | 未解析 0 |
模块头清单与 __all__ 对齐 |
脚本断言"条数一致、无名称遗漏" | 17/17 通过 |
| 模板导出脚本自测 | python scripts/download_templates.py --self-test |
26/26 通过;重复打包的 zip 逐字节一致 |
| 技能结构校验 | python scripts/validate_skill.py . --strict |
0 个错误,0 个警告(29 个文件引用) |
| 依赖边界与代码纪律 | CI 的 AST 扫描 | 无禁用依赖、无 assert、无全局 np.random、docstring 字段顺序正确 |
| 论文自检逻辑 | python scripts/check_paper.py --self-test |
好稿 FAIL=0;坏稿/美赛坏稿按预期报错 |
| 模板编译体检逻辑 | python scripts/check_latex.py --self-test |
26/26 通过(无需装 TeX) |
| 模板真编译 | GitHub Actions latex 作业(Ubuntu + TeX Live) |
三套模板在 CI 上真编译通过 |
| 配图配色与数值 | check_palette.py --quiet、make_figures.py --self-test |
二色觉最差 ΔE 16.1;24 项配图数值与改动前一致 |
诚实说明
- 本版没有并入任何第三方的论文图、表、代码。
references/paper-examples.md仍然只给链接与出处索引;assets/gallery/的 16 张图全部由make_figures.py用固定种子原创生成。 - "每个算法都有实现"的边界要说清:这 222 个函数是教学透明版——网格小、格式简单、中间量全部显式返回,目的是让论文能写清每一步在算什么、以及结果怎么检验。真正的生产规模问题,各模块 docstring 都写明了该换哪个成熟库(OR-Tools、Pyomo、statsmodels、sklearn、SALib、PySAL 等)。把"能跑通并对照"说成"工业级性能"是不诚实的,本版没有这么写。
- 自测断言是独立的,不是复读实现:用的是闭式解、独立实现(如 SOR 解与直接法解对拍)、极限行为与解析值(如 Sobol 的 S1 解析值 [0.8, 0.2]、GARCH 的方差递推),而不是"实现输出等于实现输出"。
- 黄金值的作用是防回归,不是证明正确:875 个键只保证"以后改动不会悄悄改变结果";数值本身正确性由那些独立断言负责,新增模块的黄金值是在断言全过之后才记录的。
- 本版主动"减少"了两个断言键,这不是放宽标准。
zdt1_dev_le_2pct、zdt1_g_le_2pct连同两条绝对阈值断言被删除,换成了不变量、互不支配、结构计数与相对改进。理由在「实现说明」里:它们的失败与代码正确性无关,只与 runner 的浮点求和顺序有关,留着只会训练出"红了就重跑"的坏习惯。这两个键的删除是显式改动、在CHANGELOG.md里写明了;--update-golden在本版只用于记录新增模块的断言键,没有用来掩盖过任何一次回归。 相对v1.6.0发布态,875 个键仍是 chang...
v1.6.0 — LaTeX 模板真编译门禁:把"文档说能编"变成 CI 硬门禁
这一版做了什么
给三套 LaTeX 模板加了一道以前完全不存在的门禁:真编译。
assets/latex/ 下的国赛 / 研赛 / 美赛模板从 v1.4.0 起就在仓库里,README 里也一直写着"已在 Windows + MiKTeX 上实际编译通过"。但 CI 从来不编译它们——它只校验仓库结构、算法模块、配图和路径风格。也就是说:宏包改名、\cite 打错、字体装不上、\usepackage 少一个,模板可以一直悄悄地坏下去,而仓库照样全绿。文档里的"已验证"会停留在写下它的那一天;学生拿到手,第一遍编译就报错。
这不是审美问题,是覆盖缺口。本版把它补上,并且是拿真引擎去补的。
先说结论
| 环境 | 配置 | 结果 |
|---|---|---|
| Windows + MiKTeX 25.12 | 仓库原件(fontset=windows,--keep-fontset) |
3/3 通过:国赛 9 页 / 202,842 B、研赛 8 页 / 212,439 B、美赛 8 页 / 284,317 B |
| Windows + MiKTeX 25.12 | CI 等价(临时副本换 fontset=fandol) |
3/3 通过:国赛 9 页 / 341,465 B、研赛 8 页 / 366,745 B、美赛 8 页 / 284,317 B |
| Ubuntu + TeX Live(GitHub Actions) | CI 实际配置 | 3/3 通过:国赛 9 页 / ≈341,040 B、研赛 8 页 / ≈366,285 B、美赛 8 页 / ≈268,965 B |
页数在三套环境里完全一致(9 / 8 / 8)——同一份源码换引擎、换字体集、换操作系统都不改分页。这才是"模板能跨机器编译"的实测含义,而不是一句文档承诺。
新增
scripts/check_latex.py —— 三个模板的真编译体检(纯标准库)
- 把每个模板的
main.tex+refs.bib复制到系统临时目录再编译(xelatex/pdflatex→bibtex main→ 引擎 → 引擎,共 4 遍),仓库里不会出现任何.aux/.log/.pdf。 - 解析
main.log/main.blg判定:硬错误(^!)、未解析的\cite与\ref、字体缺失(The font "..." cannot be found)、Emergency stop、交叉引用未收敛(Rerun to get cross-references right)、是否真的产出 PDF、页数是否低于下限。 - 顺带核对两条合规顺序(直接查
.tex源码):国赛/研赛「AI 工具使用声明」必须在参考文献之前,美赛「Report on Use of AI」必须在参考文献之后(即在 25 页正文之外)。这条顺序是硬规则,写错了往年是要扣分甚至判违规的。 --self-test用合成日志跑 26 项固件测试,不需要装 TeX;--require让"找不到引擎"判为失败而不是跳过(CI 用);另有--only/--keep/--keep-fontset/--tex-dir便于本地排查。- 退出码即结论,可直接接入任何 CI。
.github/workflows/ci.yml 新增 latex 作业
- 独立的第二个 job:
ubuntu-latest+ 装 TeX Live + 跑check_latex.py --require。 - 先跑不需要 TeX 的
--self-test:一旦 CI 红了,能立刻分清是"脚本逻辑坏"还是"发行版缺宏包"。 - 字体处理:国赛/研赛模板用
fontset=windows(调用 Windows 自带宋体/黑体,学生开箱即用),但 Windows 字体在 Linux 上并不存在。因此脚本在临时副本里把它换成随发行版自带的fandol再编译,仓库里的模板一个字节都不改。想验证仓库原件本身,在有 Windows 字体的机器上跑--keep-fontset。
实现说明:三个真踩到的坑(都已修并写进自测)
1. 合规顺序不能直接在整篇 .tex 里搜索。
最初用整篇文本找 \bibliography{,结果命中了模板文件头第 13 行的说明文字:
% 若你暂时不想用 .bib,可把 \bibliography{refs} 换成手写 thebibliography于是"AI 声明在参考文献之前"被误判成不合规(注释在第 13 行,AI 声明在第 429 行)。现在先剥掉注释再匹配,并加了一条对应的自测。
2. 字体集替换只能动代码行。
fontset=windows 在每个中文模板里出现 3 次,其中 2 次在说明文字里。整篇替换会把"Linux/macOS 请把 fontset=windows 换成 fontset=fandol"改成同义反复,替换计数也虚高成 3。现在按行拆出注释、只替换代码部分,计数是 1。
3. lmodern 不在任何 texlive-* 包里——第一次跑 CI 就是这么红的。
新作业首次运行结果是 2/3 通过:国赛、研赛在 Ubuntu 上顺利编出 9 页 / 8 页,美赛模板却以
! LaTeX Error: File `lmodern.sty' not found.
直接中止。原因是 lmodern.sty 由 Debian/Ubuntu 的顶层包 lmodern 提供,装再多 texlive-* 也不会有。已在安装列表里补上 lmodern,并加了一行 kpsewhich lmodern.sty 做前置断言。
这次失败本身就是这个作业的价值证明:宏包清单的窟窿,只有在真编译时才会暴露。而且脚本准确报出了缺哪个包——修的时候不需要猜。
顺带一提,判断成败也不能依赖日志里的字节数:TeX Live 写 Output written on main.pdf (9 pages, 341464 bytes).,MiKTeX 只写 Output written on main.pdf (9 pages).。把字节数当必填,会在 MiKTeX 上把明明编译成功的模板判成"没产出 PDF"。现在页数取自日志,体积以磁盘上真实文件为准。
变更
assets/latex/README.md§6「验证记录」改为一条命令即可复现,并把实测数据按fontset=windows与fontset=fandol两种配置分开列出(此前只记了前者,且没说明用的是哪个字体集)。§5 排查表新增lmodern.sty not found一行(含 Fedora 对应包名)。README.md「质量保障」表新增"模板真编译"一行,仓库结构树补scripts/check_latex.py,assets/latex/那条说明改为"每次 CI 都会被真正编译一遍"。references/templates.md补"模板改完后怎么验"(含--self-test/--require/--keep-fontset三种用法与适用场合)。SKILL.md→1.6.0,compatibility写清check_latex.py的依赖(本机需有 TeX 发行版提供xelatex/pdflatex/bibtex),参考文件索引新增一行。CITATION.cff同步版本与日期。
验证记录
| 项目 | 方式 | 结果 |
|---|---|---|
模板编译(CI 等价配置,fandol) |
python scripts/check_latex.py --require |
3/3 通过,硬错误 0、未解析 \cite/\ref 各 0 |
模板编译(仓库原件,fontset=windows) |
python scripts/check_latex.py --keep-fontset |
3/3 通过 |
| 合规顺序 | 同一脚本的源码检查 | 国赛/研赛 AI 声明在参考文献之前 ✓;美赛在其之后 ✓ |
| 解析逻辑固件测试 | python scripts/check_latex.py --self-test |
26/26 通过(无需装 TeX) |
| CI 首次运行 | Actions run 35358308247 |
2/3:脚本准确报出缺 lmodern.sty,据此修复 |
| CI 修复后 | Actions run 35358882584 |
check 与 latex 两个作业全绿,latex 作业 3/3 |
| 仓库未被污染 | 运行前后 git status --porcelain |
无输出(编译只发生在系统临时目录) |
| 技能结构 | python scripts/validate_skill.py . --strict |
0 错误 0 警告 |
| 算法回归 | python examples/run_algorithms.py |
11 个模块 / 324 个断言键全部 PASS |
| 配色体检 | python scripts/check_palette.py --quiet |
断言全部通过(二色觉最差 ΔE 16.1) |
诚实说明
fontset=windows → fandol的替换是尽力而为,不是保证:脚本只改临时副本里的那一行(且只改代码部分、不碰注释),仓库里的.tex一个字节都没动。真正的判据是编译成功 + 日志里没有Font "…" cannot be found。在没有fandol的机器上这一步会失败,失败信息会直接打出缺哪个字体。- 页数与体积都是实测值,不是估算。PDF 体积每次编译会有几十字节抖动(来自时间戳与 PDF ID),页数则完全稳定;上表中 Ubuntu 一列写作
≈就是这个原因。 - 本版没有添加任何第三方论文截图或他人图表,理由同前几版:论文插图版权归作者/出版方,未经许可下载进仓库再分发通常不构成合规使用。仓库仍然只提供原创可复现图库 + 官方/授权来源链接索引(见
references/paper-examples.md)。 - 脚本只做可机械校验的事。模板的排版是否美观、内容是否切题,仍然必须人工复核。