2021亚太ABCD数学建模

2021亚太杯

2021美赛数学建模
2021小美赛数学建模
B题背景
2017年,美国波多黎各境内有史以来最严重的飓风造成该岛严重破坏,造成2900多人死亡。飓风的风暴潮和波浪作用的综合破坏力对建筑物、房屋和道路造成了广泛的破坏,特别是波多黎各东海岸和东南海岸沿线的建筑物、房屋和道路。风暴以其猛烈的风和暴雨摧毁了波多黎各80%的公用电线杆和所有输电线,造成了损失,并基本上使得岛上所有的340万居民没有电力供应。此外,风暴损坏或摧毁了岛上的大部分移动通信网络。

% 判断数据量是否太少
n = length(x0);  % 计算原始数据的长度
disp(strcat('原始数据的长度为',num2str(n)))    % strcat()是连接字符串的函数,
if n<=3
    disp('亲,数据量太小,我无能为力哦')
    ERROR = 1;
end

% 数据太多时提示可考虑使用其他方法(不报错)
if n>10
    disp('亲,这么多数据量,一定要考虑使用其他的方法哦,例如ARIMA,指数平滑等')
end

% 判断数据是否为列向量,如果输入的是行向量则转置为列向量
if size(x0,1) == 1
    x0 = x0';
end
if size(year,1) == 1
    year = year';
end


%% 对一次累加后的数据进行准指数规律的检验(注意,这个检验有时候即使能通过,也不一定能保证预测结果非常好,例如上面的第三组数据)
if ERROR == 0   % 如果上述错误均没有发生时,才能执行下面的操作步骤
    disp('------------------------------------------------------------')
    disp('准指数规律检验')
    x1 = cumsum(x0);   % 生成1-AGO序列,cumsum是累加函数哦~    注意:1.0e+03 *0.1740的意思是科学计数法,10^3*0.1740 = 174
    rho = x0(2:end) ./ x1(1:end-1) ;   % 计算光滑度rho(k) = x0(k)/x1(k-1)
    
    % 画出光滑度的图形,并画上0.5的直线,表示临界值
    figure(2)
    plot(year(2:end),rho,'o-',[year(2),year(end)],[0.5,0.5],'-'); grid on;
    text(year(end-1)+0.2,0.55,'临界线')   % 在坐标(year(end-1)+0.2,0.55)上添加文本
    set(gca,'xtick',year(2:1:end))  % 设置x轴横坐标的间隔为1
    xlabel('年份');  ylabel('原始数据的光滑度');  % 给坐标轴加上标签
    
    
    disp(strcat('指标1:光滑比小于0.5的数据占比为',num2str(100*sum(rho<0.5)/(n-1)),'%'))
    disp(strcat('指标2:除去前两个时期外,光滑比小于0.5的数据占比为',num2str(100*sum(rho(3:end)<0.5)/(n-3)),'%'))
    disp('参考标准:指标1一般要大于60%, 指标2要大于90%,你认为本例数据可以通过检验吗?')
    
    Judge = input('你认为可以通过准指数规律的检验吗?可以通过请输入1,不能请输入0:');
    if Judge == 0
        disp('亲,灰色预测模型不适合你的数据哦~ 请考虑其他方法吧 例如ARIMA,指数平滑等')
        ERROR = 1;
    end
    disp('------------------------------------------------------------')
end

%% 当数据量大于4时,我们利用试验组来选择使用传统的GM(1,1)模型、新信息GM(1,1)模型还是新陈代谢GM(1,1)模型; 如果数据量等于4,那么我们直接对三种方法求一个平均来进行预测
if ERROR == 0   % 如果上述错误均没有发生时,才能执行下面的操作步骤
    if  n > 4  % 数据量大于4时,将数据分为训练组和试验组(根据原数据量大小n来取,n为5-7个则取最后两年为试验组,n大于7则取最后三年为试验组)
        disp('因为原数据的期数大于4,所以我们可以将数据组分为训练组和试验组')   % 注意,如果试验组的个数只有1个,那么三种模型的结果完全相同,因此至少要取2个试验组
        if n > 7
            test_num = 3;
        else
            test_num = 2;
        end
        train_x0 = x0(1:end-test_num);  % 训练数据
        disp('训练数据是: ')
        disp(mat2str(train_x0'))  % mat2str可以将矩阵或者向量转换为字符串显示, 这里加一撇表示转置,把列向量变成行向量方便观看
        test_x0 =  x0(end-test_num+1:end); % 试验数据
        disp('试验数据是: ')
        disp(mat2str(test_x0'))  % mat2str可以将矩阵或者向量转换为字符串显示
        disp('------------------------------------------------------------')
        
        % 使用三种模型对训练数据进行训练,返回的result就是往后预测test_num期的数据
        disp(' ')
        disp('***下面是传统的GM(1,1)模型预测的详细过程***')
        result1 = gm11(train_x0, test_num); %使用传统的GM(1,1)模型对训练数据,并预测后test_num期的结果
        disp(' ')
        disp('***下面是进行新信息的GM(1,1)模型预测的详细过程***')
        result2 = new_gm11(train_x0, test_num); %使用新信息GM(1,1)模型对训练数据,并预测后test_num期的结果
        disp(' ')
        disp('***下面是进行新陈代谢的GM(1,1)模型预测的详细过程***')
        result3 = metabolism_gm11(train_x0, test_num); %使用新陈代谢GM(1,1)模型对训练数据,并预测后test_num期的结果
        
        % 现在比较三种模型对于试验数据的预测结果
        disp(' ')
        disp('------------------------------------------------------------')
        % 绘制对试验数据进行预测的图形(对于部分数据,可能三条直线预测的结果非常接近)
        test_year = year(end-test_num+1:end);  % 试验组对应的年份
        figure(3)
        plot(test_year,test_x0,'o-',test_year,result1,'*-',test_year,result2,'+-',test_year,result3,'x-'); grid on;
        set(gca,'xtick',year(end-test_num+1): 1 :year(end))  % 设置x轴横坐标的间隔为1
        legend('试验组的真实数据','传统GM(1,1)预测结果','新信息GM(1,1)预测结果','新陈代谢GM(1,1)预测结果')  % 注意:如果lengend挡着了图形中的直线,那么lengend的位置可以自己手动拖动
        xlabel('年份');  ylabel('排污总量');  % 给坐标轴加上标签
        % 计算误差平方和SSE
        SSE1 = sum((test_x0-result1).^2);
        SSE2 = sum((test_x0-result2).^2);
        SSE3 = sum((test_x0-result3).^2);
        disp(strcat('传统GM(1,1)对于试验组预测的误差平方和为',num2str(SSE1)))
        disp(strcat('新信息GM(1,1)对于试验组预测的误差平方和为',num2str(SSE2)))
        disp(strcat('新陈代谢GM(1,1)对于试验组预测的误差平方和为',num2str(SSE3)))
        if SSE1<SSE2
            if SSE1<SSE3
                choose = 1;  % SSE1最小,选择传统GM(1,1)模型
            else
                choose = 3;  % SSE3最小,选择新陈代谢GM(1,1)模型
            end
        elseif SSE2<SSE3
            choose = 2;  % SSE2最小,选择新信息GM(1,1)模型
        else
            choose = 3;  % SSE3最小,选择新陈代谢GM(1,1)模型
        end
        Model = {'传统GM(1,1)模型','新信息GM(1,1)模型','新陈代谢GM(1,1)模型'};
        disp(strcat('因为',Model(choose),'的误差平方和最小,所以我们应该选择其进行预测'))
        disp('------------------------------------------------------------')
        
        %% 选用误差最小的那个模型进行预测
        predict_num = input('请输入你要往后面预测的期数: ');
        % 计算使用传统GM模型的结果,用来得到另外的返回变量:x0_hat, 相对残差relative_residuals和级比偏差eta
        [result, x0_hat, relative_residuals, eta] = gm11(x0, predict_num);  % 先利用gm11函数得到对原数据拟合的详细结果
        
        % % 判断我们选择的是哪个模型,如果是23,则更新刚刚由模型1计算出来的预测结果
        if choose == 2
            result = new_gm11(x0, predict_num);
        end
        if choose == 3
            result = metabolism_gm11(x0, predict_num);
        end
        
        %% 输出使用最佳的模型预测出来的结果
        disp('------------------------------------------------------------')
        disp('对原始数据的拟合结果:')
        for i = 1:n
            disp(strcat(num2str(year(i)), ' : ',num2str(x0_hat(i))))
        end
        disp(strcat('往后预测',num2str(predict_num),'期的得到的结果:'))
        for i = 1:predict_num
            disp(strcat(num2str(year(end)+i), ' : ',num2str(result(i))))
        end
        
        %% 如果只有四期数据,那么我们就没必要选择何种模型进行预测,直接对三种模型预测的结果求一个平均值~
    else
        disp('因为数据只有4期,因此我们直接将三种方法的结果求平均即可~')
        predict_num = input('请输入你要往后面预测的期数: ');
        disp(' ')
        disp('***下面是传统的GM(1,1)模型预测的详细过程***')
        [result1, x0_hat, relative_residuals, eta] = gm11(x0, predict_num);
        disp(' ')
        disp('***下面是进行新信息的GM(1,1)模型预测的详细过程***')
        result2 = new_gm11(x0, predict_num);
        disp(' ')
        disp('***下面是进行新陈代谢的GM(1,1)模型预测的详细过程***')
        result3 = metabolism_gm11(x0, predict_num);
        result = (result1+result2+result3)/3;
        
        disp('对原始数据的拟合结果:')
        for i = 1:n
            disp(strcat(num2str(year(i)), ' : ',num2str(x0_hat(i))))
        end
        disp(strcat('传统GM(1,1)往后预测',num2str(predict_num),'期的得到的结果:'))
        for i = 1:predict_num
            disp(strcat(num2str(year(end)+i), ' : ',num2str(result1(i))))
        end
        disp(strcat('新信息GM(1,1)往后预测',num2str(predict_num),'期的得到的结果:'))
        for i = 1:predict_num
            disp(strcat(num2str(year(end)+i), ' : ',num2str(result2(i))))
        end
        disp(strcat('新陈代谢GM(1,1)往后预测',num2str(predict_num),'期的得到的结果:'))
        for i = 1:predict_num
            disp(strcat(num2str(year(end)+i), ' : ',num2str(result3(i))))
        end
        disp(strcat('三种方法求平均得到的往后预测',num2str(predict_num),'期的得到的结果:'))
        for i = 1:predict_num
            disp(strcat(num2str(year(end)+i), ' : ',num2str(result(i))))
        end
    end
    
    %% 绘制相对残差和级比偏差的图形(注意:因为是对原始数据的拟合效果评估,所以三个模型都是一样的哦~~~)
    figure(4)
    subplot(2,1,1)  % 绘制子图(将图分块)
    plot(year(2:end), relative_residuals,'*-'); grid on;   % 原数据中的各时期和相对残差
    legend('相对残差'); xlabel('年份');
    set(gca,'xtick',year(2:1:end))  % 设置x轴横坐标的间隔为1
    subplot(2,1,2)
    plot(year(2:end), eta,'o-'); grid on;   % 原数据中的各时期和级比偏差
    legend('级比偏差'); xlabel('年份');
    set(gca,'xtick',year(2:1:end))  % 设置x轴横坐标的间隔为1
    disp(' ')
    disp('****下面将输出对原数据拟合的评价结果***')
    
    %% 残差检验
    average_relative_residuals = mean(relative_residuals);  % 计算平均相对残差 mean函数用来均值
    disp(strcat('平均相对残差为',num2str(average_relative_residuals)))
    if average_relative_residuals<0.1
        disp('残差检验的结果表明:该模型对原数据的拟合程度非常不错')
    elseif average_relative_residuals<0.2
        disp('残差检验的结果表明:该模型对原数据的拟合程度达到一般要求')
    else
        disp('残差检验的结果表明:该模型对原数据的拟合程度不太好,建议使用其他模型预测')
    end
    
    %% 级比偏差检验
    average_eta = mean(eta);   % 计算平均级比偏差
    disp(strcat('平均级比偏差为',num2str(average_eta)))
    if average_eta<0.1
        disp('级比偏差检验的结果表明:该模型对原数据的拟合程度非常不错')
    elseif average_eta<0.2
        disp('级比偏差检验的结果表明:该模型对原数据的拟合程度达到一般要求')
    else
        disp('级比偏差检验的结果表明:该模型对原数据的拟合程度不太好,建议使用其他模型预测')
    end
    disp(' ')
    disp('------------------------------------------------------------')
    
    %% 绘制最终的预测效果图
    figure(5)  % 下面绘图中的符号m:洋红色 b:蓝色
    plot(year,x0,'-o',  year,x0_hat,'-*m',  year(end)+1:year(end)+predict_num,result,'-*b' );   grid on;
    hold on;
    plot([year(end),year(end)+1],[x0(end),result(1)],'-*b')
    legend('原始数据','拟合数据','预测数据')  % 注意:如果lengend挡着了图形中的直线,那么lengend的位置可以自己手动拖动
    set(gca,'xtick',[year(1):1:year(end)+predict_num])  % 设置x轴横坐标的间隔为1
    xlabel('年份');  ylabel('排污总量');  % 给坐标轴加上标签
end

以下为闲鱼上的经典骗子
qq1139881689
2021亚太ABCD数学建模_第1张图片
2021亚太ABCD数学建模_第2张图片
2021亚太ABCD数学建模_第3张图片
2021亚太ABCD数学建模_第4张图片

 附件一:


function dy=eq2(t,y)
dy=zeros(2,1);
dy(1)=450*(90*t-y(1))/sqrt((90*t-y(1))^2+(120-y(2))^2);
dy(2)=450*(120-y(2))/sqrt((90*t-y(1))^2+(120-y(2))^2);


 [t,y]=ode45('eq2',[0 2],[0 0]);
Y=0:0.01:2;
plot(1,Y,'-'),hold on
plot(y(:,1),y(:,2),'+')


附件二:

 #include
 #include

main(){
	  FILE* file;
double x[10000],y[10000],a[10000],b[10000],s[10000]; double t=0.001,u;int i=0;
for(x[0]=0,y[0]=0,a[0]=0,b[0]=120;i<10000;i++)

{
s[i]=sqrt((x[i]-a[i])*(x[i]-a[i])+(y[i]-b[i])*(y[i]-b[i]));
x[i+1]=x[i]+450*((a[i]-x[i])/s[i])*t;
y[i+1]=y[i]+450*((b[i]-y[i])/s[i])*t;
a[i+1]=a[i]+135*((b[i]-y[i])/s[i])*t;
b[i+1]=b[i]-135*((a[i]-x[i])/s[i])*t;
if (x[i-1]<a[i-1]&&x[i]>a[i])
  break;
  }
	u=t*i;
printf("%d\n",i);
  printf("导弹的坐标为(%f,%f)\n",x[i],y[i]);
    
printf("%f\n",s[i]);

 printf("%f\n",u);
}
附件三:

#include
#include
#define PI 3.1415926
main()
{
	double x[10000],y[10000],a[10000],b[10000],s[10000],f[10000],t=0.001,k=7*PI/8,u;
	int i=0;
    for(x[0]=0,y[0]=0,a[0]=0,b[0]=120,f[0]=PI/2;i<10000;i++)
	{
    	s[i]=sqrt((x[i]-a[i])*(x[i]-a[i])+(y[i]-b[i])*(y[i]-b[i]));//准确度
        f[i]=atan((b[i]-y[i])/(a[i]-x[i]));
        x[i+1]=x[i]+450*cos(f[i])*t;
        y[i+1]=y[i]+450*sin(f[i])*t;
        a[i+1]=a[i]+135*cos(f[i]+k-PI)*t;
        b[i+1]=b[i]+135*sin(f[i]+k-PI)*t;
        if (x[i-1]<a[i-1]&&x[i]>a[i])
        break;
	}
	u=t*i;
   printf("%d\n",i);
  printf("导弹的坐标为(%f,%f)\n",x[i],y[i]);
    
printf("%f\n",s[i]);

 printf("%f\n",u);

}

你可能感兴趣的:(数学建模,笔记,数学建模)