落日圆情 2024-07-09 12:12 采纳率: 0%
浏览 7
已结题

ent 混沌人工蜂群与粒子群混合算法有问题

问题1:从运行结果看在主程序运行第一次,①TCPSO运行出的结果适应度值F_G_best结果为-9次方级,不知和0相比算不算正常误差。②主程序运行第一次TCPSO的最佳粒子的每个维度太大了,起初设置的X_min/X_max为-10/10,得出的最佳粒子的每个维度都取到了上下限,并且适应度值为-4次方级,之后尝试更改上下限到-10000/10000,得到的最佳个体的每个维度在上下限中,适应度越来越接近0,但是粒子还是太大了。

尝试解决方法:通过步进查出了在TCPSO更新粒子位置和速度时,迭代一次粒子每个维度的大小增加很多,所以通过限制速度的范围来减小迭代时粒子的增加量,但作用很小。

img

matlab
clc;
    clear;

% 初始化种群
    
    M = 80;         % 种群规模
    D = 10;         % 维度
    X_min = -10;    % 最小值
    X_max = 10;     % 最大值
    max_iter = 100; % 最大迭代次数

    % 初始化Tent混沌序列
    tent_sequences = generate_tent_population(M, D);
    
    % 将混沌序列映射至解空间
    positions = X_min + (X_max - X_min) * tent_sequences;
    
    % 反向学习策略
    K = rand(size(positions));             % 生成随机数K
    OP = K .* (X_min - X_max) - positions; % 计算反向解
    
    % 选择适应度较好的前N个解作为初始种群
    O = floor(M / 2);
    fitness_values = calculate_fitness([positions; OP]);   % 计算所有解的适应度
    [~, sorted_indices] = sort(fitness_values, 'descend'); % 排序
    best_Indices = sorted_indices(1:O);
    New_group = [positions; OP];
    initial_population = New_group(best_Indices, :);       % 生成初始种群 
    
    % 确定A群和P群的规模
    population_size_A = floor(O / 2);
    population_size_P = O - population_size_A;  
    
    % 将初始种群分为A群和P群
    index = randperm(O);                       % 随机排列种群个体的索引
    index_A = index(1:population_size_A);      % A群的个体索引
    index_P = index(population_size_A+1:end);  % B群的个体索引
    
    % 使用索引划分种群
    population_A = initial_population(index_A, :);
    population_P = initial_population(index_P, :);
    
    % 对population_A和population_P进行规范化
    population_A = max(min(population_A, X_max), X_min);
    population_P = max(min(population_P, X_max), X_min);

    % 输出A群和P群
    disp('Population A:');
    disp(population_A);
    disp('Population P:');
    disp(population_P);

% 初始化最优解
    A_best = initial_population(1, :);    % TCABC算法的最优解,选取初始种群中的一个解
    G_best = initial_population(1, :);    % TCPSO算法的全局最优解,选取初始种群中的一个解
    F_A_best = calculate_fitness(A_best); % TCABC算法的最优解的适应度值
    F_G_best = calculate_fitness(G_best); % TCPSO算法的全局最优解的适应度值
    
    % 主循环
    for iter = 1:max_iter
        
        % 调用TCABC算法
        [A_best, F_A_best] = TCABC(population_A,A_best);
        
        if iter == 1
            isFirstGen = true;
        else
            isFirstGen = false;
        end

        % 调用TCPSO算法
        [G_best, F_G_best] = TCPSO(population_P,G_best,isFirstGen);
        
        % 使用重组算子生成新的最优解
        Best = recombination_operator(A_best, G_best, F_A_best, F_G_best);
        
        % 更新TCABC和TCPSO的最优解
        if iter < max_iter
        A_best = Best;
        G_best = Best;
        end
        
        % 输出当前迭代的最优解
        fprintf('Iteration %d: Best Fitness = %f\n', iter, min(F_A_best, F_G_best));
    end

        % 输出最终的最优解及其适应度值
        if F_A_best < F_G_best
            Real_Best = A_best;
            Real_F_Best = F_A_best;
        else
            Real_Best = G_best;
            Real_F_Best = F_G_best;
        end

        disp('Final Best Solution:');
        disp(Real_Best);
        disp('Final Best Fitness:');
        disp(Real_F_Best);




function initial_population = generate_tent_population(M, D)
    % M: 种群规模
    % D: 维度

    % 初始化种群
    initial_population = zeros(M, D);

    % 生成初始随机种群在 [0, 1] 间的随机数
    for i = 1:M
        for d = 1:D
            initial_population(i, d) = rand();
        end
    end

    % 进行 Tent 混沌映射迭代
    num_iterations = 1; % 这里只需迭代一次,根据需要调整
    for t = 1:num_iterations
        for i = 1:M
            for d = 1:D
                Z_k_d_t = initial_population(i, d);
                if Z_k_d_t < 0.7
                    Z_k_d_t1 = Z_k_d_t / 0.7;
                else
                    Z_k_d_t1 = (10 * (1 - Z_k_d_t)) / 3;
                end
                initial_population(i, d) = Z_k_d_t1;
            end
        end
    end
end


function Best = recombination_operator(A_best, G_best, F_A_best, F_G_best)
    % 获取维数
    D = length(A_best);
    
    % 计算选择概率 P_best
    P_best = F_A_best / (F_G_best + F_A_best);
    
    % 初始化最优解 Best
    Best = zeros(1, D);
    
    % 为每一维产生随机数,并选择对应的最优值
    for d = 1:D
        r = rand();
        if r <= P_best
            Best(d) = A_best(d);
        else
            Best(d) = G_best(d);
        end
    end
end


function f_val = objective_function(individual)
    % 示例目标函数:Sphere函数
    f_val = sum(individual .^ 2);
end


function fitness = calculate_fitness(population)
    % 计算适应度值
    num_individuals = size(population, 1);
    fitness = zeros(num_individuals, 1);
    for i = 1:num_individuals
        f_val = objective_function(population(i, :));
        if f_val >= 0
            fitness(i) = 1 / (1 + f_val);
        else
            fitness(i) = 1 + abs(f_val);
        end
    end
end


function [A_best, F_A_best] = TCABC(population_A,Best)
 

  % Step1 : 初始化参数
    
    NP = 50;                    % 蜂群大小
    foodnumber = NP/2;          % 蜜源数量  
    D = 10;                     % 解的维度
    X_min = -10 * ones(1, D);   % 解空间最小值
    X_max = 10 * ones(1, D);    % 解空间最大值
    Limit = 100;                % 同一蜜源被限制次数
    max_iter = 10;              % 最大迭代次数
    iter = 0;                   % 初始化迭代次数
    
  % Step2 : 把通过混沌反向学习得出的种群中的A种群当作初始蜜源位置
   
    Initial_Foods = population_A;          
 
    
  % Step3 : 计算适应度,筛选出初始蜜源
    
    Initial_Fitness = calculate_fitness(Initial_Foods);                    %计算适应度值
    
    % 筛选出初始蜜源位置
    O = floor(foodnumber / 2);                                  % 选择前O个蜜源位置
    [~, sorted_Indices] = sort(Initial_Fitness, 'descend');
    best_Indices = sorted_Indices(1:O);
    Initial_Foods = Initial_Foods(best_Indices, :);   % 筛选出最佳蜜源位置,即初始蜜源位置
    Initial_Fitness = Initial_Fitness(best_Indices);                    % 筛选出最佳蜜源位置的适应度值,即最佳的适应度值
    trial = zeros(O, 1);                                        % 初始化蜜源位置的试验计数
    
    % 预设值
    F_A_best = -Inf;  
    A_best = zeros(O, 1);

% 开始迭代
while iter < max_iter
    iter = iter + 1;
  
  % Step4、5 : 采蜜蜂阶段并更新个体
    
    for i = 1:O
    % 参数随机可变
    Param1Change = fix(rand * D) + 1;
    % 随机选择一个参数进行变化,生成一个介于 1 和 D 之间的整数,表示选择哪个维度进行变化。
    neighbour = fix(rand * O) + 1;
    % 随机选择另一个食物源作为邻居,生成一个介于 1 和 foodnumber 之间的整数,表示选择哪个邻居食物源。
    while neighbour == i
        neighbour = fix(rand * O) + 1;  % 确保 neighbour 不等于 i。
    end

    sol = Initial_Foods(i, :);          % 选择上一代中的第 i 个个体
    sol(Param1Change) = Initial_Foods(i, Param1Change) + (Initial_Foods(i, Param1Change) - Initial_Foods(neighbour, Param1Change)) * (rand - 0.5) * 2;
    % 使用当前解 i 和随机选择的邻居解之间的差值进行更新,(rand - 0.5) * 2 生成一个在 [-1, 1] 之间的随机数。

    % 个体取值范围约束
    ind = find(sol < X_min);  % 最小值约束
    sol(ind) = X_min(ind);
    ind = find(sol > X_max);  % 最大值约束
    sol(ind) = X_max(ind);

    % 估计新的目标函数值和适应度值
    FitnessSol = calculate_fitness(sol);

    % 更新最优个体值
    if FitnessSol > Initial_Fitness(i)            % 如果新产生的个体值适应度值越大,则表明函数值越小,则个体最优
        Initial_Foods(i, :) = sol;
        Initial_Fitness(i) = FitnessSol;
        trial(i) = 0;
    else
        trial(i) = trial(i) + 1;                  % 如果解 i 不能改善,增加其试验计数,即拖尾数+1
    end
    
    end


  % Step6、7 : 观望蜂阶段并更新个体,记录最佳位置与适应度值
    
    for i = 1:O
    % 锦标赛选择策略,初始化得分数组
    scores = zeros(O, 1);
    
    % 随机选取两个个体进行适应度比较,并对适应度较大的个体加1分
    for j = 1:O
        candidates = randperm(O, 2); % 随机选择两个个体
        if Initial_Fitness(candidates(1)) > Initial_Fitness(candidates(2))
            scores(candidates(1)) = scores(candidates(1)) + 1;
        else
            scores(candidates(2)) = scores(candidates(2)) + 1;
        end
    end
    
    % 确保至少每个个体都参与一轮
    for j = 1:O
        if scores(j) == 0
            % 若该个体未得分,则进行一次自我比较,确保至少参与一轮
            scores(j) = scores(j) + 1;
        end
    end

    % 计算每个蜜源被选择的概率
    probabilities = scores / sum(scores);
    
    % 按概率选择一个蜜源
    selected = find(rand <= cumsum(probabilities), 1);
    
    Param2Change = fix(rand * D) + 1;  % 随机选择一个参数进行变化
    
    if iter == 1
        neighbour_index = fix(rand * O) + 1;
        while neighbour_index == selected
            neighbour_index = fix(rand * O) + 1;
        end
        neighbour = Initial_Foods(neighbour_index, :); % 确保 neighbour 是一个向量
    else
        neighbour = Best; % 使用重组算子产生的最佳解 Best 作为邻居
    end

    sol = Initial_Foods(selected, :);
    sol(Param2Change) = Initial_Foods(selected, Param2Change) + ...
        (Initial_Foods(selected, Param2Change) - neighbour(Param2Change)) * (rand - 0.5) * 2;
   
  % 个体取值范围约束
    ind = find(sol < X_min);
    sol(ind) = X_min(ind);
    ind = find(sol > X_max);
    sol(ind) = X_max(ind);
    
    % 估计新的目标函数值和适应度值
    
    FitnessSol = calculate_fitness(sol);
    
    % 更新最优个体值
    if FitnessSol > Initial_Fitness(selected)
        Initial_Foods(selected, :) = sol;
        Initial_Fitness(selected) = FitnessSol;
        trial(selected) = 0;
    else
        trial(selected) = trial(selected) + 1;
    end
    
    end


  % Step8 : 侦察蜂阶段 

    for i = 1:O
    
        if trial(i) > Limit                    
        tent_sequence = rand(1, D);                                       % 生成一个随机向量
        for j = 1:10                                                      % 使用Tent混沌映射进行多次迭代
            tent_sequence = arrayfun(@tent_map, tent_sequence);
        end
        Initial_Foods(i, :) = X_min + (X_max - X_min) .* tent_sequence;   % 将Tent混沌序列映射到解空间范围内
        Initial_Fitness = calculate_fitness(Initial_Foods);
        trial(i) = 0;
        end
    
    end

  % Step9 : 记录全局最佳蜜源和适应度值
    [best_fitness, best_index] = max(Initial_Fitness);
    best_food = Initial_Foods(best_index, :);

    %判断是否需要更新全局最佳
    if iter == 1 || best_fitness > F_A_best
       F_A_best = best_fitness;
       A_best = best_food;
    end

end

    fprintf('A_best : %s\n', mat2str(A_best));
    fprintf('F_A_best : %f\n', F_A_best);

end


function [G_Best, F_G_best] = TCPSO(population_P,Best,isFirstGen)

  % Step1 : 初始化算法相关参数

N = 15;          % 选取适应度较好的个体数量
D = 10;          % 粒子维数
X_min = -10000;  % 各维的取值范围
X_max = 10000;      
C1 = 1.5;        % 学习因子
C2 = 1.5;        
W = 0.5;         % 惯性权重
max_iter = 100;  % 最大迭代次数
max_velocity = (X_max - X_min) / 10; % 最大速度限制


% Step2 : 输入population_P作为若干初始蜜源

positions = population_P; 


% Step3 : 计算粒子适应度值, 选取适应度较好的N个位置作为初始位置, 并随机产生N个初始速度

fitness_values = calculate_fitness(positions);                    %计算适应度值
[~, sorted_indices] = sort(fitness_values);                       % 按适应度排序
positions1 = positions(sorted_indices(1:N), :);                   % 选取适应度较好的N个位置,即初始位置
velocities = X_min + (X_max - X_min) * rand(N, D);                % 生成N个初始速度

% Step4-5 : 更新群体最佳个体及适应度,更新最佳个体及适应度

fitness_values1 = calculate_fitness(positions1);                   %计算适应度值
[best_fitness,idx] = min(fitness_values1);                         % 计算出初始位置的适应度值的最小值与索引

if isFirstGen
    F_G_best = best_fitness;                                       % 初代群体位置最优适应度
    G_Best = positions1(idx, :);                                   % 初代群体最优个体
else
    F_G_best = calculate_fitness(Best);
    G_Best = Best;
end

best_positions = positions1;                                       % 每个粒子在搜索过程中的历史最佳位置矩阵   
fitness_best = fitness_values1;                                    % 个体最佳适应度 

% Step6 : 更新粒子位置和速度

for i = 1 : max_iter
    
    for j = 1 : N
    
        % 速度更新并限制在最大速度范围内
        velocities(j,:) = W * velocities(j,:) + C1 * rand * (best_positions(j,:) - positions1(j,:))...
        + C2 * rand *(G_Best - positions1(j,:));
        velocities(j,:) = max(min(velocities(j,:), max_velocity), -max_velocity);

        % 位置更新
        positions1(j,:) = positions1(j,:) + velocities(j,:);
        positions1(j,positions1(j,:) > X_max) = X_max;
        positions1(j,positions1(j,:) < X_min) = X_min;
        
        % 适应度值更新
        fitness_values1(j) = calculate_fitness(positions1(j,:));
        
        % 更新个体最优位置
        if fitness_values1(j) < fitness_best(j)
           best_positions(j,:) = positions1(j,:);
           fitness_best(j) = calculate_fitness(positions1(j,:));
        end
     
        % 更新全局最优位置
        if fitness_values1(j) < F_G_best
            F_G_best = fitness_values1(j);
            G_Best = positions1(j,:);
        end
        
    end
    
    % Step7 : 针对当前最优位置Global_best_positions, 利用Tent混沌搜索产生最优新解Gbest
    
    tent_Global_best_positions = generate_tent_population(1, D);
    
    tent_G_best_positions = X_min + (X_max - X_min) * tent_Global_best_positions; % 将Tent混沌序列映射到粒子位置范围内
    tent_G_best_fitness = calculate_fitness(tent_G_best_positions);               %计算适应度值
    
    % Step8 : 利用tent_G_best_positions替代种群任意一粒子的位置,作用:增加种群的变异性,使算法更容易跳出局部最优解,找到更好的全局最优解。
    
    if tent_G_best_fitness < F_G_best
        G_Best = tent_G_best_positions;
        F_G_best = tent_G_best_fitness;
    end

    % 替代种群任意一粒子的位置
    replace_idx = randi(N);
    positions1(replace_idx, :) = tent_G_best_positions;          % positions1为当代种群
    fitness_values1(replace_idx) = tent_G_best_fitness;          % fitness_values1为当代适应度值

    % 检查停止条件
    if F_G_best < 1e-6                                           % 假设阈值1e-6
        break;
    end

end

% 输出最佳解和最佳适应度值
fprintf('G_Best : %s\n', mat2str(G_Best));
fprintf('F_G_best: %f\n', F_G_best);

end
  • 写回答

16条回答 默认 最新

  • 专家-皆知 2024-07-09 12:13
    关注

    参考免费微信小程序:皆我百晓生 作答,经由专家-皆知整理回复,如问题解决,望采纳;如仍有疑问,请评论回复。

    根据你提供的代码和问题描述,我理解到你在使用混沌人工蜂群和粒子群混合算法时遇到了一些困难。问题主要集中在算法运行结果的适应度值异常以及粒子位置更新过快导致粒子维度过大。以下是一些可能的解决方案:

    1. 适应度值异常:适应度值异常可能与目标函数的尺度有关。如果目标函数的输出值范围很大,适应度值可能会变得非常小。你可以尝试归一化目标函数的输出值,或者调整适应度函数,使其更加适合你的优化问题。

    2. 粒子位置更新过快:你已经尝试通过限制速度范围来减小粒子位置的增加量,但效果不明显。这里可以考虑以下几点:

      • 调整粒子群优化(PSO)中的惯性权重(W)、个体学习因子(C1)和全局学习因子(C2)的值。这些参数对粒子位置的更新有直接影响。
      • 在更新粒子速度时,可以考虑增加一个速度衰减因子,使得粒子速度随迭代次数增加而逐渐减小。
      • 考虑引入一个动态调整粒子速度的机制,例如根据适应度值的变化来调整速度。
    3. 粒子维度过大:粒子维度过大可能是因为粒子在搜索空间中快速移动。可以尝试以下方法:

      • 增加搜索空间的范围限制,例如通过缩放X_min和X_max的值。
      • 在粒子位置更新时加入一个边界处理机制,确保粒子不会超出预设的边界。

    以下是针对上述建议的一些代码修改示例:

    % 调整TCPSO算法中的参数
    function [G_Best, F_G_best] = TCPSO(population_P,Best,isFirstGen)
        % ...(省略其他部分)
    
        % 引入速度衰减因子
        decay_factor = 0.99; % 每次迭代速度减少1%
    
        % Step6 : 更新粒子位置和速度
        for i = 1 : max_iter
            for j = 1 : N
                % 更新速度时加入速度衰减因子
                velocities(j,:) = velocities(j,:) * decay_factor ...
                    + W * rand * (best_positions(j,:) - positions1(j,:)) ...
                    + C1 * rand * (best_positions(j,:) - positions1(j,:)) ...
                    + C2 * rand * (G_Best - positions1(j,:));
    
                % 限制速度范围
                velocities(j,:) = max(min(velocities(j,:), max_velocity), -max_velocity);
    
                % ...(省略其他部分)
    
                % 更新粒子位置时加入边界处理
                positions1(j,:) = min(max(positions1(j,:) + velocities(j,:), X_min), X_max);
            end
            % ...(省略其他部分)
        end
        % ...(省略其他部分)
    end
    

    请注意,这些修改只是示例,实际效果可能需要根据你的具体问题进行调整。希望这些建议能帮助你解决问题。如果需要进一步的帮助,请随时告诉我。

    评论

报告相同问题?

问题事件

  • 已结题 (查看结题原因) 7月10日
  • 创建了问题 7月9日

悬赏问题

  • ¥15 在matlab中Application Compiler后的软件无法打开
  • ¥15 想问一下STM32创建工程模板时遇到得问题
  • ¥15 Fiddler抓包443
  • ¥20 Qt Quick Android 项目报错及显示问题
  • ¥15 而且都没有 OpenCVConfig.cmake文件我是不是需要安装opencv,如何解决?
  • ¥15 oracleBIEE analytics
  • ¥15 H.264选择性加密例程
  • ¥50 windows的SFTP服务器如何能批量同步用户信息?
  • ¥15 centos7.9升级python3.0的问题
  • ¥15 安装CentOS6时卡住