简介面向数学建模竞赛参赛者与算法学习者这份资源集中整理了30个常用算法的Python实现覆盖预测、分类、优化、综合评价等典型赛题场景。压缩包共39个文件以txt代码说明和docx算法解析为主辅以py脚本、dat数据文件、spec配置文件及rar/exe辅助工具整体约129.22MB结构清晰便于按算法名检索。已有1653人学习下载适合备战数模竞赛或快速上手经典模型。资源内置ARIMA时间序列预测、逻辑回归、神经网络分类、线性规划、模拟退火、K-means聚类、遗传算法、灰色预测、支持向量机、主成分分析等常见算法代码配套文档对建模思路和实现要点做了梳理可直接运行调试或迁移到自己的赛题中。此外还包含随机森林、决策树、蒙特卡洛、模糊综合评价等进阶模型覆盖从基础到智能优化的方法体系对赛前集中复习和临场调用都很有帮助。1. 数学建模常用的30个常用算法Python代码先搞清楚你拿到的是什么临近国赛还有一周才发现层次分析法的判断矩阵怎么构造都忘了K-means 的 K 值拍脑袋填了 3粒子群算法的惯性权重 w 完全不知道干嘛用。这种慌乱我不止一次遇到过比赛里最扎心的不是题目难而是你想用的算法还得现场搜代码、现场改 bug。数学建模赛题翻来覆去就是预测、评价、优化、分类几大类用到的高频算法也就二三十个。「数学建模常用的30个常用算法(Python代码).zip」这类打包好的 Python 代码集就是把比赛里最常用的算法提前写好、统一封装让你从临时找代码、改代码里省出时间直接进入读题、选算法、调参、写论文的主线。适合正在备战国赛或美赛的同学也适合刚转 Python 做数模、不想再翻 MATLAB 老脚本的人。下面我按“看清清单、拆解代码、调对参数、避开坑、变成自己的工具”这条路线展开。2. 30个算法怎么被塞进一个zip按赛题反推的清单逻辑与Python选型2.1 从赛题类型反推算法清单一份能打的目录长这样打开 zip 之前先想清楚一个问题30 个算法不是随便凑数是按赛题类型反推出来的。我按近十年国赛、美赛真题做了个粗糙归纳绝大多数题目只落在四类主线上预测、评价、优化、分类与聚类。预测类线性回归、灰色预测 GM(1,1)、ARIMA、BP 神经网络、随机森林回归。评价类层次分析法 AHP、熵权法、TOPSIS、灰色关联分析。优化类粒子群 PSO、遗传算法 GA、模拟退火、贪心算法、动态规划、匈牙利算法、A* 搜索。分类与聚类K-means、层次聚类、DBSCAN、SVM、随机森林分类、KNN。数据处理与边角滑动平均滤波、归一化/标准化、主成分分析。这个清单的妙处在于可组合。评价题用“熵权法 TOPSIS”预测题用“灰色预测 残差修正”优化题用“粒子群 模拟退火”做局部再搜索分类题用“K-means 先分簇、随机森林再建模”。少数老题会用到归并排序、KMP 这类偏数据结构的算法以及贪心、动态规划这类策略型算法它们通常被放在包尾部做补充解决的是“某个环节需要排序、匹配或状态转移”的问题而不是独立成题。2.2 为什么用 Python 而不是 MATLAB生态、代码量与可拼接性老派数模选手习惯 MATLAB但现在越来越多的代码包下沉到 Python原因很直接sklearn、scipy、statsmodels、pandas 四个库覆盖了九成赛题需求。预测有 statsmodels 的 ARIMA聚类分类有 sklearn 全家桶评价类算法虽然 sklearn 不直接给 TOPSIS但核心也就几十行矩阵运算numpy 够用。更现实的原因是论文附录要放代码。MATLAB 需要 license评审复现成本高Python 只要一个 requirements.txtpip 一次装完。这类 zip 包真正值钱的地方不是代码本身有多高级而是它把「调包侠」的代码风格统一了每个算法一个 .py 文件输入输出都用 CSV 或 numpy 数组随机种子固定这样比赛时可以把几个脚本像积木一样拼到一起。我拿到这种包第一步不是双击 main.py而是先看目录结构和依赖说明。2.3 拿到 zip 后先别急着跑主程序确认结构再建环境常见做法是解压后分三步走看 README 或目录注释确认每个文件是独立可跑的脚本还是依赖某个公共工具模块建虚拟环境避免把全局 Python 环境搅乱先挑一个最简单的评价类脚本跑通验证 numpy、pandas、sklearn 这些基础库版本兼容。# 在 zip 解压后的目录里执行 python -m venv .venv source .venv/bin/activate # Windows 下用 .venv\Scripts\activate python -m pip install -r requirements.txt python 01_entropy_weight.py # 先跑一个最简单的熵权法脚本参数说明venv 把依赖隔离到项目目录内不污染系统 Pythonrequirements.txt 里一般锁定了 numpy、pandas、scikit-learn、scipy 的大版本区间如果没锁版本建议自己手动装当前稳定版避免老脚本调用 sklearn 里已废弃的 API 报错。若跑01_entropy_weight.py时报 ModuleNotFoundError先看缺哪个库再单独安装不要一次性全装。3. 三类核心代码拆解从单算法跑通到组合出结论3.1 评价类打底组合熵权法算权重TOPSIS 出排名评价类赛题占国赛的比例不低而熵权法 TOPSIS 是被用得最多的万能组合。熵权法根据指标变异程度算权重TOPSIS 再按正负理想解的距离排序。这套组合对评委来说既常见又清晰只要数据表是规整的二维矩阵几乎不需要调参。import pandas as pd import numpy as np def entropy_weight(data): # 数据需要先正向化所有指标都是越大越好 norm (data - data.min()) / (data.max() - data.min() 1e-9) p norm / (norm.sum(axis0) 1e-9) e - (p * np.log(p 1e-9)).sum(axis0) / np.log(len(data)) w (1 - e) / (1 - e).sum() return w def topsis(data, w): norm (data - data.min()) / (data.max() - data.min() 1e-9) weighted norm * w ideal_best weighted.max(axis0) ideal_worst weighted.min(axis0) d_best np.sqrt(((weighted - ideal_best) ** 2).sum(axis1)) d_worst np.sqrt(((weighted - ideal_worst) ** 2).sum(axis1)) return d_worst / (d_best d_worst 1e-9) scores pd.read_csv(evaluation_data.csv, index_col0) w entropy_weight(scores.values) scores[score] topsis(scores.values, w)逻辑说明entropy_weight 先做 min-max 归一化再加1e-9防止对数里出现 0p 是每个样本在该指标上的占比熵值 e 越小说明该指标区分度越大权重越高。topsis 里理想最优是加权后的每列最大值理想最劣是最小值最终接近 1 的方案越优。注意scores.values必须是纯数值矩阵如果 CSV 里混入字符串列这里的 pandas 读入会把整列变成 object减法和除法都会报错。3.2 优化类手写骨架粒子群算法的循环、边界与惯性权重很多赛题最后落在“找一个参数使目标最大或最小”这类题报 30 个算法包里大概率放着 PSO、遗传算法、模拟退火。手写一个可复现的粒子群引擎比现场调 sklearn 里的黑匣子更可控因为每一步迭代都能打印出来方便写进论文的算法流程图。import numpy as np def pso(func, dim, bound, n_pop30, n_iter100, w0.8, c12.0, c22.0): lb, ub bound x np.random.uniform(lb, ub, (n_pop, dim)) v np.random.uniform(-1, 1, (n_pop, dim)) pbest x.copy() pbest_val np.array([func(i) for i in x]) gbest pbest[pbest_val.argmin()] gbest_val pbest_val.min() for _ in range(n_iter): # w 控制惯性c1 拉向个体历史最优c2 拉向全局最优 v w * v c1 * np.random.rand(n_pop, dim) * (pbest - x) \ c2 * np.random.rand(n_pop, dim) * (gbest - x) x x v x np.clip(x, lb, ub) # 边界裁剪防止飞出定义域 val np.array([func(i) for i in x]) update val pbest_val pbest[update] x[update] pbest_val[update] val[update] if pbest_val.min() gbest_val: gbest pbest[pbest_val.argmin()] gbest_val pbest_val.min() return gbest, gbest_val逻辑说明PSO 的每个粒子代表一组候选解速度更新公式里三部分分别对应惯性、个体认知和社会认知。np.clip把位置强制拉回边界这在工程约束类赛题里特别关键比如 x 表示原材料配比就只能落在 0 到 1 之间。函数 func 是目标函数越算越小则 PSO 默认做最小化如果你的赛题要最大化就把 func 改成返回负值。第一次跑先不看精度看它能不能收敛如果 30 代内 gbest_val 就不再下降说明初始值给得好如果一直在跳说明 w 偏大或迭代次数不够。3.3 预处理先于一切滑动平均滤波与归一化这么配赛题里出现传感器、温度、交通流这类连续监测数据时原始值往往噪声大、量纲乱。滑动平均滤波是一个几乎零成本的处理手段一行 pandas 就够。做完滤波再归一化后接聚类、回归、神经网络都不会被个别离群点带偏。import pandas as pd from sklearn.preprocessing import MinMaxScaler df pd.read_csv(sensor.csv, parse_dates[time]) df[temp_smooth] df[temp].rolling(window5, centerTrue, min_periods1).mean() scaler MinMaxScaler() df[temp_norm] scaler.fit_transform(df[[temp_smooth]]) print(df.head(10))参数说明window5 表示取前后各两个点平均窗口太大曲线变迟钝太小滤不掉毛刺一般 3 到 7 之间试centerTrue 让输出对齐原时间点方便和原始数据画在一起对比min_periods1 保证序列开头不出现 NaN。MinMaxScaler 把结果压到 0 到 1适合距离类和梯度类算法如果后续要做线性回归且想保留变量相对尺度改用 StandardScaler 做标准化更好。4. 参数怎么设预测、分类、优化三类算法的推荐起点与调参顺序4.1 预测类算法先盯序列长度和样本量预测题里最常见的翻车是样本量没看清就套模型。灰色预测适合小样本、单调趋势明显的短序列外推步数建议控制在原始数据长度的三分之一以内ARIMA 适合有平稳趋势的中长序列先看差分阶数 d 再定 p 和 qBP 神经网络在小样本上很容易过拟合隐藏层节点数不要贪多。算法推荐起点参数调整依据灰色预测 GM(1,1)原始数据 4-10 个点外推 1-3 步外推步数越多误差越大超过 5 步基本没法看线性回归无必调参数检查多重共线性VIF 大于 10 时删变量ARIMA先用 ACF/PACF 定 p、d、qd 由差分后是否平稳决定AIC 越小越好BP 神经网络隐藏层节点数取(输入特征数输出数)//2 左右训练集损失和验证集损失差距大时降节点数随机森林回归n_estimators100max_depth5-10看 OOB 误差是否还在下降max_depth 限制防过拟合预测类参数的共同逻辑是“先欠拟合再逐步加复杂度”。我一般把随机森林的 n_estimators 从 100 起步画一条 OOB 误差曲线如果 300 棵时还在明显下降就继续加如果 50 棵时就平了再加只会拖慢速度。ARIMA 这种则先把差分阶数 d 设对再去网格搜索 p 和 q顺序反了容易调出一个看似 AIC 很低但预测曲线发散的模型。4.2 聚类与分类算法两个最容易被问的参数聚类题里被问得最多的两个参数是 K-means 的 K 和 DBSCAN 的 eps。K 不是拍脑袋定的用肘部法看簇内平方和拐点再用轮廓系数验证DBSCAN 的 eps 看 K-距离图的拐点min_samples 取特征维数的两倍左右比较稳。算法推荐起点参数调整依据K-meansK 靠手肘法取拐点初始化 n_init10轮廓系数低于 0.2 时换 K 或换聚类方法DBSCANeps 取 K-距离图拐点min_samples2*dimeps 太大会并成一簇太小几乎全是噪点层次聚类距离用 ward聚类数看树状图剪枝位置样本量上千时不要用层次聚类计算量太大SVMC1gammascale线性可分用线性核非线性用小 gamma 配 RBF 核随机森林分类n_estimators200min_samples_leaf1 起类别不平衡时调 class_weightbalanced分类算法里 SVM 的 C 和 gamma 是玄学重灾区我都是用 GridSearchCV 在 C ∈ {0.1, 1, 10}、gamma ∈ {0.01, 0.1, 1} 的网格里搜一遍同时固定随机种子避免搜索结果波动。随机森林的 n_estimators 不是越大越好超过某个值之后准确率曲线是平的纯粹白烧 CPU比赛时我会控制在 200 棵以内。4.3 优化类算法群体迭代这些参数有公共规律粒子群、遗传算法、模拟退火虽然实现差异大但参数规律是相通的种群或样本数量 20 到 50 足够迭代次数看收敛曲线而不是拍值变异和扰动的概率要低太高会破坏已有最优解。粒子群里 w 惯性权重从 0.9 线性衰减到 0.4 能兼顾前期探索和后期收敛c1、c2 取 1.5 到 2.0。遗传算法里交叉概率 0.8、变异概率 0.01 是多年比赛验证过的起点变异太大就退化成了随机搜索。模拟退火的初始温度要参考目标函数的量级比如函数值在几千的量级却把初始温度设成 1接受劣解的概率基本为 0退火白做。匈牙利算法和 A* 没有随机参数主要检查输入数据的方向匈牙利算法的 cost 矩阵行是任务列是工人时要确认求的是最小成本还是最大收益A* 的启发函数必须满足一致性的单调条件否则搜出来的路径不一定是最优。5. 这30个算法最容易踩的5个坑现象、原因与解决办法5.1 数据没归一化粒子群第一轮迭代就发散现象PSO 跑出来的 gbest_val 是 inf 或者巨大负数每轮迭代结果毫无规律。原因粒子位置在多维空间里量纲差异大比如一个维度是 0.001 量级、另一个是 1000 量级速度更新时大数值维度直接淹没小数值维度位置直接飞出天际。解决在目标函数内部或外部先做 min-max 归一化把每个维度压到 0 到 1。如果赛题要求输出真实值反归一化只在最后做一次不要在迭代过程中来回切换。5.2 灰色预测外推步数太多曲线一路跳水现象GM(1,1) 对前几个点的拟合还不错到第 8 步、第 10 步预测值要么指数爆炸要么直接跌成负数画出的图没法交。原因灰色预测的实质是指数拟合它对纯指数趋势数据友好但对有波动、周期性或带噪声的数据短序列拟合出的发展系数 a 本身就不稳定外推越远误差被指数性质放大。解决严格限制外推步数在原始数据长度的三分之一以内超过就改用 ARIMA 或回归模型。另一点血泪经验GM(1,1) 的建模序列不要直接丢原始值先做一次滑动平均滤波去噪拟合结果更平滑。5.3 TOPSIS 没有区分指标方向正负理想解完全反了现象跑完 TOPSIS 排出来的第一名实际数据里各项指标都是最差的明显反了。原因TOPSIS 默认所有指标都是越大越好。赛题里常见成本型指标比如能耗、次品率、时长这些是越小越好直接把原始值丢进 min-max 归一化会让“越小越好”的指标被当作“越好”处理。解决先做指标正向化把成本型指标取倒数或取负值再统一走正向指标的归一化流程。我在每个评价类代码开头都会写一行data data.apply(lambda x: 1/x if metric_direction[x.name] cost else x)把指标方向显式维护成一个字典避免数据换列后翻车。5.4 随机森林没固定随机种子几分钟后结果对不上现象同一份数据同一套代码隔十分钟再跑一次准确率差了两个百分点写论文的时候现场复现和截图数值对不上。原因随机森林、K-means 初始化、BP 权重初始化都依赖随机数sklearn 里的模型默认随机种子是 None每次采样本、选特征都不同。解决在代码统一位置固定所有随机种子常见做法是np.random.seed(42)加random.seed(42)sklearn 的模型参数写random_state42。注意只固定主进程不行如果用到了 sklearn 的交叉验证还要把shuffle的随机种子一起固定。5.5 DBSCAN 的 eps 用默认值聚类结果几乎全是噪点现象跑官方示例里的默认 eps0.5结果聚类标签全是 -1一个有效簇都分不出来。原因DBSCAN 对 eps 极其敏感0.5 可能远小于实际数据的邻域尺度尤其在数据量纲是 0 到 1 的归一化后点之间的距离分布跟原始量纲完全不一样默认值没有任何参考意义。解决先对数据做标准化然后用 K-距离图定 eps。做法是算出每个样本到第 k 近邻的距离排序后画折线拐点对应的距离就是合理 eps。min_samples 从 2 倍特征维数起试簇太碎就降簇太大就升。6. 把这30个算法变成自己的备赛工具库批量自检与赛题复现6.1 用一段脚本批量自检全部算法别等到比赛当天才发现少个库解压后的包往往有几十个 .py比赛当天最尴尬的是某个算法脚本里 import 了一个只在 Linux 下能跑的库或者某个库版本升级后接口变了。我习惯拿到包里第一个动作是在虚拟环境里写一个循环把每个脚本都执行一遍能跑过的记 PASS。# 在 zip 解压后的目录里执行 for f in *.py; do if python $f /dev/null 21; then echo PASS: $f else echo FAIL: $f -- 看 error.log python $f 2 error.log fi done这个循环并不验证算得对只验证能跑通、依赖齐全。脚本里如果写了if __name__ __main__执行后还会顺带输出一份示例结果正好用来核对算法输出是否符合预期。第一次批量自检时FAIL 的文件十有八九是同一个原因代码里调用了已废弃的 sklearn API把sklearn.cross_validation改成sklearn.model_selection把train_test_split的test_size参数写法统一一遍就好了。6.2 赛题复现比看代码更有效用三套往年题验证工具库验证工具库是否合格最有效的不是从头读代码而是拿往年赛题直接套。比如 2012 年国赛葡萄酒评价题拿出评价数据表跑熵权法 TOPSIS看排序结果是否和当年优秀论文的趋势一致再比如某年小区开放对道路通行影响的题目用滑动平均滤波先清洗交通流数据再用聚类分析不同时段的车流模式。套上去不需要复现优秀论文的全部细节只需要看两点脚本能不能正常出结果、结果是否符合常识。如果三套题里有两套能顺利跑通并给出合理解释这个工具包就算合格了。剩下那些偏冷门的算法比如 KMP、归并排序我建议把它们单独放在一个「备用策略」目录里不用花时间调试真遇到字符串处理和排序性能瓶颈的题再回来翻。6.3 一点个人习惯赛前一周跑通核心算法给自己留后悔药我现在每次备赛前一周都会从 30 个算法里挑出预测、评价、优化、分类各两个核心算法重新跑一遍并截图保存。不是为了复习是防止比赛当天现场改代码。这个习惯救过我一次一次比赛当天发现粒子群代码里np.random.uniform的参数顺序写反如果没提前跑可能要在比赛前两小时才暴露。希望这些拆解和一个又一个小习惯能让你的备赛过程少一点慌乱多一点从容。希望帮到你。本文还有配套的精品资源点击获取