最近跟着清风老师学习数学建模有关插值算法,记录学习笔记。
目录
一、数学建模中的应用
二、一维插值问题
三、插值法定义
1、插值函数
2、插值节点
3、插值区间
4、插值法的定义
四、常用插值法
1、拉格朗日插值法
2、牛顿插值法
3、龙格现象
4、分段插值
5、埃尔米特插值法
6、三次样条插值法
五、例题与应用
1、MathorCup第六届A题 淡水养殖池塘水华发生及池水净化处理
2、利用插值算法还可以对问题进行短期预测
数学建模比赛中,常常需要根据已知的函数点进行数据、模型的处理和分析,而有时候现有的数据是极少的,不足以支撑分析的进行,这时就需要使用一些数学的方法,“模拟产生”一些新的但又比较靠谱的值来满足需求。
个人常见情况是在数据处理过程中。比赛时会出现已给数据缺失或不够的情况,或者数据不满足模型等情况,此时就需要利用插值算法,构造合理数据继续问题求解。
通过学习一维插值思路可以类似推广到高维的插值问题。
问题:已经有个节点,其中互不相同不妨假设
在一维插值问题中主要思路:构造函数,使得过所有节点,求即可得到。
已知函数在区间上有定义,已知节点在区间内,若存在一个简单函数经过每一个区间内的节点,则此函数为插值函数。
区间内的若干已知点。
区间为插值区间
求插值函数的方法成为插值法
学习中介绍了常用和所需的插值法分为:分段插值、多项式插值、埃尔米特插值、三次样条插值。
其中分段插值分为:分段线性插值和分段二次插值,分段插值主要是为了解决在多项式插值中存在的龙格现象。
多项式插值分为:拉格朗日插值法和牛顿插值法。其中牛顿插值法的计算过程具有继承性,但两者都存在龙格现象。
埃尔米特插值和三次样条插值:两种方法是我们建模中比较常用的插值方法。与拉格朗日插值法和牛顿插值法不同在于,他们所找到的插值函数不仅满足经过已知节点,而且在一个或全部节点上插值多项式与被插函数具有相同的低阶甚至高阶的导数值。所以所求的插值函数会更加准确。
插值多项式的次数并不是越高越好
可以看到高次的插值会产生龙格现象,即在两端处波动极大,产生明显的震荡。这种现象被称为龙格现象。
由于龙格现象的存在,我们可以采用分段插值来消除误差。
分段线性插值:通过两两节点间线段上插入。
分段二次插值:取三个节点为一段,构造分段抛物线来代替原来复杂函数。
埃尔米特插值法的Matlab语句:p=pchip(x,y,new_x)
三次样条插值法的Matlab语句:p=spline(x,y,new_x)
本题在数据与处理中可以使用插值算法
如图可见,附件一给的是每周的数据,而附件二只有奇数周的数据,可以利用插值算法补充附件二数据进而处理问题。
将附件二数据提取到下面excel表中,命名并应用于matlab中,用插值算法对数据经行预处理,补足双周数据。
matlab代码如下
%插值预测中间周的水体评价指标
load Z.mat
x=Z(1,:); %Z的第一行是星期Z: 1 3 5 7 9 11 13 15
[n,m]=size(Z);%n为Z的行数,m为Z的列数
% 注意Matlab的数组中不能保存字符串,如果要生成字符串数组,就需要使用元胞数组,其用大括号{}定义和引用
ylab={'周数','轮虫','溶氧','COD','水温','PH值','盐度','透明度','总碱度','氯离子','透明度','生物量'}; % 等会要画的图形的标签
disp(['共有' num2str(n-1) '个指标要进行插值。'])
disp('正在对一号池三次埃尔米特插值,请等待')%一号池共有十一组要插值的数据,算上星期所在的第一行,共十二行
P=zeros(11,15);%对要储存数据的矩阵P赋予初值
for i=2:n%从第二行开始都是要进行插值的指标
y=Z(i,:);%将每一行依次赋值给y
new_x=1:15;%要进行插值的x
p1=pchip(x,y,new_x);%调用三次埃尔米特插值函数
subplot(4,3,i-1);%将所有图依次变现在4*3的一幅大图上
plot(x,y,'ro',new_x,p1,'-');%画出每次循环处理后的图像
axis([0 15,-inf,inf]) %设置坐标轴的范围,这里设置横坐标轴0-15,纵坐标不变化
% xlabel('星期')%x轴标题
ylabel(ylab{i})%y轴标题 这里是直接引用元胞数组中的字符串哦
P(i-1,:)=p1;%将每次插值之后的结果保存在P矩阵中
end
legend('原始数据','三次埃尔米特插值数据','Location','SouthEast')%加上标注,注意要手动在图中拖动标注到图片右下角哦
P = [1:15; P] %把P的第一行加上周数
end
legend('原始数据','三次埃尔米特插值数据','Location','SouthEast')%加上标注,注意要手动在图中拖动标注到图片右下角哦
P = [1:15; P] %把P的第一行加上周数
最终数据预处理结果与图像
根据过去人口数量,预测未来三年的人口数量。
人口数据如下:
举例代码如下:
population=[133126,133770,134413,135069,135738,136427,137122,137866,138639, 139538];
year = 2009:2018;
p1 = pchip(year, population, 2019:2021) %分段三次埃尔米特插值预测
p2 = spline(year, population, 2019:2021) %三次样条插值预测
figure(4);
plot(year, population,'o',2019:2021,p1,'r*-',2019:2021,p2,'bx-')
legend('样本点','三次埃尔米特插值预测','三次样条插值预测','Location','SouthEast')
结果如下:
注:一般我们很少使用插值算法来预测数据,随着继续的学习,后面清风老师会有更适合预测的算法供选择,例如灰色预测、拟合预测等。