1. 项目概述为什么需要一本“手写”的数学建模算法笔记如果你参加过数学建模竞赛或者在工作中需要用到建模分析大概率会有一个共同的感受资料太杂了。网上的代码、论文里的公式、教材上的推导它们像散落一地的珍珠看似丰富但在紧张的比赛或项目周期里你往往找不到最需要的那一颗。更常见的情况是你找到了一个算法的代码却看不懂其中某个参数为什么要这么设置或者你理解了模型的数学形式却不知道如何把它变成一行行能跑出结果的程序。这种“知道”与“做到”之间的鸿沟正是数学建模学习中最磨人的部分。“数学建模算法笔记手写”这个项目正是为了解决这个痛点而生的。它不是一个简单的资料汇编而是一个高度个人化、强逻辑关联的知识体系构建过程。手写是这个项目的灵魂。它强迫你慢下来不是机械地复制粘贴而是用自己的逻辑去重新组织、推导和诠释每一个算法。当你用笔在纸上画出Leslie人口模型的矩阵结构在旁边标注每一行、每一列的现实意义时当你一步步推导灰色预测的累加生成序列公式并注明其“弱化随机性”的原理时这个算法才真正开始属于你。这本笔记最终会成为你的“建模瑞士军刀”在关键时刻你能迅速定位到所需工具并且清楚地知道它的原理、适用场景以及可能存在的陷阱。这份笔记适合所有数学建模的参与者无论是备战“亚太杯”、“国赛”的大学生还是工作中需要运用模型解决实际问题的工程师、分析师。即使你只是对算法感兴趣希望通过一个系统的项目来提升自己的逻辑思维与编程能力这个“手写笔记”的过程也将让你受益匪浅。它不追求形式的华丽只关注内化的深度与调用的效率。2. 核心算法选型与笔记架构设计面对海量的数学建模算法全部记录既不可能也无必要。笔记的价值在于精炼和实用。我的选型原则是覆盖经典、突出应用、串联思想。基于高频搜索词和竞赛真题我将其核心分为四大模块这构成了笔记的一级骨架。2.1 模块一预测与评估类算法这是数学建模的“开场利器”多数赛题都需要对趋势进行研判。灰色预测模型 (GM(1,1)): 其核心优势在于处理“小样本、贫信息”的不确定性问题。笔记重点不在于背公式而在于理解其“累加生成”如何弱化随机性以及如何用“后验差比”和“小误差概率”来检验预测精度。我会手写推导从原始序列到预测值的过程并附上一个简单的MATLAB或Python函数框架标注关键参数如发展系数a和灰色作用量b的物理意义。时间序列分析 (ARIMA等): 相较于灰色预测它更适合有足够历史数据、且序列平稳或可差分平稳的情况。笔记会以流程图形式梳理ARIMA模型的建模步骤平稳性检验ADF检验→ 差分阶数d确定 → 自相关/偏自相关图定阶(p,q) → 参数估计 → 模型检验。旁边会备注statsmodels库中的ARIMA函数如何使用以及如何解读AIC/BIC准则。2.2 模块二优化与规划类算法解决“如何分配资源达到最佳”的问题是建模的核心。线性/非线性规划: 笔记会从标准形式写起强调“决策变量、目标函数、约束条件”三要素。重点记录scipy.optimize.linprog线性和minimize非线性的调用语法特别是如何将实际问题转化为函数要求的格式。例如如何把“最大化”问题转化为“最小化”如何把不等式约束写成矩阵形式。多目标规划: 这是热点和难点。笔记不会罗列所有方法而是聚焦最实用的两种权重系数法和主要目标法。我会用表格对比方法核心思想适用场景注意事项权重系数法给各目标赋权转化为单目标目标量纲一致或可归一化权重容易确定权重微小变化可能导致解的巨大差异需做灵敏度分析主要目标法保证一个主要目标最优其余作为约束目标有明显主次关系约束条件的阈值设定需要合理否则可能无解旁边附上一个简化案例企业生产既要利润最大又要污染最小如何建模。启发式算法鲸鱼算法WOA、蚁群算法ACO: 对于连续或组合优化问题当传统方法难以求解时这些算法是利器。笔记重点记录其核心思想隐喻和算法流程图。例如鲸鱼算法的“包围猎物”、“气泡网攻击”和“随机搜索”三个阶段对应代码中的数学公式。我会手写伪代码并注明关键参数如种群大小、最大迭代次数的调参经验范围。2.3 模块三分类评价与决策分析用于比较、排序或做出选择。层次分析法 (AHP): 手写部分的核心是构造判断矩阵和一致性检验。我会画出一个完整的AHP层次结构图然后详细记录如何用1-9标度法进行两两比较如何计算权重向量方根法或和积法以及最关键的一步计算一致性指标CI和一致性比率CR。旁边用红笔标注CR0.1才通过检验否则必须调整判断矩阵。TOPSIS法 (逼近理想解排序法): 笔记以步骤为导向1. 构造决策矩阵2. 数据标准化消除量纲3. 确定正/负理想解4. 计算各方案到正负理想解的距离5. 计算相对贴近度并排序。我会用一个包含4个评价指标、3个备选方案的小例子完整演算一遍。2.4 模块四现代智能算法与交叉应用体现笔记的前沿性和扩展性。机器学习基础用于拟合、分类、预测: 不追求深度只记录在建模中可能直接调用的模型。例如随机森林用于特征重要性排序和高精度回归/分类支持向量机(SVM)用于小样本、非线性分类。笔记记录其sklearn调用接口和核心参数如随机森林的n_estimators, SVM的kernel和C。深度学习初步: 仅作为展望记录如LSTM网络处理时间序列预测的基本思想并备注“数据需求量大赛题中谨慎使用”。算法融合思路: 这是高分论文的亮点。例如用模拟退火(SA)或改进的鲸鱼算法来优化神经网络的初始权重避免陷入局部最优用主成分分析(PCA)对多目标规划前的指标进行降维减少冗余。笔记架构心得不要按教材目录抄要按问题导向来组织。我的笔记首页就是一张“算法选择决策树”问题是要预测优化评价数据量多少是否有约束根据回答迅速定位到对应的算法模块。这才是实战笔记的价值。3. 手写笔记的实操方法与内容深化手写不是目的通过手写实现深度理解和快速检索才是。我的笔记采用“一页纸一个算法核心”的原则每页包含以下固定板块3.1 板块一思想直观与模型定义在页面顶部用一两句话和简易图形概括算法精髓。例如Leslie模型旁边画一个年龄结构金字塔箭头表示随时间推移向上移动和生育补充直观展示“按年龄分组的人口离散递推”思想。蚁群算法画几条路径蚂蚁图标在路径上信息素浓度用线条粗细表示体现“正反馈”和“启发式”搜索。灰色预测画一个原始波动曲线和一个经过累加后变得平滑的曲线对比展示“弱化随机性凸显规律”。接着给出模型的数学定义。例如对于多目标规划明确写出Minimize F(x) [f1(x), f2(x), ..., fm(x)]^T Subject to: g_j(x) ≤ 0, j1,2,...,p h_k(x) 0, k1,2,...,q x ∈ X并用不同颜色的笔圈出“目标函数向量”和“约束条件”。3.2 板块二核心公式推导与关键参数这是笔记的硬核部分。不是照抄公式而是推导关键步骤。以灰色预测GM(1,1)为例原始序列X^(0) (x^(0)(1), x^(0)(2), ..., x^(0)(n))用蓝笔写。一次累加生成(1-AGO)x^(1)(k) Σ_{i1}^k x^(0)(i)推导其目的是为了降低噪声。在旁边用铅笔演算一个小例子如(1,2,1.5,3)累加后变成(1,3,4.5,7.5)直观感受数据变得单调。建立灰微分方程x^(0)(k) a*z^(1)(k) b其中z^(1)(k)是背景值通常取均值。这里用红笔标注背景值的构造方式常用紧邻均值生成是模型的一个关键点。转化为矩阵方程用最小二乘法求解a, b手写Y B * [a, b]^T的形式并写出最小二乘解[a, b]^T (B^T * B)^{-1} * B^T * Y。这个推导过程能让你彻底理解参数来源。时间响应式与预测写出解x^(1)(t)的表达式并还原到x^(0)。精度检验表在页面下方画一个表格列出手算或程序跑出来的残差、相对误差、后验差比C和小误差概率P并给出评价等级好、合格、勉强、不合格。3.3 板块三代码框架与接口注释在公式推导的右侧或背面附上精简的、可运行的代码片段Python/MATLAB。代码必须高度注释且与前面的公式一一对应。# 灰色预测GM(1,1)模型 Python实现 import numpy as np def GM11(x0): 参数: x0: 原始序列一维numpy数组如 np.array([1,2,3,4]) 返回: predict: 预测值包括历史拟合和未来预测 a: 发展系数 b: 灰色作用量 C: 后验差比 P: 小误差概率 # 1. 累加生成(AGO) x1 np.cumsum(x0) # 对应公式 x^(1)(k) # 2. 构造数据矩阵B和常数向量Y # 计算背景值z^(1)(k) 0.5*(x^(1)(k)x^(1)(k-1)) z1 (x1[:-1] x1[1:]) / 2.0 # 关键步骤 B np.vstack([-z1, np.ones(len(z1))]).T # 对应矩阵B Y x0[1:].reshape(-1, 1) # 对应向量Y # 3. 最小二乘法求解参数 [a, b]^T # 对应公式 [a, b]^T (B^T B)^{-1} B^T Y a, b np.linalg.inv(B.T B) B.T Y a, b a[0], b[0] # 4. 时间响应式及预测 # 对应解 x^(1)(t) (x0(1)-b/a)*exp(-a*t) b/a predict_x1 (x0[0] - b/a) * np.exp(-a * np.arange(len(x0)5)) b/a # 累减还原(IAGO)得到预测的原始序列 predict_x0 np.diff(predict_x1) predict_x0 np.insert(predict_x0, 0, predict_x1[0]) # 插入第一个值 # 5. 精度检验此处省略详细计算代码笔记上会展开 # ... 计算残差、相对误差、后验差比C、小误差概率P C 0.05 # 示例值 P 0.95 # 示例值 return predict_x0, a, b, C, P # 使用示例 # data np.array([1.2, 1.5, 1.8, 2.1, 2.3]) # predict, a, b, C, P GM11(data) # print(f发展系数 a{a:.4f}, 灰色作用量 b{b:.4f}) # print(f后验差比 C{C:.4f}, 预测等级为{好 if C0.35 else 合格 if C0.5 else 勉强 if C0.65 else 不合格})在代码旁用箭头和便签纸注明“np.cumsum()对应累加生成”、“z1的背景值计算是模型核心之一”、“np.linalg.inv求逆可能不稳定大规模数据建议用np.linalg.lstsq”。3.4 板块四适用场景、优缺点与联想钩子在页面底部或边缘用总结性语言记录适用场景GM(1,1)适用于短期、指数趋势明显、数据量少通常4-15个的预测。不适合长期预测和数据波动剧烈的场景。优缺点优点不需要大量数据计算简单短期预测精度尚可。缺点对指数趋势假设强长期预测误差放大对异常值敏感。联想钩子对比→ 与时间序列ARIMA对比数据要求、线性vs非线性。改进→ 可考虑残差GM(1,1)修正或背景值优化如用加权均值。应用→ 可用于预测类赛题的基准模型或作为其他复杂模型的组成部分。手写实操心得使用活页笔记本和多种颜色的笔。黑色写主体和公式蓝色写推导和注释红色画框标注重点、警告和关键参数绿色写代码和输出示例。活页方便后续在特定算法前后插入新的关联内容如看到一篇用改进鲸鱼算法优化灰色模型参数的论文可以立刻加到灰色预测页后面。定期如每周花半小时快速翻阅强化记忆。4. 经典模型深度剖析以Leslie模型和多目标规划为例掌握了笔记方法我们来深入两个高频且易错的模型看看如何将上述方法应用到具体内容中。4.1 Leslie人口模型从矩阵到代码的完全透视Leslie模型的核心是利用当前人口的年龄结构通过生育率和存活率来预测未来人口。笔记的关键是打通“生物学假设→数学矩阵→程序实现”的全链条。4.1.1 模型假设与矩阵构建首先明确假设1) 仅考虑女性人口主导生育2) 按相同间隔如1岁或5岁划分年龄组3) 生育率和存活率不随时间变化这是模型的强假设也是局限性。 假设将人口分为m个年龄组。我们需要两个关键向量存活率向量S [s1, s2, ..., s_{m-1}]si表示第i组存活到第i1组的比例。注意最后一个年龄组如85的存活率为0因为模型不考虑该组人存活到下一个周期。生育率向量F [f1, f2, ..., fm]fi表示第i组女性在单位时间内平均生育的女婴数。通常只有部分育龄年龄组如15-49岁的fi非零。Leslie矩阵L是一个m x m的矩阵L [ f1 f2 f3 ... f_{m-1} f_m s1 0 0 ... 0 0 0 s2 0 ... 0 0 ... ... ... ... ... ... 0 0 0 ... s_{m-1} 0 ]第一行是各年龄组的生育率次对角线是存活率。这个结构完美体现了“生育增加新生儿存活推动年龄增长”的动态过程。4.1.2 递推预测与长期行为记t时刻各年龄组的人口数为列向量N(t) [n1(t), n2(t), ..., nm(t)]^T。则模型递推公式为N(t1) L * N(t)这是一个离散动力系统。通过迭代我们可以预测未来任何时刻的人口结构。笔记上我会手算一个3×3的Leslie矩阵与初始人口向量相乘1-2步直观感受这个过程。更深入的分析是研究其长期行为。根据Perron-Frobenius定理非负不可约矩阵存在一个正实数的优势特征值λ1其对应的特征向量代表了稳定的年龄结构。λ1 1人口增长λ1 1人口稳定λ1 1人口衰减。在笔记上我会用numpy.linalg.eig计算一个小例子的特征值和特征向量并验证其长期趋势。4.1.3 Python实现与可视化import numpy as np import matplotlib.pyplot as plt def leslie_forecast(F, S, N0, years): F: 生育率向量 (list/np.array) S: 存活率向量 (list/np.array)长度比F少1 N0: 初始人口向量 (list/np.array) years: 预测年数 m len(F) # 构建Leslie矩阵L L np.zeros((m, m)) L[0, :] F # 第一行是生育率 for i in range(m-1): L[i1, i] S[i] # 次对角线是存活率 # 迭代预测 population [N0] current N0.copy() for _ in range(years): current L current # 矩阵乘法进行递推 population.append(current.copy()) # 计算总人口 total_pop [np.sum(p) for p in population] return np.array(population), total_pop, L # 示例一个简化的5年龄组模型 F [0, 0.2, 0.8, 0.1, 0] # 只有第2、3组有生育能力 S [0.9, 0.95, 0.85, 0.5] # 存活到下一组的概率 N0 [100, 80, 60, 40, 20] # 初始各年龄组人口 years 20 pop_history, total_pop, L_matrix leslie_forecast(F, S, N0, years) # 可视化总人口变化 plt.figure(figsize(10,4)) plt.subplot(1,2,1) plt.plot(range(years1), total_pop, markero) plt.xlabel(年份) plt.ylabel(总人口) plt.title(总人口预测) plt.grid(True) # 可视化年龄结构演变最后一年 plt.subplot(1,2,2) age_groups [0-1, 1-2, 2-3, 3-4, 4-5] plt.bar(age_groups, pop_history[-1]) plt.xlabel(年龄组) plt.ylabel(人口数) plt.title(f第{years}年年龄结构) plt.tight_layout() plt.show() # 分析长期趋势计算优势特征值 eigenvalues, eigenvectors np.linalg.eig(L_matrix) dominant_idx np.argmax(np.abs(eigenvalues)) lambda1 eigenvalues[dominant_idx].real print(fLeslie矩阵的优势特征值 λ1 {lambda1:.4f}) print(f长期预测人口将{增长 if lambda11 else 稳定 if lambda11 else 衰减}。)在笔记中我会将这段代码的输出图表和特征值打印出来贴在一旁并分析为什么这个参数设定下人口会增长/衰减调整F和S后结果如何变化4.2 多目标规划从矛盾到妥协的求解艺术多目标规划难在“目标之间往往冲突”。笔记的重点是理清各种求解方法的适用边界和实操转换。4.2.1 权重系数法的陷阱与技巧最直观的方法是将多目标加权求和Min U w1*f1(x) w2*f2(x) ... wm*fm(x)。但问题来了权重wi怎么定主观赋权法如AHP通过专家打分判断各目标重要性。笔记记录AHP的步骤并强调其主观性。实操技巧可以请团队多个成员分别打分取平均判断矩阵或进行敏感性分析观察权重微小变动对最优解的影响范围。客观赋权法如熵权法根据各目标函数值的数据离散程度自动确定权重。离散程度越大权重越高。笔记记录熵权法的计算步骤标准化、计算熵值、计算差异系数、确定权重。适用场景当你有大量样本数据且难以主观衡量目标重要性时。重要提示权重系数法要求目标函数量纲一致或可无量纲化。如果目标是利润万元和污染排放吨直接加权求和没有意义。必须先进行归一化例如都转化为[0,1]区间内的效益型或成本型指标。4.2.2 主要目标法与实践转换设定一个最主要的目标作为优化目标其他目标转化为约束条件。例如“在污染排放不超过P0的前提下使利润最大化”。笔记的关键是记录如何确定约束阈值。阈值太松失去约束意义阈值太紧可能无解。一个实用的方法是先单独优化每个目标得到每个目标的理想值f_i*和最差值然后在这个范围内选择一个合理的、可接受的阈值。4.2.3 实战编程求解以权重法为例假设有两个目标成本f1(x)最小化、效率f2(x)最大化假设已转化为最小化问题即-f2(x)且有线性约束。import numpy as np from scipy.optimize import minimize # 定义两个目标函数 def f1(x): return 4*x[0] 5*x[1] # 成本 def f2(x): return - (10*x[0] 12*x[1]) # 效率取负转化为最小化 # 定义约束条件x1 x2 10, x1 6, x1, x2 0 cons ({type: ineq, fun: lambda x: 10 - x[0] - x[1]}, {type: ineq, fun: lambda x: 6 - x[0]}, {type: ineq, fun: lambda x: x[0]}, # x1 0 {type: ineq, fun: lambda x: x[1]}) # x2 0 # 设定不同的权重组合进行求解 weights [(0.1, 0.9), (0.5, 0.5), (0.9, 0.1)] # (w1, w2) solutions [] for w1, w2 in weights: # 定义加权单目标函数 def weighted_obj(x): return w1 * f1(x) w2 * f2(x) # 初始猜测 x0 np.array([3.0, 3.0]) # 求解 res minimize(weighted_obj, x0, constraintscons, bounds[(0, None), (0, None)]) solutions.append((w1, w2, res.x, res.fun)) # 输出帕累托前沿近似解 print(权重组合 - 最优解 (x1, x2) - 加权目标值) for w1, w2, x_opt, f_opt in solutions: print(f({w1}, {w2}) - ({x_opt[0]:.2f}, {x_opt[1]:.2f}) - {f_opt:.2f}) # 同时计算原始两个目标的值 print(f 原始目标: 成本 f1{f1(x_opt):.2f}, 效率 f2{-f2(x_opt):.2f}) # 注意f2取回正值笔记中我会将不同权重下的解和对应的原始目标值列成表格绘制成“帕累托前沿”的散点图直观展示目标间的权衡关系。这比单纯求解更有价值。5. 从笔记到实战竞赛应用与高级技巧一本好的算法笔记最终要服务于实战尤其是数学建模竞赛。这部分记录如何将笔记知识转化为论文中的亮点。5.1 赛题拆解与算法匹配流程拿到赛题后我的笔记首页的“算法选择决策树”就派上用场了。但更关键的是第二步混合与创新。例如2023年国赛A题涉及复杂的优化问题单纯用线性规划可能不够。笔记里“算法融合思路”部分就会提醒我是否可以结合模拟退火(SA)或改进的鲸鱼算法来求解因为启发式算法能更好地处理非线性、多峰问题。 具体流程问题识别是预测、优化、评价、分类还是关联分析数据审视数据量大小、质量、维度时间序列还是横截面数据初选模型根据1和2从笔记中选出2-3个候选基础模型。模型组合/改进思考看笔记的“联想钩子”和“算法融合”部分是否有可结合的思路例如预测后用优化模型做决策用评价模型对优化结果进行筛选。简单实现与对比快速编写候选模型代码在部分数据上试跑比较初步效果和计算复杂度确定主力模型。5.2 模型检验与灵敏度分析论文的加分项很多队伍只建模、求解却忽略了检验和分析这是丢分项。笔记中每个算法板块都必须包含其检验方法。预测模型必须进行残差分析画残差图看是否随机分布、后验差检验如灰色预测的C和P值、滚动预测用前t个数据预测第t1个逐步检验。优化模型必须进行灵敏度分析。例如在多目标规划中改变权重系数观察最优解的变化是否剧烈在线性规划中分析影子价格对偶变量说明资源增加一单位对目标函数的影响。笔记中要记录如何在linprog的输出中提取影子价格res.dual。评价模型如AHP必须报告一致性比率CR并说明若CR不合格如何调整判断矩阵例如找出不一致性最大的元素微调其值。5.3 可视化表达让结果自己说话一图胜千言。笔记中要积累每种算法的标准可视化代码模板。预测图横轴时间纵轴指标。必须同时画出历史数据的拟合曲线和未来预测曲线用不同颜色或线型区分并标注预测起点。用阴影区域表示预测的置信区间如果模型能提供。优化结果图对于多目标规划绘制帕累托前沿图两个目标时是散点图三个目标时是三维散点图。对于路径规划问题如AGV调度画出最优路径图。评价结果图用雷达图展示不同方案在各指标上的优劣用条形图结合折线图展示TOPSIS法的贴近度排序。# 帕累托前沿示例 (假设已有解集solutions) import matplotlib.pyplot as plt f1_vals [s[0] for s in solutions] # 目标1值 f2_vals [s[1] for s in solutions] # 目标2值 plt.scatter(f1_vals, f2_vals, cred, alpha0.6, edgecolorsk) plt.xlabel(Cost (f1)) plt.ylabel(-Efficiency (f2)) # 注意这里是负效率 plt.title(Pareto Front of Multi-Objective Optimization) plt.grid(True, linestyle--, alpha0.5) # 标记几个特殊点如理想点 ideal_f1 min(f1_vals) ideal_f2 min(f2_vals) # 因为f2已转化为最小化 plt.scatter(ideal_f1, ideal_f2, cblue, s100, marker*, labelIdeal Point) plt.legend() plt.show()5.4 论文写作的“弹药库”笔记的最终形态是论文写作时可以直接引用的“弹药库”。模型描述部分直接参照笔记中的“思想直观”和“模型定义”部分用专业的语言重新组织。公式可以直接引用。求解过程部分参照“代码框架”但论文中只展示核心步骤的伪代码或流程图而非全部代码。结果分析部分参照“适用场景与优缺点”结合本次赛题数据讨论模型的适用性、结果的合理性以及局限性。模型检验与改进部分直接调用笔记中记录的检验方法和改进思路如残差GM、背景值优化成为论文的亮点。竞赛实战心得在三天比赛中翻看自己手写的笔记比在网上漫无目的地搜索要高效十倍。因为你熟悉每一页的位置理解每一个标注的含义。更重要的是笔记里记录了你曾经踩过的坑和总结的技巧能让你在高压下避免重复错误。例如我在笔记的灰色预测页用红笔大字写着“数据预处理级比检验如果原始序列的级比不在可容覆盖区间内必须做平移或对数处理否则模型无效。”这个提醒在比赛中可能直接挽救一个模型。