ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

数学建模竞赛攻略:水系电解液配方优化与多目标建模实战

2026/9/16 2:25:52 拓冰建站 浏览量
数学建模竞赛攻略:水系电解液配方优化与多目标建模实战 认证杯的A题出来了题目叫水系电解液配方。群里不少同学第一反应是完了这是化学题我学的是计算机/金融/机械配方这东西根本看不懂。别急数学建模比赛从来不是考专业知识它考的是你面对一个陌生领域时能不能快速找到建模思路、搞到数据、写出代码、把结果包装成一篇能看的论文。这题表面上是个材料学问题实际上就是非常典型的配方优化类问题跟奶茶店调配方、钢厂调合金成分本质上一回事。这篇东西我按历年A题的套路和这次标题透露的信息把完整解题框架、代码实现和论文写作顺序全部拆给你适合今年参赛的队伍直接参考也适合想系统学配方优化题型的同学收藏。1. 赛题解读这道题到底在考什么1.1 从标题拆出三个关键词“水系电解液配方”这七个字可以拆成三个层次来理解。第一层是“水系”。水系电解液这两年特别火锌离子电池、水系液流电池都在用核心卖点就是安全、便宜、不燃烧比有机电解液环保得多。它对应到题目里其实是在约束你的优化空间告诉你不要考虑那些易燃易爆的有机溶剂体系老老实实在水溶液里做文章。第二层是“电解液”。电解液是电池的“血液”负责离子传输它的性能直接决定电池的功率密度、循环寿命和安全性能。题目里大概率会给出某些性能要求比如离子电导率、黏度、电化学稳定窗口、析氢析氧过电位这些让你在限定条件下找到能用的配方。第三层是“配方”。配方就是决策变量比如主盐的种类和浓度、添加剂的种类和用量、pH值、温度可能还有不同溶剂的比例。你的任务就是找到一组配方参数让电解液的各项性能尽量同时达标。我虽然没有拿到题目官方的PDF原文但根据以往认证杯和同类赛题的习惯A题大概率会包含这样几个子问第一问让你建立“配方→性能”的数学模型第二问给你设定优化目标比如高电导率、低黏度、低成本让你给出推荐配方第三问可能让你分析方案的稳定性或者讨论某个添加剂的影响。拿到题之后先花半小时把这几件事对应上后面就不容易跑偏。1.2 问题归类与难度评估这类题目在数学建模里可以归为“黑箱优化问题”更具体地说是“多目标约束优化问题”。什么叫黑箱就是你只知道输入配方输出性能但中间物理化学机理非常复杂你没法用几行微分方程把离子迁移、溶剂化、界面反应全描述清楚。所以就不要费力去推机理模型用数据驱动的方式建立输入到输出的映射关系是性价比最高的选择。从难度上说这题的坑不在模型而在数据和约束。数据处理量不大但很脏因为文献里的数据来自不同课题组测试条件不一致你需要自己做归一化和清洗。约束条件才是真正卡人的地方比如盐浓度太高就析出添加剂太多会影响黏度pH值太极端会腐蚀集流体这些工程约束只要你漏掉一个评委一眼就能看出来你的方案脱离实际。但换个角度这题的得分点也很清晰建模方法完整、优化逻辑清晰、结果有对比分析、灵敏度分析到位。做到这四点国二以上的水平基本就有了。所以别被化学名词吓退把它当成一个带约束的多目标优化题去打就行。1.3 评委想看什么明确一下评委的打分偏好这比盲目堆模型重要得多。第一摘要必须直接给出结论。评委每天看几十篇论文你的摘要如果三句话还没说到推荐配方是什么、性能提升多少基本就进不了第一梯队。第二模型要有“可复现性”。不要写那种“利用深度学习模型预测性能”却连训练集多少条、特征是什么、参数怎么调的都不交代。你要让评委觉得给他同样的数据他按你的方法也能复现出结果。第三创新点不用太大但要能说清楚。比如你用随机森林建立了代理模型再用NSGA-II做多目标寻优这个组合不算新鲜但如果你在约束处理上做了改进或者用SHAP值分析了各因素对性能的贡献这就是可以写进论文的亮点。第四图表要精致。数学建模比赛的论文不是实验报告图的表达力直接决定评委对你工作的第一印象。Pareto前沿图、灵敏度扫描图、预测值与真实值对比图这三张图必须有而且必须出现在正文不是塞在附录里。2. 整体建模思路先想清楚再动手2.1 配方类题目的通用三段式解法打多了就会总结出来配方优化类题目有一套几乎固定的三段式套路先建立从配方到性能的映射模型再在可行域内做寻优最后做决策分析选出推荐方案。第一段是“预测”。给定一组配方你要能预测出它的离子电导率、黏度、循环寿命等性能指标。可以用传统的响应面法也可以上机器学习模型关键是把误差控制在做决策可接受的范围内。第二段是“寻优”。在配方可行域内找到同时让多个目标尽量优的方案。这里就涉及多目标优化因为高电导率和低黏度常常是矛盾的盐多一点电导率上升但黏度也上升你需要找到一整条权衡曲线也就是Pareto前沿。第三段是“决策”。Pareto前沿上有一堆解到底选哪个这时候要根据题目给定的偏好比如更看重安全性和循环寿命或者更看重成本把多目标通过权重或者约束转化为单目标挑出最终推荐配方。这三段式几乎是通吃的。无论是电解液配方、合金成分配比、食品配方乃至物流路径优化思维框架都一样区别只是具体变量和目标函数不同。2.2 为什么选择“数据驱动多目标优化”路线我见过不少队伍一上来就想写机理模型翻各种电化学教材试图推导离子电导率跟浓度的关系式。最后结果往往是模型假设太多跟真实数据对不上还花了大量时间。我的建议是比赛阶段不要死磕机理模型。原因有三第一水系电解液体系本身很复杂离子间相互作用、溶剂化结构、添加剂与电极的界面反应这些机理哪怕在学术论文里也还在争论你三天时间推不出来第二评委考察的重点是你的建模能力和分析能力而不是你电化学知识有多深第三数据驱动模型在样本量合适的情况下拟合精度远比简化机理模型高而且在论文里更好讲故事。当然完全抛弃机理也不行。你可以用一点电化学的半经验规律来辅助生成数据、判断量纲是否合理这在第三部分会细说。整体的技术路线建议是文献数据收集整理随机森林或XGBoost做代理模型NSGA-II或差分进化做多目标寻优最后用灵敏度分析和Pareto前沿做决策。2.3 技术路线图与时间分配数学建模比赛时间紧节奏不能乱。以最常见的三天赛程为例我给一个比较稳的时间分配方案。第一天上午只做一件事把题目读透拆解出决策变量、目标函数、约束条件然后全员分头去收集文献数据。第一天下午到晚上完成数据清洗和特征工程跑通第一个版本的代理模型。这里有一个关键原则第一版模型能跑通就行了不要追求精度先保证代码流程没问题后面再慢慢调。第二天主攻优化。把代理模型封装成目标函数写优化代码跑出Pareto前沿顺便把灵敏度和单因素分析做出来。第二天晚上所有核心结果都应该出来了。记住数学建模比赛最大的坑就是第三天下午还在跑程序结果论文没时间写。第三天全天留给论文。早上写摘要和问题分析下午写模型建立和求解过程晚上画图表、排版、检查错别字和公式。如果第三天中午还能挤出时间可以把模型参数再微调一轮用新结果替换旧图表但千万不要在这个阶段改模型结构很容易翻车。3. 数据从哪里来没有试验数据时的破局方法3.1 文献数据挖掘是第一步拿到题目最慌的就是没有数据。其实水系电解液方向文献很多尤其是锌离子电池相关的综述论文里经常会有“配方-性能对照表”比如不同浓度硫酸锌溶液的离子电导率测试结果不同添加剂含量下的循环寿命数据。我的做法是团队三个人分头去搜索引擎上找带数据的综述文章用“aqueous electrolyte conductivity zinc sulfate concentration”这种关键词去搜下载PDF后用表格提取工具把数据扒出来。实在找不到表格的直接从论文里的曲线图用在线工具读点虽然精度差一些但用来训练模型够了。目标样本量不要贪多20到50条有效数据就能支撑起一个随机森林模型。当然如果题目本身给了数据文件那就直接用把重心放在特征工程和模型调优上。注意记录每条数据的来源论文里要写清楚数据来源和筛选标准这既是学术规范也能体现你做工作的严谨程度。3.2 用半经验关系做数据增强文献数据往往不够而且分布不均匀。这时候可以用电化学的一些半经验关系做数据增强前提是你要在论文里明确说明这些数据是根据已知经验关系生成的属于模型假设的一部分。举个例子稀溶液的摩尔电导率跟浓度的平方根近似满足科尔劳施定律但在高浓度区间会偏离描述溶液黏度跟浓度的关系可以用Jones-Dole经验式。用这些关系你可以生成一批覆盖完整浓度范围的补充样本再跟文献实测数据合并让代理模型学到更光滑的响应面。不过我得提醒一句数据增强只是辅助手段不能喧宾夺主。生成的样本占比最好控制在三分之一以内否则模型会被“假数据”带偏论文也容易被评委质疑。比赛里用过这招的都知道这属于“灰色操作”但合理引用为模型假设和先验知识约束逻辑上是站得住的。3.3 数据清洗与特征工程决定了模型上限同样一批数据会做特征工程的人能建模到90分的水平不会做的人可能只有70分。电解液配方数据常见的坑有三个。第一个是单位不统一。有的文献浓度用 mol/L有的用 mol/kg有的直接用质量分数必须统一换算。我一般全部换算成 mol/L因为跟电导率的经验公式对得上。第二个是温度条件不一致。电导率和黏度对温度非常敏感文献里25度和30度测的数据不能直接混用。要么只保留一个温度条件下的数据要么把温度作为特征输入。强烈建议把温度作为特征这样后面做灵敏度分析时还能多一个维度。第三个是离群值处理。文献数据来自不同课题组测试误差本来就大偶尔会出现离谱的点。我习惯用箱线图先筛一遍对明显离群的样本做标记再结合化学常识判断要不要删掉。比如某个数据点电导率比其他同浓度样本高出一倍那八成是抄录错误直接删。特征工程方面除了盐浓度、添加剂含量、pH值、温度这些原始特征还可以构造交互特征比如“盐浓度乘以温度”或者“盐浓度的平方”。随机森林这类树模型对交互特征的依赖不大但如果你后面换成线性回归或者神经网络交互特征会很管用。4. 模型构建与代码实现把思路跑通4.1 代理模型选型为什么优先选随机森林代理模型就是用来替代真实实验的预测器。可选方案有线性回归、支持向量回归、随机森林、XGBoost、神经网络。我的建议是优先上随机森林原因很实在小样本下表现稳定不需要繁琐的特征缩放超参数少不容易过拟合而且能输出特征重要性这在论文里是一个现成的分析点。神经网络在这个场景下我不推荐。电解液配方数据通常就几十条神经网络在这种数据量下非常容易过拟合调参又费时间比赛期间性价比很低。如果你的数据量能到几百条那可以考虑XGBoost性能会略好于随机森林。下面给一个可以直接跑的随机森林代理模型代码框架。import pandas as pd import numpy as np from sklearn.ensemble import RandomForestRegressor from sklearn.model_selection import train_test_split from sklearn.metrics import mean_absolute_error, r2_score # 假设 df 是清洗后的数据 df pd.read_csv(electrolyte_data.csv) # 特征与目标按实际情况改列名 features [salt_concentration, additive_ratio, temperature, ph] targets [conductivity, viscosity] X df[features] y df[targets] X_train, X_test, y_train, y_test train_test_split( X, y, test_size0.2, random_state42 ) model RandomForestRegressor( n_estimators300, max_depth8, min_samples_leaf2, random_state42 ) model.fit(X_train, y_train) pred model.predict(X_test) print(R2:, r2_score(y_test, pred, multioutputraw_values)) print(MAE:, mean_absolute_error(y_test, pred, multioutputraw_values))这里有几个细节需要注意。max_depth设成8左右不要用默认的无限深度否则几十条数据会被完全记住测试集分数会很难看。min_samples_leaf设成2或者3可以防止叶子节点样本太少导致预测跳变。训练完成后把特征重要性打出来看一眼importance pd.Series(model.feature_importances_, indexfeatures).sort_values() importance.plot(kindbarh)如果发现某个特征重要性几乎为零比如添加剂对于电导率的影响可有可无这本身就是论文里可以写的发现。4.2 多目标优化实现用NSGA-II找Pareto前沿代理模型建好之后接下来就是寻优。如果题目只有一个优化目标比如“给定成本约束下电导率最大”那直接用scipy的差分进化就行。如果题目是多目标比如要同时优化电导率和黏度那建议用NSGA-II画出Pareto前沿。用Python的pymoo库来实现NSGA-II非常方便安装命令是pip install pymoo。如果比赛环境不能联网提前在自己电脑上装好库然后在论文附录里写清楚环境依赖。下面是核心代码框架import numpy as np from pymoo.core.problem import Problem from pymoo.algorithms.moo.nsga2 import NSGA2 from pymoo.optimize import minimize from pymoo.operators.crossover.sbx import SBX from pymoo.operators.mutation.pm import PM from pymoo.operators.sampling.rnd import FloatRandomSampling # 决策变量盐浓度、添加剂含量、温度、pH xl np.array([0.5, 0.0, 20.0, 3.5]) xu np.array([3.0, 5.0, 60.0, 6.5]) class ElectrolyteProblem(Problem): def __init__(self, model): super().__init__( n_var4, n_obj2, n_constr1, xlxl, xuxu ) self.model model def _evaluate(self, x, out, *args, **kwargs): # x 形状是 (n_samples, 4) pred self.model.predict(x) # 假设返回 [electrolyte_concentration, conductivity, viscosity] 之类 # 目标1电导率取负号是最大化转最小化 f1 -pred[:, 0] # 目标2黏度直接最小化 f2 pred[:, 1] # 约束盐浓度 添加剂含量不能超过某个上限比如总量限制 g1 x[:, 0] x[:, 1] * 0.1 - 4.0 out[F] np.column_stack([f1, f2]) out[G] g1.reshape(-1, 1) problem ElectrolyteProblem(model) algorithm NSGA2( pop_size100, samplingFloatRandomSampling(), crossoverSBX(prob0.9, eta15), mutationPM(prob0.1, eta20), eliminate_duplicatesTrue ) res minimize( problem, algorithm, (n_gen, 200), seed42, verboseFalse ) X_pareto res.X F_pareto res.F跑完之后把Pareto前沿画出来一般是二维散点图横轴是某个目标纵轴是另一个目标你会看到一条往左下角凹的曲线。把这条曲线放进论文配一段文字解释“A点对应的方案电导率最高但黏度过大B点方案黏度最低但电导率不达标C点位于膝点位置综合性能最优因此推荐C点配方”。如果队伍里没人用过pymoo怕出问题还有一个备选方案把多目标用加权法合成单目标然后用scipy的differential_evolution来优化。方法简单粗暴但需要做多次不同权重扫描才能近似出Pareto前沿。from scipy.optimize import differential_evolution w1 0.7 w2 0.3 def combined_objective(x): pred model.predict([x])[0] conductivity pred[0] viscosity pred[1] return -(w1 * conductivity - w2 * viscosity) bounds [(0.5, 3.0), (0.0, 5.0), (20.0, 60.0), (3.5, 6.5)] result differential_evolution(combined_objective, bounds, seed42) print(最优配方:, result.x) print(最优目标值:, -result.fun)这个方法的好处是不依赖额外库缺点是只能得到单点解画不出漂亮的前沿图。我的建议是主力用pymoo如果装不上库再用scipy顶替。4.3 灵敏度分析与可视化让论文有血有肉优化完成之后不要急着写论文先做一轮灵敏度分析。这是提升论文档次的性价比最高的一步。方法很简单固定其他变量在推荐配方处单独扫描某一个变量在其取值范围内的变化记录目标函数的变化曲线。比如固定盐浓度、添加剂、pH在最优值把温度从20度扫到60度看电导率怎么变。代码如下import matplotlib.pyplot as plt base result.x.copy() temp_range np.linspace(20, 60, 30) cond_list [] visc_list [] for t in temp_range: x_try base.copy() x_try[2] t pred model.predict([x_try])[0] cond_list.append(pred[0]) visc_list.append(pred[1]) fig, ax1 plt.subplots() ax1.plot(temp_range, cond_list, colortab:red, labelconductivity) ax1.set_xlabel(Temperature (°C)) ax1.set_ylabel(Conductivity, colortab:red) ax2 ax1.twinx() ax2.plot(temp_range, visc_list, colortab:blue, labelviscosity) ax2.set_ylabel(Viscosity, colortab:blue) plt.tight_layout() plt.savefig(sensitivity_temp.png, dpi300)这组图放进论文后你可以得出类似这样的结论“电导率随温度上升近似线性增加但黏度在40度以后下降趋缓考虑到安全性和长期循环稳定性推荐工作温度设定在35度附近而不是追求最高电导率的60度。”这种有取舍的分析比单纯报一个优化结果有说服力得多。另外如果用了随机森林特征重要性图也很适合放进问题分析章节用来回答“哪个因素对电解液性能影响最大”这类问题。多数情况下你会看到盐浓度的重要性排第一然后是温度添加剂和pH的影响相对较小。这个结论要正面回答不要回避。5. 论文写作从算法到获奖论文的最后一公里5.1 摘要用三段话把全部亮点讲完摘要的重要性我再强调也不为过。评委很可能先看摘要再看图表最后才扫正文。摘要写不好后面模型再漂亮也可能被埋没。我的摘要模板是这样的。第一段写问题背景和你干了什么“针对水系电解液配方优化问题本文构建了数据驱动的配方性能预测模型与多目标寻优框架。”一句话点题。第二段写具体方法和关键步骤“首先收集并整理了公开发献中的XX组电解液配方与性能数据采用随机森林建立配方到电导率、黏度的映射模型测试集R2达到0.91。其次以盐浓度、添加剂含量、温度和pH为决策变量以最大化电导率、最小化黏度为优化目标使用NSGA-II算法求得Pareto前沿。最后通过灵敏度分析讨论了各因素对性能的影响。”第三段写结论“在综合考虑离子电导率、黏度与安全性后推荐配方为硫酸锌浓度1.2 mol/L、添加剂质量分数0.8%、工作温度30℃、pH4.5。该配方下电导率预测值为XX mS/cm相比基准配方提升约XX%黏度满足预期约束。”注意摘要里必须出现具体数字。没有数字的摘要等于白写。哪怕你的数字是预测值也要写出来因为这说明你跑完了整条流程。5.2 模型假设与符号说明不要让评委抓你漏洞论文里模型假设不能随便写每条假设都要经得起推敲。水系电解液这个题比较合理的假设有这么几条第一假设各组分混合均匀忽略局部浓度梯度。这是所有配方模型的前提不然没法建立全局映射关系。第二假设在常温常压附近压力对电导率和黏度的影响可以忽略。水溶液体系这个假设基本成立。第三假设文献数据来自不同测试条件但通过温度特征引入和归一化处理可以认为数据具有可比性。这条假设是给你的数据处理“打圆场”的一定要写。第四假设添加剂在设定浓度范围内不与主盐发生沉淀等副作用。如果你优化出来的添加剂含量很高这个假设就要谨慎最好在模型里加一个约束防止添加剂含量超出溶解极限。符号说明表放在模型建立之前用三线表列出所有变量和单位。这既方便评委阅读也能让正文公式更简洁。符号表不用太多一般十来个就够。5.3 图表、代码与附录的规范图表有几个硬性要求。每张图必须在正文中有文字引用比如“如图4所示”不能出现“如下图所示”这种指向不明的表述。所有坐标轴必须有物理量和单位曲线要有图例图的分辨率至少300dpi。三张核心图必须有数据相关性热力图或特征重要性图、模型预测效果对比图、Pareto前沿图。再加一到两张灵敏度分析图整体就非常完整了。代码不要全部塞进正文。正文里保留关键算法伪代码或者核心代码片段完整代码放到附录并在正文中说“完整代码见附录A”。评委下载论文后大概率不会真的去跑你的代码但附录里有没有代码直接影响他们对你这篇工作是否“完整”的评价。6. 常见问题与排查技巧实录6.1 高频翻车点代码跑不通。这是最常见的常见原因有三个pymoo库版本不匹配、特征列名对不上、目标函数里预测维度写错。排查方法很简单写代码时每步都print一下数组形状从读取数据到预测结果保证每一步的形状都是(n_samples, 4)这样的合理形状。优化结果全是边界值。如果你发现最优解永远贴着某个变量的上下限比如盐浓度直接顶到3.0的上限那说明目标函数有问题或者数据里最优区域确实在边界外。这时要么扩大变量范围要么检查数据是否覆盖了边界区域。如果加了约束但约束函数写错方向也会出现这种情况务必检查不等式符号方向。预测性能标方差。随机森林跑出来的R2如果只有0.5左右先别急着调参回头检查数据里有没有离群点温度和浓度单位是否统一。绝大多数预测分低的问题出在数据而不是模型。时间不够用。这题最大的风险就是模型调参上瘾反复调参一整天就没了。我的建议是随机森林初始参数直接跑不理想就检查数据优化算法用默认参数跑一遍先出图看趋势再决定要不要加迭代次数。能出图的结果就是能写论文的结果先保住下限。6.2 我踩过的坑有一年我打类似题目前两个问题都顺利第三问要求分析“添加剂对循环寿命的影响”但我手里循环寿命的数据只有五条模型根本训不动。当时的解决办法是退而求其次用文献里的趋势描述简化成单调关系假设加上电导率和黏度的代理模型做了一轮模拟分析。结果虽然不完美但好歹把问题答了比交白卷强。这给我的教训是遇到数据不足的子问不要硬上复杂模型用合理假设加简化分析照样能拿分。另一个坑是过于迷信优化算法。有一版结果Pareto前沿特别漂亮但仔细一对照化学常识发现其中一个配方点的盐浓度已经超过溶解度现实中根本配不出来。后来我养成了习惯每次优化完都把结果打印出来对照化学常识检查一遍。在模型里增加溶解度和总浓度约束就不会再出现这种低级错误。还有一个团队配合的坑。有一次写论文的同学和写代码的同学对变量名没有统一论文里写的是“salt_concentration”代码里写的是“concentration”最后画图的时候全乱套。从那以后我都要求团队在第一天就敲定变量命名规范统一以代码里的变量名为准。给今年参赛的同学一个建议比赛最重要的是流程完整从数据到模型到优化到论文每一步都做到60分总分就比那些某一步做到100分但全流程断掉的队伍高得多。遇到完全不懂的领域名词先跳过去把它当成一个普通优化问题来处理你会发现一切都没那么难。