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_limit trials, 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";