src/aco.cpp
/**
    * Runs the algorithm until stop_condition is reached.
    */
Runs the algorithm until stop_condition is reached.
Runs the algorithm until stop_condition is reached .
void ACO::run(StopCondition *stop_condition) {
    LOG_SCOPE_F(INFO, "run");
    stop_condition->start();
    run_init();
    auto cmp = [](auto l, auto r) { return l->cost() < r->cost(); };
    for ( ; !stop_condition->is_reached(); stop_condition->next_iteration()) {
        build_ant_solutions();
        iteration_best_ = *min_element(begin(ants_), end(ants_), cmp);
        const auto cost = iteration_best_->cost();
        if (!global_best_cost_no_ls_ || global_best_cost_no_ls_ > cost) {
            global_best_cost_no_ls_ = cost;
            global_best_values_no_ls_.push_back(cost);
        }
        apply_local_search();
        iteration_best_ = *min_element(begin(ants_), end(ants_), cmp);
        if (!global_best_ || global_best_->cost() > iteration_best_->cost()) {
            global_best_ = make_shared<Ant>(*iteration_best_);
            if (new_best_found_callback_) {
                new_best_found_callback_(*this);
            }
        } else {
        }
        if (!restart_best_ || restart_best_->cost() > iteration_best_->cost()) {
            restart_best_ = make_shared<Ant>(*iteration_best_);
            restart_best_found_iteration_ = current_iteration_;
        }
        const auto best_cost = global_best_->cost();
        max_pheromone_ = 1. / (best_cost * evaporation_rate_);
        min_pheromone_ = max_pheromone_ / (2 * instance_.dimension_);
        pheromone_->set_trail_limits(min_pheromone_, max_pheromone_);
        pheromone_->evaporate(evaporation_rate_);
        Ant* update_ant = nullptr;
        if (current_iteration_ % u_gb_ != 0) {
            update_ant = iteration_best_.get();
        } else {
            if (u_gb_ == 1
                && (current_iteration_ - restart_best_found_iteration_) > 50) {
                update_ant = global_best_.get();
            } else {
                update_ant = restart_best_.get();
            }
        }
        double deposit = 1. / update_ant->cost();
        auto prev = update_ant->get_route().back();
        for (auto market : update_ant->get_route()) {
            pheromone_->increase(prev, market, deposit);
            prev = market;
        }
        if ((current_iteration_ + 1) % 100 == 0) {
            const auto lambda = 0.05;
            const auto branching_factor_threshold = 1.00001;
            const auto branching_factor = node_branching(lambda, cand_list_size_,
                                                         *pheromone_, instance_);
            LOG_F(WARNING, "Branching factor: %lf", branching_factor);
            if ((current_iteration_ - restart_best_found_iteration_ > 250)
                && branching_factor < branching_factor_threshold) {
                LOG_F(WARNING, "Resetting pheromone at iteration: %d",
                      current_iteration_);
                pheromone_->set_all_trails(max_pheromone_);
                restart_best_ = nullptr;
                pheromone_reset_iteration_ = current_iteration_;
                global_best_cost_no_ls_ = numeric_limits<int>::max();
                global_best_values_no_ls_.clear();
            }
        }
        ++current_iteration_;
        update_u_gb();
    }
    LOG_F(INFO, "Final best value: %d", global_best_->cost());
    LOG_F(INFO, "Best ant affinity: %lf", global_best_->affinity_);
    LOG_F(INFO, "Best ant laziness_: %lf", global_best_->laziness_);
    LOG_F(INFO, "Best ant avidity_: %lf", global_best_->avidity_);
}
void ACO :: run ( StopCondition * stop_condition ) { LOG_SCOPE_F ( INFO , " " ) ; stop_condition -> start ( ) ; run_init ( ) ; auto cmp = [ ] ( auto l , auto r ) { return l -> cost ( ) < r -> cost ( ) ; } ; for ( ; ! stop_condition -> is_reached ( ) ; stop_condition -> next_iteration ( ) ) { build_ant_solutions ( ) ; iteration_best_ = * min_element ( begin ( ants_ ) , end ( ants_ ) , cmp ) ; const auto cost = iteration_best_ -> cost ( ) ; if ( ! global_best_cost_no_ls_ || global_best_cost_no_ls_ > cost ) { global_best_cost_no_ls_ = cost ; global_best_values_no_ls_ . push_back ( cost ) ; } apply_local_search ( ) ; iteration_best_ = * min_element ( begin ( ants_ ) , end ( ants_ ) , cmp ) ; if ( ! global_best_ || global_best_ -> cost ( ) > iteration_best_ -> cost ( ) ) { global_best_ = make_shared < Ant > ( * iteration_best_ ) ; if ( new_best_found_callback_ ) { new_best_found_callback_ ( * this ) ; } } else { } if ( ! restart_best_ || restart_best_ -> cost ( ) > iteration_best_ -> cost ( ) ) { restart_best_ = make_shared < Ant > ( * iteration_best_ ) ; restart_best_found_iteration_ = current_iteration_ ; } const auto best_cost = global_best_ -> cost ( ) ; max_pheromone_ = 1. / ( best_cost * evaporation_rate_ ) ; min_pheromone_ = max_pheromone_ / ( 2 * instance_ . dimension_ ) ; pheromone_ -> set_trail_limits ( min_pheromone_ , max_pheromone_ ) ; pheromone_ -> evaporate ( evaporation_rate_ ) ; Ant * update_ant = nullptr ; if ( current_iteration_ % u_gb_ != 0 ) { update_ant = iteration_best_ . get ( ) ; } else { if ( u_gb_ == 1 && ( current_iteration_ - restart_best_found_iteration_ ) > 50 ) { update_ant = global_best_ . get ( ) ; } else { update_ant = restart_best_ . get ( ) ; } } double deposit = 1. / update_ant -> cost ( ) ; auto prev = update_ant -> get_route ( ) . back ( ) ; for ( auto market : update_ant -> get_route ( ) ) { pheromone_ -> increase ( prev , market , deposit ) ; prev = market ; } if ( ( current_iteration_ + 1 ) % 100 == 0 ) { const auto lambda = 0.05 ; const auto branching_factor_threshold = 1.00001 ; const auto branching_factor = node_branching ( lambda , cand_list_size_ , * pheromone_ , instance_ ) ; LOG_F ( WARNING , " " , branching_factor ) ; if ( ( current_iteration_ - restart_best_found_iteration_ > 250 ) && branching_factor < branching_factor_threshold ) { LOG_F ( WARNING , " " , current_iteration_ ) ; pheromone_ -> set_all_trails ( max_pheromone_ ) ; restart_best_ = nullptr ; pheromone_reset_iteration_ = current_iteration_ ; global_best_cost_no_ls_ = numeric_limits < int > :: max ( ) ; global_best_values_no_ls_ . clear ( ) ; } } ++ current_iteration_ ; update_u_gb ( ) ; } LOG_F ( INFO , " " , global_best_ -> cost ( ) ) ; LOG_F ( INFO , " " , global_best_ -> affinity_ ) ; LOG_F ( INFO , " " , global_best_ -> laziness_ ) ; LOG_F ( INFO , " " , global_best_ -> avidity_ ) ; }
Runs the algorithm until stop_condition is reached.
Runs the algorithm until stop_condition is reached .
// For sorting ants according to the cost of a solution //pheromone_->add_solution(global_best_->solution_.route_, //global_best_->cost()); //pheromone_->add_solution(global_best_->solution_.route_, //global_best_->cost()); //const auto threshold = global_best_->cost() * 1.01; //if (iteration_best_->cost() < threshold) { //pheromone_->add_solution(iteration_best_->solution_.route_, iteration_best_->cost()); //} // Update pheromone levels' limits // Evaporate & update pheromone