Back
Bee Algorithm
Overview
The BeeAlgorithm class in the df::ml namespace implements the
Artificial Bee Colony (ABC) optimization algorithm. Inspired by the foraging behavior of
honey bees, the ABC algorithm uses three types of bees (employed, onlooker, and scout) to
explore the search space. It is effective for both continuous and combinatorial optimization
problems and is known for its simplicity and good exploration capabilities.
BeeAlgorithm Class
Class Definition
namespace df::ml {
class BeeAlgorithm {
public:
// Constructor with configuration parameters
BeeAlgorithm(
size_t colony_size = 100, // Total colony size
size_t employed_bees = 50, // Number of employed bees
size_t onlooker_bees = 50, // Number of onlooker bees
size_t max_iterations = 1000, // Maximum number of cycles
size_t abandonment_limit = 20 // Trials before abandoning a source
);
// Optimize a continuous objective function
// fitness: function returning fitness value (higher = better)
// bounds: {min, max} for each dimension
std::vector<double> optimize(
std::function<double(const std::vector<double>&)> fitness,
const std::vector<std::pair<double, double>> &bounds
);
// Optimize a combinatorial problem (permutation-based)
std::vector<size_t> optimize_combinatorial(
std::function<double(const std::vector<size_t>&)> fitness,
size_t num_elements
);
// Get the history of best fitness per iteration
std::vector<double> get_evolution_history() const;
// Get current population statistics
struct PopulationMetrics {
double best_fitness;
double worst_fitness;
double mean_fitness;
double diversity;
};
PopulationMetrics get_population_metrics() const;
};
} // namespace df::ml
The ABC algorithm operates in three phases per iteration:
- Employed bees: Each employed bee exploits a food source (candidate solution) by searching in its neighborhood.
- Onlooker bees: Select food sources based on their quality (fitness-proportionate selection) and further exploit promising solutions.
- Scout bees: When a food source is not improved after
abandonment_limittrials, it is abandoned and replaced with a random new source.
Factory Functions
Factory Functions
namespace df::ml {
// Create a bee algorithm with default settings for continuous optimization
BeeAlgorithm create_bee_algorithm(
size_t colony_size = 100,
size_t max_iterations = 1000
);
// Create a bee algorithm configured for combinatorial optimization
BeeAlgorithm create_bee_algorithm_combinatorial(
size_t colony_size = 100,
size_t max_iterations = 1000
);
} // namespace df::ml
Examples
Continuous Optimization
Minimize Sphere Function
#include <dataframe/ml/bee_algorithm.h>
#include <iostream>
#include <cmath>
int main() {
// Sphere function: f(x) = sum(x_i^2), minimum at origin
auto sphere = [](const std::vector<double> &x) -> double {
double sum = 0;
for (double xi : x) sum += xi * xi;
return -sum; // Negate because ABC maximizes
};
// Create ABC optimizer
df::ml::BeeAlgorithm abc(
80, // colony size
40, // employed bees
40, // onlooker bees
2000, // max iterations
30 // abandonment limit
);
// 5-dimensional search in [-10, 10]
std::vector<std::pair<double, double>> bounds(5, {-10.0, 10.0});
auto best = abc.optimize(sphere, bounds);
std::cout << "Best solution: (";
for (size_t i = 0; i < best.size(); ++i) {
if (i > 0) std::cout << ", ";
std::cout << best[i];
}
std::cout << ")\n";
// Check convergence
auto history = abc.get_evolution_history();
std::cout << "Iterations: " << history.size() << "\n";
std::cout << "Final best fitness: " << history.back() << "\n";
auto metrics = abc.get_population_metrics();
std::cout << "Population diversity: " << metrics.diversity << "\n";
return 0;
}
Combinatorial Optimization
Assignment Problem
// Cost matrix: cost[i][j] = cost of assigning task i to worker j
std::vector<std::vector<double>> cost = {
{9, 2, 7, 8},
{6, 4, 3, 7},
{5, 8, 1, 8},
{7, 6, 9, 4}
};
auto assignment_fitness = [&](const std::vector<size_t> &perm) -> double {
double total = 0;
for (size_t i = 0; i < perm.size(); ++i) {
total += cost[i][perm[i]];
}
return -total; // Minimize total cost
};
auto abc = df::ml::create_bee_algorithm_combinatorial(60, 3000);
auto best_assignment = abc.optimize_combinatorial(assignment_fitness, 4);
std::cout << "Best assignment:\n";
for (size_t i = 0; i < best_assignment.size(); ++i) {
std::cout << " Task " << i << " -> Worker " << best_assignment[i]
<< " (cost: " << cost[i][best_assignment[i]] << ")\n";
}
Comparison with Genetic Algorithm
Side-by-Side Comparison
// Compare GA and ABC on the same problem
auto fitness = [](const std::vector<double> &x) -> double {
return -(x[0]*x[0] + x[1]*x[1]); // Sphere function
};
std::vector<std::pair<double,double>> bounds{{-10,10}, {-10,10}};
// Genetic Algorithm
auto ga = df::ml::create_genetic_algorithm(100, 500);
auto ga_result = ga.optimize(fitness, bounds);
// Bee Algorithm
auto abc = df::ml::create_bee_algorithm(100, 500);
auto abc_result = abc.optimize(fitness, bounds);
std::cout << "GA best: (" << ga_result[0] << ", " << ga_result[1] << ")\n";
std::cout << "ABC best: (" << abc_result[0] << ", " << abc_result[1] << ")\n";