✅作者简介:热爱科研的Matlab仿真开发者,擅长
毕业设计辅导、数学建模、数据处理、建模仿真、程序设计、完整代码获取、论文复现及科研仿真。
🍎 往期回顾关注个人主页:Matlab科研工作室
👇 关注我领取海量matlab电子书和数学建模资料
🍊个人信条:格物致知,完整Matlab代码获取及仿真咨询内容私信。
🔥 内容介绍
在全球积极推进可持续能源发展的浪潮中,光伏能源凭借其清洁、可再生的特性,成为了能源领域的一颗璀璨明星。尤其在北半球,广阔的地域和多样的气候条件为光伏能源的大规模应用提供了丰富的资源。然而,光伏系统的输出功率并非恒定不变,它受到诸如日照强度、温度、云层覆盖等多种因素的综合影响,呈现出显著的不确定性。这种不确定性给电网的稳定运行带来了挑战,也对光伏能源的高效管理和光伏系统的优化设计提出了更高的要求。因此,准确的光伏数据预测成为了关键。本文旨在探索一种创新的方法,即基于凌日优化算法(TSOA)优化极限学习机(ELM),构建 TSOA - ELM 模型,以期实现高精度的北半球光伏数据预测,为光伏能源的稳定发展和有效利用提供有力支持。
理论基石:算法与数据洞察
- 凌日优化算法:源于天文的灵感
凌日优化算法(TSOA)独辟蹊径,从天文现象中的行星凌日获取灵感,并将其转化为一种强大的优化工具。想象一下,行星在围绕恒星运行过程中,偶尔会出现凌日现象,行星在恒星前方经过,这一过程涉及到行星的位置、轨道等多种要素的变化。在 TSOA 中,我们类比这一现象,将优化问题的解空间看作是一个宇宙,每个可能的解(即一组参数)就如同行星在宇宙中的位置。算法通过精心设计的机制,模拟凌日过程中行星位置的变化规律,实现对最优解的搜索。首先,定义一个包含所有可能解的搜索空间,如同确定了宇宙的边界。然后,初始化一组个体(类似于行星的初始位置),这些个体代表了不同的参数组合。在迭代过程中,通过模拟凌日过程中的关键要素,如行星的运动轨迹、与恒星的相对位置变化等,对个体的位置进行更新。这种独特的搜索机制赋予了 TSOA 强大的全局搜索能力,使其能够在复杂的解空间中不断探索,不易陷入局部最优,从而有更大的机会找到真正的最优解。
- 极限学习机:快速学习的神经网络
极限学习机(ELM)作为一种单隐层前馈神经网络,以其独特的学习方式在机器学习领域崭露头角。与传统的神经网络不同,ELM 在训练过程中展现出极高的效率。它摒弃了繁琐的反向传播算法,而是随机生成输入层与隐层之间的连接权值和隐层神经元的阈值。这就好比在构建神经网络时,随机地搭建了输入层到隐层的桥梁以及确定了隐层神经元的初始状态。然后,通过简单而直接的计算,得出输出层权值。具体来说,输入数据经过输入层传递到隐层,隐层神经元根据激活函数对输入进行非线性变换,再将变换后的结果传递到输出层,通过线性组合得到最终的输出。激活函数的选择如同为隐层神经元赋予了不同的 “个性”,对模型的性能有着重要影响。尽管 ELM 学习速度快,能够在短时间内处理大量数据,但由于其参数的随机性,在面对复杂的光伏数据时,可能无法准确捕捉数据中的复杂特征和规律,导致预测精度受到一定限制。
- 北半球光伏数据:复杂多变的能源信号
北半球地域广袤,不同地区的光伏数据呈现出丰富多样的特点。从季节变化来看,夏季时,北半球大部分地区日照时间延长,太阳辐射强度增强,光伏系统能够捕获更多的太阳能,输出功率相对较高。而到了冬季,日照时间缩短,太阳辐射减弱,光伏输出功率明显降低。此外,天气条件对光伏数据的影响也极为显著。晴天时,阳光直射,光伏电池能够高效工作,功率输出稳定且较高;阴天或多云天气下,云层遮挡阳光,光伏系统的输出功率会大幅下降,且波动较大。这种强烈的非线性和波动性使得光伏数据的准确预测成为一项具有挑战性的任务。同时,不同地区的地理环境、气候类型差异也导致光伏数据各具特色,进一步增加了预测的难度。
模型构建:融合创新实现精准预测
- 创新融合:优势互补的策略
将 TSOA 与 ELM 相结合,是基于两者优势互补的考量。ELM 的快速学习能力为模型的训练提供了高效的基础,但参数的随机性限制了其预测精度。而 TSOA 强大的全局搜索能力恰好能够弥补这一不足。我们的思路是利用 TSOA 在广阔的参数空间中搜索最优解,为 ELM 找到一组最适合光伏数据的参数,包括输入层与隐层之间的连接权值、隐层神经元的阈值以及输出层权值等。通过这种方式,克服 ELM 参数选择的盲目性,充分发挥其潜力,提升模型对光伏数据的预测性能,实现高精度的预测目标。
- 优化之旅:TSOA 的精细操作
TSOA 对 ELM 参数的优化过程犹如一场精密的科学实验。首先,将 ELM 的参数进行编码,使其成为 TSOA 种群中的个体。每个个体就像是一个装满参数的 “宝箱”,代表着一组可能的 ELM 参数组合。接下来,构建适应度函数,这个函数就如同一个精准的 “裁判”,以光伏数据预测的误差为依据,评估每个个体的优劣。误差越小,个体的适应度越高,也就意味着这组参数越有可能使 ELM 模型准确地预测光伏数据。然后,按照 TSOA 的独特原理,模拟凌日过程中的各种操作。在这个过程中,个体(即参数组合)会像行星在凌日过程中改变位置一样,不断调整自己的值。例如,通过特定的规则更新个体的位置,模拟行星的运动轨迹;根据个体与当前最优解的相对关系,进行类似行星状态转换的操作,促使个体向更优的方向发展。在每次迭代中,计算每个个体的适应度值,并记录下当前的最优个体。随着迭代的进行,个体不断进化,适应度函数值逐渐减小,趋近于最优解。当达到预设的终止条件(如最大迭代次数或适应度值收敛)时,我们就得到了一组最优的 ELM 参数。
- 预测实现:ELM 的精准输出
在 TSOA 成功找到最优参数后,这些参数就如同为 ELM 注入了强大的 “能量”。根据北半球光伏数据的特点,我们精心选择合适的输入特征。日照时间是影响光伏输出功率的直接因素,太阳辐射强度决定了光伏电池能够捕获的能量多少,温度对光伏电池的效率也有重要影响,这些都成为了模型的重要输入。为了使模型更好地处理数据,我们对数据进行预处理。去除数据中的异常值,就像清理道路上的障碍物,确保数据的准确性;填补缺失值,让数据更加完整;通过归一化操作,将不同范围的数据统一到一个标准尺度,便于模型进行学习。经过预处理的数据输入到优化后的 ELM 模型中,ELM 按照其独特的计算过程,从输入层开始,经过隐层的非线性变换,再到输出层的线性组合,最终得出光伏数据的预测值。
实验验证:数据见证模型实力
- 数据准备:打造坚实基础
为了全面、准确地验证 TSOA - ELM 模型的性能,我们广泛收集了北半球不同地区的实际光伏数据。这些数据涵盖了多个年份和不同季节,如同一个丰富的数据库,充分反映了光伏数据在时间和空间上的变化特性。在数据预处理阶段,我们采取了一系列严谨的措施。对于异常值,通过统计分析和领域知识进行识别和剔除,避免其对模型训练产生干扰。缺失值则采用合适的插值方法进行填补,保证数据的完整性。数据归一化是关键的一步,它将不同特征的数据统一到 [0, 1] 或 [-1, 1] 的区间内,使模型能够更好地学习数据中的特征和规律。最后,按照一定比例将数据划分为训练集、验证集和测试集。训练集用于模型的学习,验证集用于调整模型的参数,测试集则用于最终评估模型的性能,为实验的顺利进行奠定了坚实的基础。
- 实验设计:多模型的同台竞技
为了客观地评估 TSOA - ELM 模型的优势,我们设计了一场多模型的 “较量”。将 TSOA - ELM 模型与其他常见的光伏数据预测模型放在相同的 “舞台” 上进行对比。这些对手包括传统的人工神经网络(ANN),它以其强大的非线性拟合能力而闻名;支持向量机(SVM),在小样本数据处理方面表现出色;以及未经过 TSOA 优化的 ELM 模型,作为对比基准,突出 TSOA 优化的效果。在实验设置上,我们确保所有模型处于相同的条件下,设定相同的训练次数、学习率等参数,就像为所有选手制定了相同的比赛规则,保证实验的公平性。
- 评价指标:全面衡量模型表现
为了全面、细致地衡量模型的预测性能,我们选取了均方根误差(RMSE)、平均绝对误差(MAE)和平均绝对百分比误差(MAPE)作为评价指标。RMSE 就像一个严格的 “放大镜”,对预测值与真实值之间误差的平方进行平均后再开方,特别关注较大误差的影响,能够反映模型预测值的波动程度。MAE 则以一种简单直接的方式,计算预测值与真实值之间绝对误差的平均值,直观地展示了模型预测的平均误差大小。MAPE 以百分比的形式呈现预测误差,便于在不同数据规模和模型之间进行比较,能清晰地反映预测值与真实值的偏离程度。这三个指标从不同角度全面地刻画了模型的预测精度,为我们准确评估模型性能提供了有力的工具。
⛳️ 运行结果![]()
![]()
![]()
📣 部分代码
function [Best_Planet , best,Bestss] = TransitSearch (ns,maxcycle,Vmin,Vmax,nvar,CostFunction)
SN=10;
%% Initialization
Empty.Location = [];
Empty.Cost = inf;
Galaxy_Center = repmat (Empty, 1, 1);
region = repmat (Empty, ns*SN, 1);
selested_regions = repmat (Empty, ns, 1);
Stars = repmat (Empty, ns, 1);
Stars_sorted = zeros(ns,1);
Ranks = 1:1:ns;
Stars_Ranks = zeros(ns,1);
Luminosity = zeros(ns,1);
Star_RanksNormal = zeros(ns,1);
Distance = zeros(ns,1);
Transit0 = zeros(ns,1);
SN_P = repmat (Empty, SN, 1);
Bests=region;
if length(Vmin) >1
Vmin=Vmin;
Vmax=Vmax;
else
Vmin=Vmin*ones(1,nvar);
Vmax=Vmax*ones(1,nvar);
end
%% Galaxy Phase
% Initial Location of The Center of the Galaxy
Galaxy_Center.Location = unifrnd(Vmin,Vmax,1,nvar);
% Galaxy_Center.Location=initialization(ns,nvar,Vmax,Vmin);
Galaxy_Center.Cost = CostFunction(Galaxy_Center.Location);
% Galactic Habitate Zone of the Galaxy
for l = 1:ns*SN
zone = randi(2);
if zone ==1
difference = rand().*(Galaxy_Center.Location)-(unifrnd(Vmin,Vmax,1,nvar));
else
difference = rand().*(Galaxy_Center.Location)+(unifrnd(Vmin,Vmax,1,nvar));
end
Noise = ((rand(1,nvar)).^3).*(unifrnd(Vmin,Vmax,1,nvar));
region(l).Location = Galaxy_Center.Location + difference - Noise;
region(l).Location = max(region(l).Location, Vmin);
region(l).Location = min(region(l).Location, Vmax);
region(l).Cost = CostFunction(region(l).Location);
end
% Selection of Stars from the Galactic Habitate Zone of the Galaxy
[Sort,index]=sort([region.Cost]);
for i = 1:ns
selested_regions(i) = region(i);
for k = 1:SN
zone = randi(2);
if zone ==1
difference = rand().*(selested_regions(i).Location)-rand().*(unifrnd(Vmin,Vmax,1,nvar));
else
difference = rand().*(selested_regions(i).Location)+rand().*(unifrnd(Vmin,Vmax,1,nvar));
end
Noise = ((rand(1,nvar)).^3).*(unifrnd(Vmin,Vmax,1,nvar));
new.Location = selested_regions(i).Location + difference - Noise;
new.Location = max(new.Location, Vmin);
new.Location = min(new.Location, Vmax);
new.Cost = CostFunction(new.Location);
if new.Cost < Stars(i).Cost
Stars(i) = new;
end
end
end
% Initial Location of the Best Planets (Start Point: Its Star)
Best_Planets = Stars;
% Specification of the Best Planet
[Sort,index]=sort([Best_Planets(1).Cost]);
Best_Planet = Best_Planets(index(1,1));
% Telescope Location
Telescope.Location = unifrnd(Vmin,Vmax,1,nvar);
% Determination of the Luminosity of the Stars
for i = 1:ns
Stars_sorted(i,1) = Stars(i).Cost;
end
Stars_sorted = sort (Stars_sorted);
for i = 1:ns
for ii = 1:ns
if Stars(i).Cost == Stars_sorted(ii,1)
Stars_Ranks(i,1) = Ranks(1,ii);
Star_RanksNormal(i,1) = (Stars_Ranks(i,1))./ns;
end
end
Distance(i,1) = sum((Stars(i).Location-Telescope.Location).^2).^0.5;
Luminosity(i,1) = Star_RanksNormal(i,1)/((Distance(i,1))^2);
end
Luminosity_new = Luminosity;
Stars2 = Stars;
%% Loops of the TS Algorithm
for it = 1:maxcycle
%% Transit Phase
Transit = Transit0;
Luminosity = Luminosity_new;
for i = 1:ns
difference = (2*rand()-1).*(Stars(i).Location);
Noise = ((rand(1,nvar)).^3).*(unifrnd(Vmin,Vmax,1,nvar));
Stars2(i).Location = Stars(i).Location + difference - Noise;
Stars2(i).Location = max(Stars2(i).Location, Vmin);
Stars2(i).Location = min(Stars2(i).Location, Vmax);
Stars2(i).Cost = CostFunction(Stars2(i).Location);
end
for i = 1:ns
Stars_sorted(i,1) = Stars2(i).Cost;
end
Stars_sorted = sort (Stars_sorted);
for i = 1:ns
for ii = 1:ns
if Stars2(i).Cost == Stars_sorted(ii,1)
Stars_Ranks(i,1) = Ranks(1,ii);
Star_RanksNormal(i,1) = (Stars_Ranks(i,1))./ns;
end
end
Distance(i,1) = sum((Stars2(i).Location-Telescope.Location).^2).^0.5;
Luminosity_new(i,1) = Star_RanksNormal(i,1)/((Distance(i,1))^2);
if Luminosity_new(i,1) < Luminosity(i,1)
Transit (i,1) = 1; % Has transit been observed? 0 = No; 1 = Yes
end
end
Stars = Stars2;
%% Location Phase (Exploration)
for i = 1:ns
if Transit (i,1) == 1
% Determination of the Location of the Planet
Luminosity_Ratio = Luminosity_new(i,1)/Luminosity(i,1);
Planet.Location = (rand().*Telescope.Location + Luminosity_Ratio.*Stars(i).Location)./2;
for k = 1:SN
zone = randi(3);
if zone ==1
new.Location = Planet.Location - (2*rand()-1).*(unifrnd(Vmin,Vmax,1,nvar));
elseif zone ==2
new.Location = Planet.Location + (2*rand()-1).*(unifrnd(Vmin,Vmax,1,nvar));
else
new.Location = Planet.Location + (2.*rand(1,nvar)-1).*(unifrnd(Vmin,Vmax,1,nvar));
end
new.Location = max(new.Location, Vmin);
new.Location = min(new.Location, Vmax);
% new.Cost = CostFunction(new.Location);
SN_P(k) = new;
end
SUM = 0;
for k = 1:SN
SUM = SUM+SN_P(k).Location;
end
new.Location = SUM./SN;
new.Cost = CostFunction(new.Location);
if new.Cost < Best_Planets(i).Cost
Best_Planets(i) = new;
end
else % No Transit observed: Neighbouring planets
Neighbor.Location = (rand().*Stars(i).Location + rand().*(unifrnd(Vmin,Vmax,1,nvar)))./2;
for k = 1:SN
zone = randi(3);
if zone ==1
Neighbor.Location = Neighbor.Location - (2*rand()-1).*(unifrnd(Vmin,Vmax,1,nvar));
elseif zone ==2
Neighbor.Location = Neighbor.Location + (2*rand()-1).*(unifrnd(Vmin,Vmax,1,nvar));
else
Neighbor.Location = Neighbor.Location + (2.*rand(1,nvar)-1).*(unifrnd(Vmin,Vmax,1,nvar));
end
Neighbor.Location = max(Neighbor.Location, Vmin);
Neighbor.Location = min(Neighbor.Location, Vmax);
Neighbor.Cost = CostFunction (Neighbor.Location);
SN_P(k) = Neighbor;
end
SUM = 0;
for k = 1:SN
SUM = SUM+SN_P(k).Location;
end
Neighbor.Location = SUM./SN;
Neighbor.Cost = CostFunction (Neighbor.Location);
if Neighbor.Cost < Best_Planets(i).Cost
Best_Planets(i) = Neighbor;
end
end
end
%% Signal Amplification of the Best Planets (Exploitation)
for i = 1:ns
for k = 1:SN
RAND = randi(2 );
if RAND ==1
Power = randi(SN*ns);
Coefficient = 2*rand();
Noise = ((rand(1,nvar)).^Power).*(unifrnd(Vmin,Vmax,1,nvar));
else
Power = randi(SN*ns);
Coefficient = 2*rand();
Noise = -((rand(1,nvar)).^Power).*(unifrnd(Vmin,Vmax,1,nvar));
end
% new.Location = (rand().*Best_Planets(i).Location) - Coefficient.*Noise;
chance = randi(2);
if chance ==1
new.Location = Best_Planets(i).Location - Coefficient.*Noise;
else
new.Location = (rand().*Best_Planets(i).Location) - Coefficient.*Noise;
end
new.Location = max(new.Location, Vmin);
new.Location = min(new.Location, Vmax);
new.Cost = CostFunction(new.Location);
% new.Cost = Penalty(new,ConstraintFunction,CostFunction);
if new.Cost < Best_Planets(i).Cost
Best_Planets(i) = new;
best=Best_Planets(i).Location;
end
end
if Best_Planets(i).Cost < Best_Planet.Cost
Best_Planet = Best_Planets(i);
end
end
% Results
Bestss(it)=Best_Planet.Cost;
end
end