文章目录
文章目录
01 内容概要
本资料集合了多种数学建模和优化算法的常用代码资源,旨在为参与美国大学生数学建模竞赛(MCM/ICM,简称美赛)的参赛者提供实用的编程工具和算法实现。这些算法包括BP神经网络、CT图像重建、Floyd算法、Topsis算法、层次分析法、分支定界法、灰色预测、粒子群算法、模拟退火算法(特别适用于TSP和背包问题)、人口增长模型以及搜索和遗传算法。这些算法覆盖了从机器学习到优化问题的广泛领域,为解决复杂问题提供了多样化的方法。
02 各种算法基本原理
1. BP神经网络
- 基本原理:BP神经网络是一种按误差反向传播训练的多层前馈网络,其算法称为BP算法。基本思想是梯度下降法,利用梯度搜索技术,以期使网络的实际输出值和期望输出值的误差均方差为最小。基本BP算法包括信号的前向传播和误差的反向传播两个过程。即计算误差输出时按从输入到输出的方向进行,而调整权值和阈值则从输出到输入的方向进行。正向传播时,输入信号通过隐含层作用于输出节点,经过非线性变换,产生输出信号,若实际输出与期望输出不相符,则转入误差的反向传播过程。误差反传是将输出误差通过隐含层向输入层逐层反传,并将误差分摊给各层所有单元,以从各层获得的误差信号作为调整各单元权值的依据。通过调整输入节点与隐层节点的联接强度和隐层节点与输出节点的联接强度以及阈值,使误差沿梯度方向下降,经过反复学习训练,确定与最小误差相对应的网络参数(权值和阈值),训练即告停止。此时经过训练的神经网络即能对类似样本的输入信息,自行处理输出误差最小的经过非线形转换的信息。
2. CT图像重建 - 基本原理:CT图像重建是通过投影数据重建物体内部结构的过程。常用的算法包括滤波反投影(FBP)算法。FBP算法通过在频域对投影函数乘上一个高通滤波器来抵消直接反投影算法带来的误差,然后进行反投影重建。随着科技的发展,CT重建算法大致分为传统重建算法、迭代重建算法和深度学习算法三类。传统重建算法基于FBP,迭代重建算法根据实时采集到的探测器数据对预测图像进行迭代优化,而深度学习算法则利用深度学习技术来提高图像质量和降低辐射剂量。
3. Floyd算法 - 基本原理:Floyd算法是一种利用动态规划思想寻找给定加权图中多源点之间最短路径的算法。它通过不断“插点”的方式,更新节点之间的最短路径。对于节点i和j,若d[i][k] + d[k][j] < d[i][j],则更新节点i、j之间的距离。该算法适用于APSP(All Pairs Shortest Paths,多源最短路径),是一种动态规划算法,稠密图效果最佳,边权可正可负。此算法简单有效,由于三重循环结构紧凑,对于稠密图,效率要高于执行|V|次Dijkstra算法,也要高于执行|V|次SPFA算法。
4. Topsis算法 - 基本原理:Topsis算法是一种多准则决策分析方法,通过计算每个方案与理想解和负理想解的相对接近度来进行排序。理想解是各指标的最优值,负理想解是各指标的最差值。相对接近度越大,方案越优。
5. 层次分析法 - 基本原理:层次分析法是一种将复杂问题分解为不同层次,并通过成对比较来确定权重的决策分析方法。它将目标、准则和方案分为不同层次,构建判断矩阵,并通过特征向量法计算权重,进行一致性检验。
6. 分支定界法 - 基本原理:分支定界法是一种搜索问题的解空间的算法,通过分支和定界来剪枝,避免不必要的搜索。它适用于组合优化问题,能够找到全局最优解。
7. 灰色预测 - 基本原理:灰色预测是一种基于灰色系统的预测方法,通过生成灰色模型(如GM(1,1))来预测系统行为。它适用于小样本、贫信息的预测问题。
8. 粒子群算法 - 基本原理:粒子群算法是一种基于群体智能的优化算法,模拟鸟群觅食行为。粒子在搜索空间中飞行,调整自己的位置和速度,向全局最优解靠拢。
9. 模拟退火算法 - 基本原理:模拟退火算法是一种基于物理退火过程的优化算法,通过模拟金属退火过程来寻找全局最优解。它允许一定程度的“爬坡”,以跳出局部最优解。
10. 人口增长模型 - 基本原理:人口增长模型用于描述人口随时间的增长过程,常见的有指数增长模型和逻辑斯蒂增长模型。指数增长模型假设人口增长率恒定,而逻辑斯蒂增长模型考虑了环境承载力的影响。
11. 搜索结果和遗传算法 - 基本原理:遗传算法是一种基于自然选择和遗传机制的优化算法,通过选择、交叉和变异操作来进化种群,寻找最优解。搜索算法则是一类通过搜索解空间来寻找问题解的算法,包括广度优先搜索、深度优先搜索等。
03 部分代码
%BP神经网络的公路运量的预测 P121
%未debug完
clc %清屏
clear all; %清楚内存以加快运算速度
close all; %关闭当前所有figure图像
SamNum=20; %样本的输入数量为20
TestSamNum=20;%测试样本数量为20
ForcastSamNum=2; %预测样本数量为2
HiddenUnitNum=8;%中间层隐节点数量取8
InDim=3;%网络输入维度为三
OutDim=2;%网络输出为维度为2
%原始数据
%人数(万人)
sqrs=[20.55 22.44 25.37 27.13 29.45 30.10 30.96 34.06 36.42 38.09 39.13 39.99 41.43 44.59 47.30 52.89 55.73 56.76 79.17 60.63];
%机动车数(万辆)
sqjdcs=[0.6 0.75 0.85 0.9 1.05 1.35 1.45 1.6 1.7 1.85 2.15 2.2 2.25 2.35 2.5 2.6 2.7 2.85 2.95 3.1];
%公路面积(万平方千米)
sqglmj=[0.09 0.11 0.11 0.14 0.20 0.23 0.23 0.32 0.32 0.34 0.36 0.36 0.38 0.49 0.56 0.59 0.59 0.67 0.69 0.79];
%公路客运量(万人)
glkyl=[5126 6217 7730 9145 10460 11387 12353 15750 18304 19836 21024 19490 20433 22598 25107 33442 36836 40548 42927 43462];
%公路货运量(万吨)
glhyl=[1237 1379 1385 1399 1663 1714 1834 4322 8132 8936 11099 11203 10524 11115 13320 16762 18673 20724 20803 21804];
p=[sqrs;sqjdcs;sqglmj]; %输入数据矩阵
t=[glkyl;glhyl]; %目标数据矩阵
[SamIn,minp,maxp,tn,mint,maxt]=premnmx(p,t); %原始样本对(输入与输出)初始化
rand('state',sum(100*clock)); %依据系统时钟种子产生随机数
NoiseVar=0.01; %噪声强度为0.01(添加噪声的原因是防止网络过度拟合)
Noise=NoiseVar*randn(2,SamNum); %生成噪声
SamOut=tn+Noise; %将噪声加到输出样本上
TestSamIn=SamIn;
TestOut=SamOut;
MaxEpochs=50000;
lr=0.035;
E0=0.65*10^(-3);
W1=0.5*rand(HiddenUnitNum,InDim)-0.1;
B1=0.5*rand(HiddenUnitNum,1)-0.1;
W2=0.5*rand(OutDim,HiddenUnitNum)-0.1;
B2=0.5*rand(OutDim,1)-0.1;
ErrHistory=[];
for i=1:MaxEpochs
HiddenOut=logsig(W1*SamIn+repmat(B1,1,SamNum));
NetWorkOut=W2*HiddenOut+repmat(B2,1,SamNum);
Error=SamOut-NetWorkOut;
SSE=sumsqr(Error)
ErrHistory=[ErrHistory SSE];
if SSE<E0,break,end
Delta2=Error;
Deltal= W2'* Delta2.*HiddenOut.*(1-HiddenOut);
dW2=Delta2*HiddenOut';
dB2=Delta2*ones(SamNum,1);
dW1=Deltal*SamIn';
dB1=Deltal*ones(SamNum,1);
W2=W2+lr*dW2;
B2=B2+lr*dB2;
W1=W1+lr*dW1;
B1=B1+lr*dB1;
end
HiddenOut=logsig(W1*SamIn+repmat(B1,1,TestSamNum));
NetworkOut=W2*HiddenOut+repmat(B2,1,TestSamNum);
a=postmnmx(NetworkOut,mint,maxt);
x=1990:2009;
newk=a(1,:);
newh=a(2,:);
figure;
subplot(2,1,1);plot(x,newk,'r-o',x,glkyl,'b--+');
legend('网络输出客运量','实际客运量');
xlabel('年份');ylabel('客运量/万人');
title('源程序神经网络客运量学习和测试对比图');
title('源程序神经网络货运量学习和测试对比图');
subplot(2,1,2);plot(x,newh,'r-o',x,glhyl,'b--+');
legend('网络输出货运量','实际货运量');
xlabel('年份');ylabel('货运量/万吨');
%利用训练好的网络进行测试
pnew=[73,39 75.55
3.9635 4.097
0.9880 1.0268];
pnewm=tramnmx(pnew,minp,maxp);
HiddenOut=logsig(W1*pnew+repmat(B1,1,ForcastSamNum));
anewn=W2*HiddenOut+repmat(B1,1,ForcastSamNum);
anew=postmnmx(anewn,mint,maxt);
04 代码下载
提供了MATLAB的实现代码,使得用户可以根据自己的需求进行调整和应用。
MATLAB代码下载地址