非遗传案例的Matlab遗传算法

Matlab Genetic Algorithm for a non-genetic case

我从来没有使用过优化工具,但我想我现在必须使用,所以我有点迷茫。使用@A给出的答案后。 Donda,我注意到这可能不是最好的解决方案,因为每次我 运行 函数都会给出不同的矩阵 'pares' 并且在大多数情况下它说我需要更多评估。所以我在想,也许我的问题的答案是遗传算法优化,但我又一次不知道如何使用它们。

下面描述了我的第一个问题,@A 给出了答案。 Donda 是唯一的 post 个答案。我确实需要完成此优化,但我不知道如何使用 GA 工具处理这种情况。

再次非常感谢你,谢谢@A。 Donda 为您解答。

按照要求,我试着把我试图解释的代码放在这里,我希望它会结果:

    function opt_pares
clear all; clc; close all;

h = randi(24,8760,1);
nd = randi(365,8760,1);
veic = randi(333,8760,1);
max_veic = max(veic);
veicN = veic./max_veic;
Gh = randi(500,8760,1);
Dh = randi(500,8760,1);
Ih = Gh-Dh;
A = randi([300 800], 27,1);
max_Gh = max(Gh);
max_Dh = max(Dh);
max_Ih = max(Ih);

lat = 70;
HRA =15.*(h-12);
decl = 23.27*sind(360*(284+nd)/365);

Ii = zeros(8760,27);
Di = zeros(8760,27);
Gi = zeros(8760,27);

pares = randi([0,90],27,2);
inclin = pares(:,1);
azim = pares(:,2);
% for MATRIZC
    for n=1:27
    Ii(:,n) = Ih.*(sind(decl).*sind(lat).*cosd(inclin(n))-sind(decl).*cosd(lat).*sind(inclin(n)).*cosd(azim(n))+cosd(decl).*cosd(lat).*cosd(inclin(n)).*cosd(HRA)+cosd(decl).*sind(lat).*sind(inclin(n)).*cosd(azim(n)).*cosd(HRA)+cosd(decl).*sind(inclin(n)).*sind(azim(n)).*sind(HRA));
    Di(:,n) = 0.5*Dh.*(1+cosd(inclin(n)));
    Gi(:,n) = (Ii(:,n)+Di(:,n))*A(n,1);
    end
Gparque = sum(Gi,2);
max_Gparque = max(Gparque);
GparqueN = Gparque./max_Gparque;
RMSE = sqrt(mean((GparqueN-veicN).^2));
% end

end

不知道可不可以,也许这次我可以更自信一些。

我的主要目标是尽可能做到最好 'RMSE',为此我必须创建一个矩阵 ('pares'),其中每一行包含一对值(每列中的一个值).

这些值必须在一定范围内 (0-90)。对于这 27 对中的每一对,我必须计算 'Ii'/'Gi'/'Di',给我一个大小类似于 8760*27 的矩阵。

然后我对 'Gi' 求和得到 'Gparque'(向量 8760*1),最后我计算 'RMSE'。当我计算 RMSE 时,我必须将矩阵 'pares' 修改为其他值,以产生更好的 RMSE。一旦有 27 个值的许多组合可以在 0-90 范围内,我必须得到一个解决方案,可以优化此搜索以获得最小 RMSE。

代码注释中的部分(带有 'pares' 的 for 循环)是我不知道该怎么做的事情,因为我必须更改 'pares' 的值但有一些优化标准可以接近 RMSE 的最小值。

希望这次我把这个疑惑解释得更好

非常感谢!

好的,这是一个问题的尝试。我不确定结果最终会有多大用处,因为我不了解潜在的问题,也没有真实的数据来测试它。

你是对的,你需要一个优化算法,你的问题似乎比简单的线性代数更复杂。为了进行优化,我使用了优化工具箱中的函数 fminsearch

首先需要定义要优化其值的函数(objective函数)。根据您的代码,这是

function RMSE = fun(pares)
    inclin = pares(:,1);
    azim = pares(:,2);
    Ii = zeros(8760,27);
    Di = zeros(8760,27);
    Gi = zeros(8760,27);
    for n=1:27
        Ii(:,n) = Ih.*(sind(decl).*sind(lat).*cosd(inclin(n))-sind(decl).*cosd(lat).*sind(inclin(n)).*cosd(azim(n))+cosd(decl).*cosd(lat).*cosd(inclin(n)).*cosd(HRA)+cosd(decl).*sind(lat).*sind(inclin(n)).*cosd(azim(n)).*cosd(HRA)+cosd(decl).*sind(inclin(n)).*sind(azim(n)).*sind(HRA));
        Di(:,n) = 0.5*Dh.*(1+cosd(inclin(n)));
        Gi(:,n) = (Ii(:,n)+Di(:,n))*A(n,1);
    end
    Gparque = sum(Gi,2);
    max_Gparque = max(Gparque);
    GparqueN = Gparque./max_Gparque;
    RMSE = sqrt(mean((GparqueN-veicN).^2));
end

现在我们可以调用

pares_opt = fminsearch(@fun, randi([0,90],27,2))

使用随机初始化。优化需要相当长的时间,因为 objective 函数的实现效率不高。这是执行相同操作的矢量化版本:

% precompute
cHRA = cosd(HRA);
sHRA = sind(HRA);
sdecl = sind(decl);
cdecl = cosd(decl);
slat = sind(lat);
clat = cosd(lat);

function RMSE = fun(pares)
    % precompute
    cinclin = cosd(pares(:,1))';
    sinclin = sind(pares(:,1))';
    cazim = cosd(pares(:,2))';
    sazim = sind(pares(:,2))';

    Ii = bsxfun(@times, Ih, ...
        sdecl * (slat * cinclin - clat * sinclin .* cazim) ...
        + (cdecl .* cHRA) * (clat * cinclin + slat * sinclin .* cazim) ...
        + (cdecl .* sHRA) * (sinclin .* sazim));
    Di = 0.5 * Dh * (1 + cinclin);
    Gi = (Ii + Di) * diag(A);

    Gparque = sum(Gi,2);
    max_Gparque = max(Gparque);
    GparqueN = Gparque./max_Gparque;
    RMSE = sqrt(mean((GparqueN-veicN).^2));
end

我们尚未实现 pares 位于 [0, 90] 内的约束。一种粗略的方法是插入这些行:

    if any(pares(:) < 0) || any(pares(:) > 90)
        RMSE = inf;
        return
    end

在 objective 函数的开头。

综合起来:

function Raquel

h = randi(24,8760,1);
nd = randi(365,8760,1);
veic = randi(333,8760,1);
max_veic = max(veic);
veicN = veic./max_veic;
Gh = randi(500,8760,1);
Dh = randi(500,8760,1);
Ih = Gh-Dh;
A = randi([300 800], 27,1);

lat = 70;
HRA =15.*(h-12);
decl = 23.27*sind(360*(284+nd)/365);

% precompute
cHRA = cosd(HRA);
sHRA = sind(HRA);
sdecl = sind(decl);
cdecl = cosd(decl);
slat = sind(lat);
clat = cosd(lat);

pares_opt = fminsearch(@fun, randi([0,90],27,2))


    function RMSE = fun(pares)

        if any(pares(:) < 0) || any(pares(:) > 90)
            RMSE = inf;
            return
        end

        % precompute
        cinclin = cosd(pares(:,1))';
        sinclin = sind(pares(:,1))';
        cazim = cosd(pares(:,2))';
        sazim = sind(pares(:,2))';

        Ii = bsxfun(@times, Ih, ...
            sdecl * (slat * cinclin - clat * sinclin .* cazim) ...
            + (cdecl .* cHRA) * (clat * cinclin + slat * sinclin .* cazim) ...
            + (cdecl .* sHRA) * (sinclin .* sazim));
        Di = 0.5 * Dh * (1 + cinclin);
        Gi = (Ii + Di) * diag(A);

        Gparque = sum(Gi,2);
        max_Gparque = max(Gparque);
        GparqueN = Gparque./max_Gparque;
        RMSE = sqrt(mean((GparqueN-veicN).^2));

    end
end

使用模拟数据,如果我 运行 在相同的随机数据上优化两次但初始值不同,我会得到不同的解决方案。这表明 objective 函数存在不止一个局部最小值。希望真实数据不会出现这种情况。