
1. 从“练习”到“实战”电子科大数模实验的进阶之路很多同学拿到“数学建模练习”或者“数学实验”的题目时第一反应往往是打开MATLAB照着题目要求把代码敲一遍跑出结果然后交差。如果你也是这么想的那可能就错过了这类练习最核心的价值。我当年在准备各类数模竞赛包括国赛、美赛时就曾把电子科技大学这类经典的数学实验题目当作“磨刀石”它们远不止是几个孤立的编程题。这些题目通常设计精巧背后隐藏着从问题抽象、模型构建、算法实现到结果分析的全链条思维训练。今天我就以一名过来人和多次带队参赛的指导者身份和你聊聊如何深度利用这类“练习”将其转化为你个人建模能力跃升的实战经验。这不仅仅是学会几个MATLAB函数更是掌握一套解决未知问题的科学方法论。2. 解构典型实验以“醉汉游走”与“微分方程”为例电子科技大学的数学实验题目覆盖面很广从基础的数值计算到复杂的系统仿真都有涉及。结合热词我们可以选取两个极具代表性的方向进行深度剖析随机过程模型如醉汉随机游走和动态系统模型如微分方程求解。这两个方向几乎贯穿了所有数模竞赛。2.1 醉汉随机游走模型从仿真到洞察“醉汉随机游走”Drunkard‘s Walk是一个经典的随机过程模型听起来简单却是理解布朗运动、股票价格模拟、算法搜索策略如蒙特卡洛方法的基石。在MATLAB中实现它绝不是简单写个循环生成随机数就完了。核心实现与参数化设计最基础的二维游走代码可能十来行% 基础参数设置 numSteps 10000; % 总步数 stepSize 1; % 每步长度 x zeros(numSteps1, 1); y zeros(numSteps1, 1); % 随机游走核心循环 for i 2:numSteps1 angle 2 * pi * rand(); % 生成0到2π的随机方向 x(i) x(i-1) stepSize * cos(angle); y(i) y(i-1) stepSize * sin(angle); end % 可视化 plot(x, y, ‘-b‘); hold on; plot(x(1), y(1), ‘go‘, ‘MarkerSize‘, 10, ‘MarkerFaceColor‘, ‘g‘); % 起点 plot(x(end), y(end), ‘ro‘, ‘MarkerSize‘, 10, ‘MarkerFaceColor‘, ‘r‘); % 终点 xlabel(‘X‘); ylabel(‘Y‘); title(‘2D Random Walk‘); axis equal; grid on;但作为“练习”到此为止就太可惜了。一个有价值的练习应该追问以下问题并用MATLAB探索答案均方位移Mean Squared Displacement, MSD醉汉走了N步后离起点的平均距离平方是多少理论告诉我们MSD与步数N成正比。你需要写代码计算多次模拟的MSD并绘制MSD ~ N的曲线验证这个线性关系。numSimulations 100; % 模拟次数 msd zeros(numSteps, 1); for sim 1:numSimulations % ... 执行一次随机游走得到x, y ... for n 1:numSteps msd(n) msd(n) (x(n1)^2 y(n1)^2); % 累积平方距离 end end msd msd / numSimulations; % 平均 plot(1:numSteps, msd, ‘LineWidth‘, 2); xlabel(‘步数 N‘); ylabel(‘MSD‘); title(‘均方位移分析‘);边界条件与吸收态如果游走是在一个有限区域如一个圆形或方形边界内进行碰到边界就停止被吸收那么平均生存步数是多少这引入了“吸收边界”的概念是很多物理和金融模型的简化。非各向同性游走如果醉汉更倾向于朝某个方向走比如有风如何修改模型这只需要在随机角度生成上加一个偏置即可但结果分析会完全不同。注意在模拟随机过程时rand()函数生成的是伪随机数。对于严格的科学研究或需要结果可复现的竞赛论文应使用rng函数固定随机数种子例如rng(42)这样每次运行都能得到完全相同的结果便于调试和论文重现。2.2 微分方程建模从定义到仿真“matlab中定义微分方程”是另一个核心技能。数模题目中涉及人口增长、传染病传播、生态系统动力学、电路瞬态响应等问题最终都会归结为微分方程组的求解。常微分方程ODE求解实战假设一个经典的SIR传染病模型S(t): 易感者I(t): 感染者R(t): 康复者β: 感染率γ: 康复率 其微分方程组为 dS/dt -β * S * I / N dI/dt β * S * I / N - γ * I dR/dt γ * I在MATLAB中我们首先需要将其转化为ODE求解器如ode45能识别的函数形式。% 文件sir_model.m function dydt sir_model(t, y, beta, gamma, N) % y(1)S, y(2)I, y(3)R S y(1); I y(2); dSdt -beta * S * I / N; dIdt beta * S * I / N - gamma * I; dRdt gamma * I; dydt [dSdt; dIdt; dRdt]; end然后进行求解和可视化% 主脚本 beta 0.3; % 感染率 gamma 0.1; % 康复率 N 1000; % 总人口 I0 1; % 初始感染者 S0 N - I0; R0 0; y0 [S0; I0; R0]; % 初始条件 tspan [0 200]; % 时间范围 [t, y] ode45((t,y) sir_model(t, y, beta, gamma, N), tspan, y0); % 绘图 plot(t, y(:,1), ‘b-‘, ‘LineWidth‘, 2, ‘DisplayName‘, ‘易感者 S‘); hold on; plot(t, y(:,2), ‘r-‘, ‘LineWidth‘, 2, ‘DisplayName‘, ‘感染者 I‘); plot(t, y(:,3), ‘g-‘, ‘LineWidth‘, 2, ‘DisplayName‘, ‘康复者 R‘); xlabel(‘时间‘); ylabel(‘人数‘); title(‘SIR传染病模型动态‘); legend(‘Location‘, ‘best‘); grid on;练习的深度延伸参数敏感性分析改变β和γ观察疫情峰值、持续时间如何变化。这能帮你理解什么是模型的“关键参数”。基本再生数R0在SIR模型中R0 β / γ。当R0 1时疫情会爆发R0 1时会自然消退。通过模拟验证这个理论阈值。模型变体考虑潜伏期SEIR模型、考虑疫苗接种SIRV模型。这锻炼了你根据实际问题修改模型结构的能力。使用meshgrid探索参数空间热词中提到了meshgrid这正是进行二维参数扫描的利器。例如同时扫描β和γ计算最终的感染总人数即R(∞)并绘制等高线图或三维曲面直观展示参数影响。[Beta, Gamma] meshgrid(linspace(0.1, 0.5, 30), linspace(0.05, 0.3, 30)); FinalR zeros(size(Beta)); for i 1:numel(Beta) % 对每一组(beta, gamma)运行SIR模型并提取最终的R值存入FinalR(i) % ... 此处需要将上面的求解过程封装成函数 ... end surf(Beta, Gamma, FinalR); xlabel(‘\beta‘); ylabel(‘\gamma‘); zlabel(‘最终康复人数‘);3. 数据处理与可视化让结果自己“说话”数模竞赛中清晰、专业、有信息量的图表是论文的“门面”。MATLAB的绘图系统非常强大但用好它需要技巧。3.1 精细化绘图以“截断横坐标”和“RGB画线”为例横坐标截断Break Axis当数据在某个区间存在剧烈变化或异常值导致大部分数据挤在一起时需要截断坐标轴。MATLAB没有内置函数但可以通过创建两个重叠的坐标系来实现。% 假设有一组数据x在0-100但0-10区间变化剧烈10-100平缓 x 0:0.1:100; y [exp(-x(1:101)/2), 0.1*sin(x(102:end)/10)0.05]; % 示例数据 figure(‘Position‘, [100,100,800,400]) % 创建第一个坐标系画左边部分 ax1 axes(‘Position‘, [0.1 0.15 0.35 0.75]); plot(ax1, x(1:101), y(1:101), ‘b-‘, ‘LineWidth‘, 1.5); xlim(ax1, [0 10]); ylabel(‘Y值‘); title(‘数据细节0-10区间‘); grid(ax1, ‘on‘); % 创建第二个坐标系画右边部分 ax2 axes(‘Position‘, [0.55 0.15 0.35 0.75]); plot(ax2, x(102:end), y(102:end), ‘b-‘, ‘LineWidth‘, 1.5); xlim(ax2, [10 100]); title(‘数据整体10-100区间‘); grid(ax2, ‘on‘); % 隐藏ax2的左侧Y轴使其与ax1对齐 ax2.YAxisLocation ‘right‘; linkaxes([ax1, ax2], ‘y‘); % 链接Y轴范围确保尺度一致 % 在两个坐标系之间画上截断符号// annotation(‘line‘, [0.465 0.475], [0.3 0.7], ‘LineWidth‘, 2, ‘Color‘, ‘k‘); annotation(‘line‘, [0.48 0.49], [0.3 0.7], ‘LineWidth‘, 2, ‘Color‘, ‘k‘);这个技巧在展示具有不同数量级特征的数据时非常有用能让评委一眼抓住重点。用RGB颜色画线plot函数可以直接接受RGB三元组来指定颜色这比使用‘r‘, ‘b‘等预设颜色更灵活尤其当需要绘制多条线并精确控制其颜色梯度时。x linspace(0, 2*pi, 100); numLines 5; % 创建一个从蓝色到红色的颜色梯度 colors [linspace(0,1,numLines)‘, zeros(numLines,1), linspace(1,0,numLines)‘]; figure; hold on; for i 1:numLines y sin(x) 0.2*i; % 每条线稍有偏移 plot(x, y, ‘Color‘, colors(i,:), ‘LineWidth‘, 2, ... ‘DisplayName‘, sprintf(‘Line %d‘, i)); end hold off; xlabel(‘X‘); ylabel(‘Y‘); legend(‘show‘); colormap(colors); % 可选使colorbar与线条颜色对应 colorbar(‘Ticks‘, linspace(0,1,numLines), ‘TickLabels‘, {‘Line1‘, ‘Line2‘, ‘Line3‘, ‘Line4‘, ‘Line5‘});通过精细控制颜色、线型、标记点你可以制作出出版物级别的图表极大提升论文的可读性和专业性。3.2 统计分析与假设检验ttest与ttest2辨析热词中提到了ttest和ttest2这是数据分析中验证结论可靠性的关键。很多同学会混淆。ttest单样本或配对t检验用于比较一组数据的均值是否与某个理论值有显著差异或者比较两组配对数据的均值差是否显著如同一组人服药前后的血压值。它关注的是“差异本身”。ttest2双样本t检验用于比较两个独立样本组的均值是否有显著差异如男生组和女生组的数学成绩。它假设两组数据相互独立。实战场景假设你研究两种教学方法A和B对学生成绩的影响。如果你让同一批学生先后接受两种方法教学然后比较他们的成绩这是配对样本应该用ttest检验成绩差的均值是否为0。scores_A [85, 88, 78, 92, 80]; % 方法A的成绩 scores_B [88, 90, 85, 95, 83]; % 同一批学生方法B的成绩 [h, p] ttest(scores_A, scores_B); % h1拒绝原假设有显著差异p是p值 fprintf(‘配对t检验: h%d, p%.4f\n‘, h, p);如果你随机分配两批不同的学生分别接受方法A和B然后比较两组的平均成绩这是独立样本应该用ttest2。scores_A_ind [85, 88, 78, 92, 80]; % 组A学生成绩 scores_B_ind [82, 85, 90, 87, 84]; % 组B学生成绩不同的人 [h2, p2] ttest2(scores_A_ind, scores_B_ind); fprintf(‘独立样本t检验: h%d, p%.4f\n‘, h2, p2);在建模论文中任何基于数据比较得出的结论如“优化后效率显著提升”都应辅以相应的统计检验结果p值否则结论缺乏说服力。4. 效率提升与高级技巧告别蛮力计算当模型复杂、数据量大时计算效率成为瓶颈。掌握以下技巧能让你的代码运行速度提升一个数量级。4.1 向量化编程抛弃for循环MATLAB的底层是矩阵运算向量化操作比循环快得多。例如计算一个矩阵所有行向量的欧氏距离% 低效的循环写法 A rand(1000, 100); % 1000个100维向量 dist_loop zeros(1000, 1000); for i 1:1000 for j 1:1000 dist_loop(i,j) sqrt(sum((A(i,:) - A(j,:)).^2)); end end % 高效的向量化写法利用广播机制 % 计算每对向量差平方和 (a-b)^2 a^2 b^2 - 2ab AA sum(A.*A, 2); % 每行元素的平方和形状(1000,1) AB A * A‘; % 所有行向量点积形状(1000,1000) dist_vec sqrt(AA AA‘ - 2*AB); % 利用广播AA是列向量AA‘是行向量 % 验证结果是否一致在浮点误差内 max(abs(dist_loop(:) - dist_vec(:))) % 应该是一个非常小的数对于简单的随机游走也可以向量化numSteps 10000; angles 2 * pi * rand(numSteps, 1); % 一次性生成所有随机角度 steps [cos(angles), sin(angles)]; % 每步的位移向量 positions cumsum([0,0; steps]); % 累积求和得到路径比循环快很多4.2 并行计算parfor内核还是逻辑处理器热词提到了parfor的分配问题。parforParallel for-loop可以将循环迭代分配到多个CPU核心上并行执行。按逻辑处理器分配这是默认行为。MATLAB的并行池parpool会尝试使用所有可用的逻辑核心包括超线程产生的虚拟核心。对于计算密集型但内存访问不密集的任务这通常能带来接近线性核心数的加速。按物理内核分配如果你怀疑超线程带来的收益不大或者任务严重依赖内存带宽可能导致虚拟核心争抢资源可以手动设置并行池使用更少的worker等于物理核心数。% 获取物理核心数可能需要系统命令这里是一种近似方法 numPhysicalCores feature(‘numcores‘); % 注意这个函数返回的可能不是物理核心数需结合系统信息判断 % 更可靠的方法是查询CPU信息但跨平台较复杂。通常对于现代CPU直接使用默认设置即可。 % 创建指定worker数量的并行池 if isempty(gcp(‘nocreate‘)) parpool(‘local‘, 4); % 例如指定4个worker end % 使用parfor n 100; parfor i 1:n % 执行一些独立计算 result(i) someExpensiveFunction(i); end实操心得parfor不是万能的。它要求循环迭代之间是独立的一次迭代的结果不依赖于另一次迭代。如果循环体内部有文件读写、图形绘制等操作并行化可能带来问题或性能下降。通常先优化算法和向量化如果仍有瓶颈且循环可并行再考虑使用parfor。4.3 大数据处理巧用matfile与内存映射当数据量超过内存时不能一次性加载。MATLAB的matfile函数允许你像访问普通变量一样访问.mat文件中的部分数据。% 假设有一个巨大的矩阵保存在‘bigData.mat‘文件的变量‘X‘中 % 方式1直接加载会内存溢出 % load(‘bigData.mat‘, ‘X‘); % 危险 % 方式2使用matfile对象进行部分加载 m matfile(‘bigData.mat‘, ‘Writable‘, false); % 仅加载前100行所有列 dataChunk m.X(1:100, :); % 或者加载特定范围 dataPatch m.X(5000:6000, 2000:3000);对于超大型矩阵的逐块处理例如分块计算均值、方差这是必不可少的技巧。5. 从实验到竞赛构建你的建模工作流最后我们来谈谈如何将这些分散的“练习”技能整合成一套应对数学建模竞赛的完整工作流。第一步问题拆解与文献检索第一天上午拿到赛题后不要急于打开MATLAB。先用1-2小时将题目翻译成具体的数学问题。例如“预测城市交通流量”可能涉及时间序列分析ARIMA, LSTM、图网络道路网络、或基于代理的仿真。同时利用“数学建模优秀论文”、“国赛2019年c题优秀论文”等关键词快速检索类似问题的经典解法获取灵感。记住站在巨人肩膀上。第二步模型选择与原型搭建第一天下午至晚上根据问题特征选择1-2个最有希望的模型方向。用MATLAB快速搭建原型Prototype。这个阶段的目标是验证可行性而不是追求完美。使用小规模、合成的或部分真实数据跑通整个流程数据导入 - 预处理 - 模型计算 - 结果输出。如果原型都跑不通说明模型或算法假设可能有问题需要及时调整方向。第三步数据深挖与模型调优第二天在原型可行的基础上使用全部数据并开始精细调整。数据预处理处理缺失值、异常值、标准化/归一化。MATLAB的fillmissing,rmoutliers,zscore等函数是利器。参数调优对于有参数的模型如机器学习模型中的超参数设计实验网格搜索用meshgrid或使用优化算法如fmincon,bayesopt寻找最优组合。模型验证务必划分训练集/测试集或使用交叉验证cvpartition避免过拟合。用ttest/ttest2等统计方法严谨地比较不同模型的性能差异。第四步仿真分析与可视化呈现第三天上午对最优模型进行全面的仿真分析。敏感性分析改变关键输入参数观察输出结果的变化用曲面图、等高线图展示。场景模拟运行模型在各种假设场景下的表现。故事线图表绘制最能支撑你核心结论的图表。一张信息量丰富的图胜过千言万语。确保每张图都有清晰的标题、坐标轴标签、图例并注意配色美观。第五步论文撰写与结果整合第三天下午至晚上将代码、图表、分析结论整合到论文中。MATLAB的publish功能或实时脚本.mlx可以帮你将代码、运行结果和说明文字生成漂亮的报告草稿。但最终论文应在Word或LaTeX中精心排版。确保模型描述、算法步骤、结果分析环环相扣逻辑严密。在整个过程中文件管理至关重要。建议建立清晰的文件夹结构Project_2026APMCM_B/ ├── code/ │ ├── data_preprocessing.m │ ├── model_prototype.m │ ├── model_final.m │ └── visualization.m ├── data/ │ ├── raw/ │ └── processed/ ├── figs/ (保存所有生成的图表格式为 .png 和 .eps) ├── docs/ (存放参考文献、赛题) └── paper/ (论文草稿)使用版本控制如Git管理代码变更也是一个好习惯虽然竞赛时间紧但至少能避免误删文件。回过头看电子科技大学的数学实验题目就像一个个设计好的“零件加工车间”。当你不再满足于仅仅做出题目要求的“零件”而是主动去研究这个“零件”为什么这么设计、它在更大的“机器”完整模型中起什么作用、还有没有更好的“加工工艺”算法时你就完成了从被动练习到主动实战的关键转变。这些实验题目中的每一个知识点——随机游走、微分方程、统计检验、高效编程——都不是孤立的它们是你构建复杂数学模型、解决实际竞赛问题的砖瓦。真正的准备始于把每一次练习都当作一次微型的竞赛来对待。