src/main.cc
/*
 * Calculates the next node the given ant should move to from its current
 * position. This is a version optimized for SelectivePheromoneMemory
 */
Calculates the next node the given ant should move to from its current
position. This is a version optimized for SelectivePheromoneMemory
Calculates the next node the given ant should move to from its current position . This is a version optimized for SelectivePheromoneMemory
uint32_t acs_calc_move(Ant &ant, 
                       const vector<vector<double>> &heuristic_matrix,
                       const vector<vector<double>> & ,
                       const vector<vector<uint32_t>> &nn_lists,
                       double q0,
                       mt19937 &rng,
                       SelectivePheromoneMemory *pheromone_memory
                       ) {
    auto &memory = *pheromone_memory;
    uint32_t next_node = ant.nodes_count_ + 1;
    const uint32_t curr = ant.visited_.back();
    static uint32_t cand_set[64];
    assert( heuristic_matrix.size() > curr );
    auto &heuristic = heuristic_matrix.at(curr);
    uint32_t cand_count = 0;
    auto &nn = nn_lists[curr];
    for (auto node : nn) {
        if (!ant.is_visited_[node]) {
            cand_set[cand_count++] = node;
            break ;
        }
    }
    if (cand_count) {
        uniform_real_distribution<> random_double(0.0, 1.0);
        double q = random_double(rng);
        if (q < q0) { 
            double max_product = 0;
            auto &trails = memory.get_trails(curr);
            for (uint32_t i = 0; i < trails.size(); ++i) {
                auto &e = trails[i];
                auto node = e.first;
                if ( !ant.is_visited_[node] ) {
                    const double product = e.second * heuristic[node];
                    if (product > max_product) {
                        max_product = product;
                        next_node = node;
                    }
                }
            }
            auto node = cand_set[0];
            const double product = memory.default_pheromone() * heuristic[node];
            if (product > max_product) {
                next_node = node;
            }
        } else { 
            cand_count = 0;
            double sum = 0.0;
            for (auto node : nn) {
                if (!ant.is_visited_[node]) {
                    cand_set[cand_count++] = node;
                    const double product = memory.default_pheromone() * heuristic[node];
                    sum += product;
                }
            }
            const uint32_t nn_end = cand_count;
            auto &trails = memory.get_trails(curr);
            for (uint32_t i = 0; i < trails.size(); ++i) {
                auto &e = trails[i];
                auto node = e.first;
                if ( !ant.is_visited_[node] ) {
                    cand_set[cand_count++] = node;
                    const double product = e.second * heuristic[node];
                    sum += product;
                }
            }
            next_node = cand_set[0];
            const double r = random_double(rng) * sum;
            double v = 0.0;
            for (uint32_t i = 0; i < cand_count; ++i) {
                auto node = cand_set[i];
                if (i < nn_end) {
                    v += memory.default_pheromone() * heuristic[node];
                } else {
                    v += memory.get(curr, node) * heuristic[node];
                }
                if (r <= v) {
                    next_node = node;
                    break ;
                }
            }
        }
    } else { 
        double max_product = 0.0;
        auto &trails = memory.get_trails(curr);
        for (uint32_t i = 0; i < trails.size(); ++i) {
            auto &e = trails[i];
            auto node = e.first;
            if ( !ant.is_visited_[node] ) {
                const double product = e.second * heuristic[node];
                if (product > max_product) {
                    max_product = product;
                    next_node = node;
                }
            }
        }
        if (next_node == ant.nodes_count_+1) {
        for (uint32_t node = 0; node < ant.nodes_count_; ++node) {
            if (!ant.is_visited_[node]) {
                const double product = memory.default_pheromone() * heuristic[node];
                if (product > max_product) {
                    max_product = product;
                    next_node = node;
                }
            }
        }
        }
    }
    assert(next_node != ant.nodes_count_ + 1);
    return next_node;
}
uint32_t acs_calc_move ( Ant & ant , const vector < vector < double > > & heuristic_matrix , const vector < vector < double > > & , const vector < vector < uint32_t > > & nn_lists , double q0 , mt19937 & rng , SelectivePheromoneMemory * pheromone_memory ) { auto & memory = * pheromone_memory ; uint32_t next_node = ant . nodes_count_ + 1 ; const uint32_t curr = ant . visited_ . back ( ) ; static uint32_t cand_set [ 64 ] ; assert ( heuristic_matrix . size ( ) > curr ) ; auto & heuristic = heuristic_matrix . at ( curr ) ; uint32_t cand_count = 0 ; auto & nn = nn_lists [ curr ] ; for ( auto node : nn ) { if ( ! ant . is_visited_ [ node ] ) { cand_set [ cand_count ++ ] = node ; break ; } } if ( cand_count ) { uniform_real_distribution < > random_double ( 0.0 , 1.0 ) ; double q = random_double ( rng ) ; if ( q < q0 ) { double max_product = 0 ; auto & trails = memory . get_trails ( curr ) ; for ( uint32_t i = 0 ; i < trails . size ( ) ; ++ i ) { auto & e = trails [ i ] ; auto node = e . first ; if ( ! ant . is_visited_ [ node ] ) { const double product = e . second * heuristic [ node ] ; if ( product > max_product ) { max_product = product ; next_node = node ; } } } auto node = cand_set [ 0 ] ; const double product = memory . default_pheromone ( ) * heuristic [ node ] ; if ( product > max_product ) { next_node = node ; } } else { cand_count = 0 ; double sum = 0.0 ; for ( auto node : nn ) { if ( ! ant . is_visited_ [ node ] ) { cand_set [ cand_count ++ ] = node ; const double product = memory . default_pheromone ( ) * heuristic [ node ] ; sum += product ; } } const uint32_t nn_end = cand_count ; auto & trails = memory . get_trails ( curr ) ; for ( uint32_t i = 0 ; i < trails . size ( ) ; ++ i ) { auto & e = trails [ i ] ; auto node = e . first ; if ( ! ant . is_visited_ [ node ] ) { cand_set [ cand_count ++ ] = node ; const double product = e . second * heuristic [ node ] ; sum += product ; } } next_node = cand_set [ 0 ] ; const double r = random_double ( rng ) * sum ; double v = 0.0 ; for ( uint32_t i = 0 ; i < cand_count ; ++ i ) { auto node = cand_set [ i ] ; if ( i < nn_end ) { v += memory . default_pheromone ( ) * heuristic [ node ] ; } else { v += memory . get ( curr , node ) * heuristic [ node ] ; } if ( r <= v ) { next_node = node ; break ; } } } } else { double max_product = 0.0 ; auto & trails = memory . get_trails ( curr ) ; for ( uint32_t i = 0 ; i < trails . size ( ) ; ++ i ) { auto & e = trails [ i ] ; auto node = e . first ; if ( ! ant . is_visited_ [ node ] ) { const double product = e . second * heuristic [ node ] ; if ( product > max_product ) { max_product = product ; next_node = node ; } } } if ( next_node == ant . nodes_count_ + 1 ) { for ( uint32_t node = 0 ; node < ant . nodes_count_ ; ++ node ) { if ( ! ant . is_visited_ [ node ] ) { const double product = memory . default_pheromone ( ) * heuristic [ node ] ; if ( product > max_product ) { max_product = product ; next_node = node ; } } } } } assert ( next_node != ant . nodes_count_ + 1 ) ; return next_node ; }
Calculates the next node the given ant should move to from its current
 position.
Calculates the next node the given ant should move to from its current position .
/*total_matrix*/ // Greedy move // Select using proportional rule // Select best next node among all the unvisited nodes