数学建模-插值算法(Matlab)

注意:代码文件仅供参考,一定不要直接用于自己的数模论文中
国赛对于论文的查重要求非常严格,代码雷同也算作抄袭
如何修改代码避免查重的方法:https://www.bilibili.com/video/av59423231   //清风数学建模

一、基础知识

简单来说是根据已知点进行线性数据预测,但数据太少需要通过数学方法生成一些数据,如根据十年人口数据预测未来五年人口增减情况。

1.两个常用的插值法

一般多用分段三次埃尔米特插值三次样条插值

其内置函数分别为

p=pchip(x,y,new_x)

x,y为已知样本点横纵坐标,new_x为要插入对应点的横坐标(纵坐标会计算生成,即为p)

三次样条插值函数参数也同理:

 p=spline(x,y,new_x)

2.生成和打印图片

脚本文件中生成图片(在同一个脚本文件里面,要想画多个图,需要给每个图编号,否则只会显示最后一个图)

figure(1) 

plot函数,显示图像,至少要两种点的横纵坐标,多种会生成更多线

线方式:-实线   :点线    -.虚点线   --波折线

点方式: .圆点   +加号   *型号   o小圆

颜色: y黄  r红  g绿  b蓝  k黑

标注使用legend函数,跟在figure、plot之后,一组x,y(即一种点)对应一个名称,最后选择注释所在图中的位置(如东南是右下角)

x = -pi:pi; y = sin(x); 
new_x = -pi:0.1:pi;
p = pchip(x,y,new_x);
figure(1); % 在同一个脚本文件里面,要想画多个图,需要给每个图编号,否则只会显示最后一个图哦~
plot(x, y, 'o', new_x, p, 'r-')
legend('样本点','三次埃尔米特插值','Location','SouthEast') 

 3.n维数据的插值

p=interpn(x1,x2,...,xn,y,new_x1,new_x2,...,new_xn,method)

 参数还是已知样本点的横纵坐标,new_x为要插入点的横坐标。最后method是调用方法,如下

'linear':线性插值(默认) 'cubic':三次插值

'spline':三次样条插值(多用) 'nearest':最邻近插值

 例:人口预测,给09-18年的人口,预测19-21年的

population=[133126,133770,134413,135069,135738,136427,137122,137866,138639, 139538];
year = 2009:2018;  %类似于等差数列,是09-18每个数值取整组成的矩阵
%可以加上 p1 = pchip(year, population, 2019:2021) 这样最后就是两条线了 
p2 = interpn(year, population, 2019:2021,'spline') %等价于p2 = spline(year, population, 2019:2021)
figure(4);
plot(year, population,'o',2019:2021,p2,'bx-')
legend('样本点','interpn三次样条插值预测','Location','SouthEast')

 二、实战演练

例题来源:第六届MathorCup大学生数学建模挑战A题 淡水养殖池塘水华发生及池水净化处理

 上图是附件二每个池子一些物质含量的变化,可以主要上沿,每个池子只有奇数周的数据,本演练是把1号池子的每周数据补充完整(即补上偶数周)

根据一号池的数据,把数据保存为Z(忽略叶绿体和汉字),如下图(可以另存为本地)

 多组数据图片的演示,可以for循环处理,同时要用到subplot(m,n,p)

m表示是图排成m行,n表示图排成n列.p表示图所在的位置,如p=1表示从左到右从上到下的第一个位置。

ylabel(ylab{i}) %给y轴标题,这里是直接引用元胞数组(先定义好的)中的字符串哦。

参考优秀代码(Mr.sandman同学提供):

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的第一行加上周数

 矩阵P的数值即为要求的,可以粘贴回excel

  • 3
    点赞
  • 53
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 6
    评论
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

牛大了202X

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值