实现简单的人工蜂群算法(ABC),用MATLAB和Java实现

avatar 2024年05月28日11:07:24 0 76 views
博主分享免费Java教学视频,B站账号:Java刘哥 ,长期提供技术问题解决、项目定制:本站商品点此

一、MATLAB实现

clc;clear;

% 定义常量
num_employed_beas = 20;
num_onlooker_beas = 20;
dim = 2;
max_generations = 1000;
limit = 1000;

target_function = @(x) x(1) ^ 2 + (x(2) - 2) ^ 2;
bounds =  [-10, 10];

% 初始化
populations = rand(num_employed_beas, dim) * (bounds(2) - bounds(1)) + bounds(1);
fitness = arrayfun(@(i) target_function(populations(i, :)), 1:num_employed_beas);
trail_count = zeros(num_employed_beas);

% 循环
for gen=1:max_generations
    % 雇佣蜂阶段
    for i=1:num_employed_beas
        % 产生新解 xi = xi + (xr1 - xi) * rand
        other_index = randi(num_employed_beas);
        while other_index == i
            other_index = randi(num_employed_beas);
        end
        dimension = randi(dim);
        new_solution = populations(i, :);
        new_solution(dimension) = populations(i, dimension) ...
        + (populations(other_index, dimension) - populations(i, dimension)) ...
        * (rand() - 0.5 ) * 2;

        % 求适应度
        new_fitness = target_function(new_solution);

        % 选择更新
        if new_fitness < fitness(i)
            fitness(i) = new_fitness;
            populations(i, :) = new_solution;
            trail_count(i) = 0;
        else
            trail_count(i) = trail_count(i) + 1;
        end

    end

    % 观察蜂阶段
    for j=1:num_onlooker_beas
        route_wheel = cumsum((1 ./ fitness) / sum (1 ./ fitness));
        r = rand();
        i = find(route_wheel >= r, 1);


        % 产生新解 xi = xi + (xr1 - xi) * rand
        other_index = randi(num_employed_beas);
        while other_index == i
            other_index = randi(num_employed_beas);
        end
        dimension = randi(dim);
        new_solution = populations(i, :);
        new_solution(dimension) = populations(i, dimension) ...
        + (populations(other_index, dimension) - populations(i, dimension)) ...
        * (rand() - 0.5 ) * 2;
        
        % 将解限定在边界内
        new_solution = min(max(new_solution, bounds(1)), bounds(2));

        % 求适应度
        new_fitness = target_function(new_solution);

        % 选择更新
        if new_fitness < fitness(i)
            fitness(i) = new_fitness;
            populations(i, :) = new_solution;
            trail_count(i) = 0;
        else
            trail_count(i) = trail_count(i) + 1;
        end

    end

    % 侦查蜂阶段
    for i=1:num_employed_beas
        if trail_count(i) >= limit
            trail_count(i) = 0;
            populations(i, :) = rand(1, dim) * (bounds(2) - bounds(1)) + bounds(1);
            fitness(i) = target_function(populations(i, :));
        end
    end

    % 最优解
    [bestFitness, bestIndex] = min(fitness);
    bestSolution = populations(bestIndex, :);

    fprintf("%d次,fitness:%d,x1:%d, x2:%d \n", gen, bestFitness, bestSolution(1), bestSolution(2));
end

二、Java实现

package com.liuyanzhao.abc;

import java.util.Random;

/**
 * @author 言曌
 * @since 2024/5/28 19:48
 */
public class MyABC1 {

    // 目标函数
    public static double targetFunction(double[] x) {
        return Math.pow(x[0], 2) + Math.pow((x[1] - 2), 2);
    }

    // 求累加概率
    private static double[] getCumulativeProbabilities(double[] fitness) {
        double[] cumulativeProbabilities = new double[fitness.length];
        double sum = 0;
        for (double v : fitness) {
            sum += 1 / v;
        }
        for (int i = 0; i < fitness.length; i++) {
            cumulativeProbabilities[i] = 1 / fitness[i] / sum;
        }
        for (int i = 1; i < fitness.length; i++) {
            cumulativeProbabilities[i] += cumulativeProbabilities[i - 1];
        }
        return cumulativeProbabilities;
    }

    // 轮盘赌选择
    private static int rouletteWheelSelect(double[] fitness) {
        double[] cumulativeProbabilities = getCumulativeProbabilities(fitness);
        Random random = new Random();
        double r = random.nextDouble();
        for (int i = 0; i < cumulativeProbabilities.length; i++) {
            if (cumulativeProbabilities[i] >= r) {
                return i;
            }
        }
        return cumulativeProbabilities.length - 1;
    }


    // 获得最小值下标
    private static int getMinIndex(double[] fitness) {
        int minIndex = 0;
        for (int i = 1; i < fitness.length; i++) {
            if (fitness[i] < fitness[minIndex]) {
                minIndex = i;
            }
        }
        return minIndex;
    }

    // 开采阶段
    private static void develop(int numEmployedBees, int dim,
                                double[][] populations, double[] fitness,
                                double[] trailCount, double[] bounds,
                                int i) {
        Random random = new Random();
        // 产生新解 vi = xi + (xi - xr1) * rand
        int otherIndex = random.nextInt(numEmployedBees);
        while (otherIndex == i) {
            otherIndex = random.nextInt(numEmployedBees);
        }
        int dimension = random.nextInt(dim);

        // 以下代码会修改populations[i],导致导致原种群数据被篡改
        //  double[] newSolution = populations[i]; // 重大Bug
        double[] newSolution = populations[i].clone();
        newSolution[dimension] = populations[i][dimension] +
                (populations[i][dimension] - populations[otherIndex][dimension]) *
                        (random.nextDouble() - 0.5) * 2;

        // 将解限定在边界内
        for (int j = 0; j < dim; j++) {
            newSolution[j] = Math.min(Math.max(newSolution[j], bounds[0]), bounds[1]);
        }

        // 求适应度
        double newFitness = targetFunction(newSolution);

        // 选择更新
        if (newFitness < fitness[i]) {
            populations[i] = newSolution;
            fitness[i] = newFitness;
            trailCount[i] = 0;
        } else {
            trailCount[i]++;
        }
    }


    public static void main(String[] args) {
        Random random = new Random();
        // 定义常量
        int maxGenerations = 1000;
        int limit = 1000;
        int dim = 2;
        int numEmployedBees = 20;
        int numOnlookerBees = 20;
        double[] bounds = {-10, 10};

        // 初始化种群
        double[][] populations = new double[numEmployedBees][dim];
        double[] fitness = new double[numEmployedBees];
        double[] trailCount = new double[numEmployedBees];
        for (int i = 0; i < numEmployedBees; i++) {
            for (int j = 0; j < dim; j++) {
                populations[i][j] = random.nextDouble() * (bounds[1] - bounds[0]) + bounds[0];
            }
            fitness[i] = targetFunction(populations[i]);
            trailCount[i] = 0;
        }

        // 循环
        for (int gen = 0; gen < maxGenerations; gen++) {
            // 雇佣蜂阶段
            for (int i = 0; i < numEmployedBees; i++) {
                develop(numEmployedBees, dim, populations, fitness, trailCount, bounds, i); // 开采
            }

            // 观察蜂阶段
            for (int j = 0; j < numOnlookerBees; j++) {
                int selectedIndex = rouletteWheelSelect(fitness); // 选择一个食物源
                develop(numEmployedBees, dim, populations, fitness, trailCount, bounds, selectedIndex); // 开采
            }

            // 侦查蜂阶段
            for (int i = 0; i < numEmployedBees; i++) {
                if (trailCount[i] >= limit) {
                    trailCount[i] = 0;
                    for (int j = 0; j < dim; j++) {
                        populations[i][j] = random.nextDouble() * (bounds[1] - bounds[0]) + bounds[0];
                    }
                    fitness[i] = targetFunction(populations[i]);
                }
            }


            // 输出结果
            int minIndex = getMinIndex(fitness);
            double[] solution = populations[minIndex];
            System.out.printf("%d次,fitness:%s, x1:%s, x2:%s \n", gen + 1, fitness[minIndex], solution[0], solution[1]);
        }

    }
}

 

 

 
 

 

 

  • 微信
  • 交流学习,有偿服务
  • weinxin
  • 编程爱好者交流群
  • 资源分享,问题解决,技术交流。QQ群:424285828(新群)
  • weinxin
avatar

发表评论

avatar 登录者:匿名
匿名评论,评论回复后会有邮件通知

  

已通过评论:0   待审核评论数:0