一、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]);
}
}
}
您可以选择一种方式赞助本站
支付宝扫一扫赞助
微信钱包扫描赞助
赏