2022华中杯数学建模思路


B题思路

整个题没有组合投资就比较简单,给的是宏观数据,首先宏观数据都是需要进行预测的,然后选择相关性较高的指标用于预测股票走势,不管是线性回归还是其他算法都可以,数据可以做插值拟合进行补充,以股票时刻为准。插值拟合推荐使用保形样条插值法,在matlab使用filliming函数的pchip参数实现。关于很多人说的指标时间刻度不一样的问题,一种是以股票时刻为准,其他的指标按趋势拆为每5分钟的数据,或者是都按天取平均,不管怎么样,需要统一下时间刻度

K线图怎么画就通过Kplot函数实现,这个肯定论文里需要放一个图的,一般股票的预测都是拿收盘价来预测。

来看看第一问,刚刚说了一般都是拿股票收盘价来预测,那么这里的主要指标,肯定是与收盘价相关性较高的指标,第一问就比较简单,直接通过相关性方法(推荐余弦相似度、方差分析)来做就行,不是主成分哈,那求得是映射基向量,是用来反映数据整体特征的,虽然是主要成分,但是这道题要求是找到与“数字经济”板块有关的重要指标,别用错算法了,后问也提到了成交量,这里在做一个关于成交量的相关性分析,找出相关性较强的指标。

第二问第三问就是分别用主要指标作为输入,成交量和收盘价分别作为输出,带入机器学习算法(推荐神经网络、Xgboost)中训练,最后记得做误差验证。

第四问这里普及下,可以买多也可以买空,买多就是股票涨了,你买入就赚了,买空就是股票降低买入你就赚了,一个是买多一个是买空,别绕进去了,程序中一定要记录好,关于交易多少,这个是需要大家构建一个风控模型的,股票价格就假设收盘价是一笔的价格,后面买入和卖出,都按整数笔交易,虽然题目是有2022年1月4日至2022年1月28 日的数据,你如果参考的话那肯定你的收益很高,要理解题目背景,肯定是你不知道未来的数据,通过预测得到的结果,也就是第三问的结果,然后在这基础上,依次取预测数据片段例如k+1:k+n的n数据分析看是买入还是卖出,买入的话是买多还是买空,同样依次取真实数据片段,如果预期会亏损那么会触发风控机制,会清空股票,当然也可以设定不同阈值,在不同阈值时的清空比例不一样,比如说到风险值0.5了,清空一部分,到风险值0.8了,清空全部,还有就是你把钱花去买了股票了,股票的价值可不是你的现金,卖了后到手里的钱才能用来再次做投资,关于回撤率再说一下,你在1日交易了一笔,在2日交易了一笔,这是分开的,如果1日买的一笔在遇到风险触发风控机制卖出的就算是回撤了,2日买的刚好达到卖出条件卖出了,那么此时的回撤率是50%,如果是触发你的卖出机制,那么就不算回撤,这个要理解。第四问可不是简单的预测买入卖出,肯定需要还原真实股票交易场景,风控、买入、卖出机制都需要构建模型,怎么风控,就取真实片段数据例如k+1:k+n的n数据去进行风险评估,最简单的就是计算方差,怎么买入,预测后面一段时间都是上涨,取预测片段数据如果上升的次数较多,那么可以买入,同样取预测片段数据,如果下降的次数多就卖,这是买多的情况,那么买空也是同样道理,一般股票操作软件中也会设置卖出线,比如说上涨15%自动平仓,下降15%自动平仓。

不建议大家把第四问想的太复杂,可以适当简化,第一个要注意的是风控和卖出是用的真实数据,买入是用的预测数据,第二要注意的是买多和买空要区分好。

【详细思路,C已更新】
C题非常简单,数据不用多说了吧,数据有相应解释,但是要注意题目没有给你们将缺陷的数据是怎样的,需要你们建立模型后通过设置阈值判断,题目也说了五中波形情况

如果不会读取数据就用matlab导入功能 

1)文件格式:

1号电压,2号电压,3号电压,4号电压,5号电压,6号电压,方向, 脉冲,   时间戳

1.61,   1.06,     0.97,    0.95,    0.98,   1.47,     1,     1,     102070423

2)电压值一共有六个,对应了六根钢丝绳的数据。一行数据就是一帧数据。第一列表示第一根绳子的电压值,第二列表示第二根绳子的电压值,…,第六列表示第六根绳子的电压值。

3)方向“0”代表下行,方向“1”表示上行。

4)脉冲:其实就是距离,通过距离传感器得到。从1到n递增,每一帧(一行数据代表一帧数据)对应一个脉冲数字,脉冲数每增加1,代表距离增加了0.4米。

可能有多帧数据对应一个脉冲(表示在0.4米内进行了多次测量)。在绘制波形图时,每一帧所对应的距离等于0.4米除以帧数。

5)时间戳主要用来给文件命名,避免重复。这个数据可以忽略。

6)钢丝绳长为960米,断丝的位置可以用帧表示。

7)每一个文件记录一次运行的监测数据,10个文件记录了10次往返运行的监测数据。注意上行和下行的监测数据不是从同一端记录。

第一问,既然题目说了存在噪音,那就小波降噪就可以了,然后进行异常检验,注意这里的异常检验不是说用个LOF算法将所有异常数据带进去检验,而是取片段根据时间戳依次遍历取片段数据来检验,取的数据长度自定,最简单异常检测可以就按题目说的片段数据中的电压值和平均值之差的绝对值与平均值的百分比,设定阈值识别相应的异常点位,注意一个电压对应的是一条钢丝,脉冲1对应的是0.4米。

小波降噪给个案例程序,自行修改

%%初始化程序
clear,clc
t1=clock;
 %% 载入噪声信号数据,数据为.mat格式,并且和程序放置在同一个文件夹下
load('filename.mat');%matrix
YSJ= filename;
 %% 数据预处理,数据可能是存储在矩阵或者是EXCEL中的二维数据,衔接为一维的,如果数据是一维数据,此步骤也不会影响数据

[c,l]=size(YSJ);
Y=[];
for i=1:c
    Y=[Y,YSJ(i,:)];
end
[c1,l1]=size(Y);
X=[1:l1];
 %% 绘制噪声信号图像
figure(1);
plot(X,Y);
xlabel('横坐标');
ylabel('纵坐标');
title('原始信号');
 %% 硬阈值处理
lev=3;
xd=wden(Y,'heursure','h','one',lev,'db4');%硬阈值去噪处理后的信号序列
figure(2)
plot(X,xd)
xlabel('横坐标');
ylabel('纵坐标');
title('硬阈值去噪处理')
set(gcf,'Color',[1 1 1])
 %% 软阈值处理
lev=3;
xs=wden(Y,'heursure','s','one',lev,'db4');%软阈值去噪处理后的信号序列
figure(3)
plot(X,xs)
xlabel('横坐标');
ylabel('纵坐标');
title('软阈值去噪处理')
set(gcf,'Color',[1 1 1])
%% 固定阈值后的去噪处理
lev=3;
xz=wden(Y,'sqtwolog','s','sln',lev,'db4');%固定阈值去噪处理后的信号序列
figure(4)
plot(X,xz);
xlabel('横坐标');
ylabel('纵坐标');
title('固定阈值后的去噪处理')
set(gcf,'Color',[1 1 1])
%% 计算信噪比SNR
Psig=sum(Y*Y')/l1;
Pnoi1=sum((Y-xd)*(Y-xd)')/l1;
Pnoi2=sum((Y-xs)*(Y-xs)')/l1;
Pnoi3=sum((Y-xz)*(Y-xz)')/l1;
SNR1=10*log10(Psig/Pnoi1);
SNR2=10*log10(Psig/Pnoi2);
SNR3=10*log10(Psig/Pnoi3);
%% 计算均方根误差RMSE
RMSE1=sqrt(Pnoi1);
RMSE2=sqrt(Pnoi2);
RMSE3=sqrt(Pnoi3);
%% 输出结果
disp('-------------三种阈值设定方式的降噪处理结果---------------'); 
disp(['硬阈值去噪处理的SNR=',num2str(SNR1),',RMSE=',num2str(RMSE1)]);
disp(['软阈值去噪处理的SNR=',num2str(SNR2),',RMSE=',num2str(RMSE2)]);
disp(['固定阈值后的去噪处理SNR=',num2str(SNR3),',RMSE=',num2str(RMSE3)]);
t2=clock;
tim=etime(t2,t1);
disp(['------------------运行耗时',num2str(tim),'秒-------------------'])


第二问,需要挖掘出一些指标,然后通过评价算法进行评价,得到的值是相对的,将其作为安全性能的高低,指标可以是信号异常次数、方差等,可以尽可能多挖掘一些指标出来。

【详细思路,A已更新】
一订单包含多种货品,每种商品有不同的数量,题目没说订单的需求时间,那就考虑怎么最短时间内分拣完

题目介绍中我们可以得知,一个货架放一种货品

下面就是我们要解决的问题

其实大家只要先把背景理解了,就特别简单,我们直接来看第一问怎么编程

第一问将当日订单分为多个批次。要求每个批次的订单所含货品种类数均不超过N=200 ,且批次越少越好(相应转运次数也越少,效率越高)。就是说将附件1中的订单进行打包,这里不是聚类哈,别乱搞,反正一个批次就放200多种货品,这里没讲一个货架能放多少数量,那我们也就无所谓了,我们程序怎么编,首先923个订单,是我,我就直接用randperm函数来一个随机序列再说,然后每个通过返回索引,依次遍历用矩阵保存并通过unique函数去重,直到货品种类不超过200为止作为第一个批次,后面类推,当然,肯定是用优化算法解决,这里就是说我们的每个个体都是randperm函数生成的随机序列,然后目标函数则是通过依次打包订单后的批次次数,直接来程序吧

clear
clc
%数据准备
N=200;
[~,~,X]=xlsread('附件1:订单信息.csv');
X=string(X);
X(1,:)=[];
Y=unique(X(:,1));
n=length(Y);
Z=[];
V=[];
for i=1:size(Y)
    z=X(find(X(:,1)==Y(i)),2);
    Z{i,1}=z;%记录每个订单下的货品数
    V(i,1)=sum(double(X(find(X(:,1)==Y(i)),3)));
end
%寻优,我这里只简单个初代个体,后面自己写
num=100;
x=[];
f=[];
for i=1:num
    x(i,:)=randperm(n);
    %计算目标函数
    U=[];
    UU=[];
    u=1;
    for j=1:n
        UU=[UU;Z{x(i,j),1}];
        UU=unique(UU);
        if length(UU)<=N%如果小于200,那么就直接记录
            U{u,1}=UU;
        else%如果大于,那么记录于下一批次
            u=u+1;
            UU=[];
            UU=[UU;Z{x(i,j),1}];
            U{u,1}=UU;
        end
    end
    f(i,1)=u;%记录最大批次,目标函数
end
%记录最优
[bestf,b]=min(f);
bestx=x(b,:);
%计算最优方案下每个批次的货品数和货物数
F=[];%第一列是每个批次货品数,第二列是货物数
UU=[];
u=1;
f1=0;
f2=0;
for j=1:n
    UU=[UU;Z{bestx(j),1}];
    UU=unique(UU);
    if length(UU)<=N%如果小于200,那么就直接记录
        f1=length(UU);
        f2=f2+V(bestx(j),1);
        F(u,:)=[f1,f2];
    else%如果大于,那么记录于下一批次
        u=u+1;
        f1=0;
        f2=0;
        UU=[];
        UU=[UU;Z{bestx(j),1}];
        f1=length(UU);
        f2=f2+V(bestx(j),1);
        F(u,:)=[f1,f2];
    end
end


后面就加迭代就行了,选择最优,如果不会直接蒙特卡洛模拟实验搞定,以上程序直接套模拟退火算法就可以了,有的小伙伴热衷于遗传算法,下面是我之前修改的交叉和变异程序,分享给你们

function x=jiaocha(x,a,k_gen,num_gen)
%交叉率变化
a = a*exp(-k_gen/num_gen);
for i = 1:size(x,1)
    if rand < a
        %选择交叉位点
        b = randi(size(x,2))-1;
        x(i,:)=[x(i,b+1:end),x(i,1:b)];
    end
end
function x=bianyi(x,a,k_gen,num_gen)
%变异率变化
a = a*exp(-k_gen/num_gen);
for i = 1:size(x,1)
    if rand < a
        %选择变异位点
        b1 = randi(size(x,2));
        b2 = randi(size(x,2));
        %产生变异(针对序列问题,产生两个变异点进行两两交换)
        c = x(i,b1);
        x(i,b1)=x(i,b2);
        x(i,b2)=c;
    end
end


 套用其他优化算法都可以,稍后会发布完整程序出来

第二问,在第一问基础上,考虑货架编号,在打包完一批次订单后再来寻优摆放位置,要知道一个订单有多种货品,一个货品可能会包含于多个订单,就是看一批次的货品摆放是否就当前的订单集中一点,拣选距离题目已经给出

 第二问就增加一个目标函数,然后进行多目标寻优,非支配排序算法程序分享给你们

function [TT,chrom]=ns2(NN,F1,F2)
% 快速非支配排序
a = 0;
T1 = [];
T2 = [];
chrom=NN;
chrom1 = [];
chrom2 = [];
while a == 0 %根据被支配数进行分级和排序
    M = [];
    for i = 1:length(F1)
        M(i,1) = length(find(F1>F1(i,1)))+length(find(F2
    end
    b1 = [];
    b2 = [];
    [b1,b2] = sort(M); %b1返回从小到大排序,b2返回原始序号
    if  length(chrom)>0 && b1(1) == 0   %无被支配数进入一级用T1矩阵保存
        T1 = [T1;F1(b2(1)),F2(b2(1))];
        chrom1 = [chrom1;chrom(b2(1),:)];
        F1(b2(1)) = [];
        F2(b2(1)) = [];
        chrom(b2(1),:) = [];
    else  %有被支配数进入二级用T2矩阵保存
        a = 1;
        T2 = [F1,F2];
        chrom2 = chrom;
    end
end
T2 = T2(b2,:);
chrom2 = chrom2(b2,:);
if size(T1,1) > 2  %T1矩阵不用进行拥挤度调整排序,直接对T2进行排序调整即可
    y = yongji(T1);%拥挤度
    for i = 2:size(T1,1)
        if y(i-1) > y(i)
            T1(i-1:1:i,:) = T1(i:-1:i-1,:); %根据拥挤度调整排序,如果后者优于前者则反转顺序
            chrom1(i-1:1:i,:) = chrom1(i:-1:i-1,:);
        end
    end
end
if length(T2) > 0  %T1矩阵不用进行拥挤度调整排序,直接对T2进行排序调整即可
    y = yongji(T2);%拥挤度
    for i = 2:size(T2,1)
        if b1(i) == b1(i-1)
            if y(i-1) > y(i)
                T2(i-1:1:i,:) = T2(i:-1:i-1,:); %根据拥挤度调整排序,如果后者优于前者则反转顺序
                chrom2(i-1:1:i,:) = chrom2(i:-1:i-1,:);
            end
        end
    end
end
%排序重组
TT = [T1;T2];
chrom = [chrom1;chrom2];
function y=yongji(H)
%计算拥挤度
y1=H(:,1);
y2=H(:,2);
[yy1,a1]=sort(y1);
[yy2,a2]=sort(y2);
L=[];
L=[1 1];
for i=2:length(yy1)-1
    L=[L;(yy1(i+1,1)-yy1(i-1,1))/(max(yy1)-min(yy1)),(yy2(i+1,1)-yy2(i-1,1))/(max(yy2)-min(yy2))];
end
L=[L;1 1];
L=[L(a1,1),L(a2,2)];
y=sum(L,2);
end


 第三问,在第二问基础上,又考虑多个技术工,第三问编程稍微复杂些,入手的话一个一个规则写进去,注意别弄错了,这个问只选其中一个批次的来研究即可,也可以分别做几个批次,对模型的稳定性进行说明。
————————————————
 

你可能感兴趣的:(算法,big,data,人工智能)