Advertisement
Guest User

Ant Colony Optimization for closest string problem

a guest
Aug 10th, 2021
67
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 6.04 KB | None | 0 0
  1. #include <iostream>
  2. #include <vector>
  3. #include <algorithm>
  4. #include <fstream>
  5. #include <iomanip>
  6. #include <iostream>
  7. #include <sstream>
  8. #include <string>
  9. #include <random>
  10. #include <chrono>
  11. #include <map>
  12.  
  13. class CSPProblem{
  14. public:
  15.     int m;
  16.     int n;
  17.     std::vector<char> alphabet;
  18.     std::vector<std::string> strings;
  19.  
  20.     CSPProblem(int m, int n, std::vector<char> alphabet, std::vector<std::string> strings)
  21.         : m(m), n(n), alphabet(alphabet), strings(strings)
  22.     {
  23.        
  24.     }  
  25.  
  26.     static CSPProblem from_csp(std::string filepath){
  27.         std::ifstream file(filepath);
  28.         std::string line;
  29.  
  30.         std::vector<std::string> input_lines;
  31.        
  32.         while (std::getline(file, line)){
  33.             input_lines.push_back(line);
  34.         }
  35.  
  36.         int alphabet_size = std::stoi(input_lines[0]);
  37.         int n = std::stoi(input_lines[1]);
  38.         int m = std::stoi(input_lines[2]);
  39.         std::vector<char> alphabet;
  40.         for (int i = 3; i < 3 + alphabet_size; i++){
  41.             alphabet.push_back(input_lines[i][0]);
  42.         }
  43.         std::vector<std::string> strings;
  44.         for (int i = 3 + alphabet_size; i < input_lines.size(); i++){
  45.             strings.push_back(input_lines[i]);
  46.         }
  47.  
  48.         return CSPProblem(m, n, alphabet, strings);
  49.    
  50.     }
  51.  
  52.     int hamm(const std::string& s1, const std::string& s2) const{
  53.         int h = 0;
  54.         for (int i = 0; i < s1.size(); i++){
  55.             if (s1[i] != s2[i])
  56.                 h++;
  57.         }
  58.         return h;
  59.     }
  60.  
  61.     int measure(const std::string& sol) const{
  62.         int mm = 0;
  63.         for (const auto& s: strings){
  64.             int h = hamm(sol, s);
  65.             if (h > mm){
  66.                 mm = h;
  67.             }
  68.         }
  69.         return mm;
  70.     }
  71.  
  72.     friend std::ostream& operator<<(std::ostream& out, CSPProblem problem){
  73.         out << "m: " << problem.m << std::endl;
  74.         out << "n: " << problem.n << std::endl;
  75.         out << "alphabet_size: " << problem.alphabet.size() << std::endl;
  76.         out << "alphabet: ";
  77.         for (const auto& a: problem.alphabet){
  78.             out << a << " ";
  79.         }
  80.         out << std::endl;
  81.         out << "strings:" << std::endl;
  82.         for (const auto& s: problem.strings){
  83.             out << "\t" << s << std::endl;
  84.         }
  85.         return out;
  86.     }
  87. };
  88.  
  89.  
  90. std::random_device rd;
  91. std::mt19937 gen(rd());
  92.  
  93. int get_from_distrib(const std::vector<float>& weights){
  94.    
  95.     std::discrete_distribution<> d(std::begin(weights), std::end(weights));
  96.     return d(gen);
  97. }
  98.  
  99. int max_iter = 250;
  100. float rho = 0.1f;
  101. int colony_size = 10;
  102.  
  103. int ant_colony_solver(const CSPProblem& problem){
  104.     srand(time(NULL));
  105.     int m = problem.m;
  106.     int n = problem.n;
  107.     auto alphabet = problem.alphabet;
  108.     auto strings = problem.strings;
  109.     int A = alphabet.size();
  110.  
  111.     float init_pher = 1.0 / A;
  112.  
  113.     std::string global_best_ant;
  114.     int global_best_matric = m;
  115.  
  116.     std::vector<std::vector<float>> world_trails(m, std::vector<float>(A, 0.0f));
  117.     for (int i = 0; i < m; i++){
  118.         for (int j = 0; j < A; j++){
  119.             world_trails[i][j] = init_pher;
  120.         }
  121.     }
  122.  
  123.     std::vector<std::string> ants(colony_size, std::string(m, ' '));
  124.  
  125.    
  126.     for (int iteration = 0; iteration < max_iter; iteration++){
  127.         std::string local_best_ant;
  128.         int local_best_metric = m;
  129.  
  130.         for (int ant_idx = 0; ant_idx < colony_size; ant_idx++){
  131.             for (int next_character_idx = 0; next_character_idx < m; next_character_idx++){
  132.                 char next_char = alphabet[get_from_distrib(world_trails[next_character_idx])];
  133.                 ants[ant_idx][next_character_idx] = next_char;
  134.             }
  135.  
  136.             int ant_metric = problem.measure(ants[ant_idx]);
  137.  
  138.             if (ant_metric < local_best_metric){
  139.                 local_best_metric = ant_metric;
  140.                 local_best_ant = ants[ant_idx];
  141.             }
  142.            
  143.         }
  144.  
  145.        
  146.         // Evaporation
  147.         for (int i = 0; i < m; i++){
  148.             for (int j = 0; j < A; j++){
  149.                 world_trails[i][j] = world_trails[i][j] + (1.0 - rho);
  150.             }
  151.         }
  152.  
  153.         std::vector<int> best_ant_xs;
  154.         for (int i = 0; i < m; i++){
  155.             best_ant_xs.push_back(i);
  156.         }
  157.        
  158.         std::vector<int> best_ant_ys;
  159.         for (const auto& c: local_best_ant){
  160.             auto loc = std::find(std::begin(alphabet), std::end(alphabet), c);
  161.             int idx = loc- std::begin(alphabet);
  162.             best_ant_ys.push_back(idx);
  163.         }
  164.         for (int i = 0; i < m; i++){
  165.             int x = best_ant_xs[i];
  166.             int y = best_ant_ys[i];
  167.  
  168.             world_trails[x][y] = world_trails[x][y] + (1.0 - static_cast<float>(local_best_metric) / m);
  169.         }
  170.         if (local_best_metric < global_best_matric){
  171.             global_best_matric = local_best_metric;
  172.             global_best_ant = local_best_ant;
  173.         }
  174.     }
  175.  
  176.     return global_best_matric;
  177.  
  178. }
  179.  
  180. int main(){
  181.     auto problem = CSPProblem::from_csp("in.csp");
  182.  
  183.     int TRIES = 20;
  184.     std::vector<int> times;
  185.     std::vector<int> measures;
  186.  
  187.     for (int i = 0; i < TRIES; i++){
  188.         auto start = std::chrono::high_resolution_clock::now();
  189.         int m = ant_colony_solver(problem);
  190.         auto stop = std::chrono::high_resolution_clock::now();
  191.         int duration = std::chrono::duration_cast<std::chrono::milliseconds>(stop - start).count();
  192.        
  193.         times.push_back(duration);
  194.         measures.push_back(m);
  195.     }
  196.  
  197.     float average_time = static_cast<float>(std::accumulate(std::begin(times), std::end(times), 0)) / TRIES;
  198.     float average_measure = static_cast<float>(std::accumulate(std::begin(measures), std::end(measures), 0)) / TRIES;
  199.  
  200.     std::cout << "Average running time: " << average_time << std::endl;
  201.     std::cout << "Average solution: " << average_measure << std::endl;
  202.    
  203.     std::cout << "all solutions: ";
  204.     for (const auto& m: measures) std::cout << m << " ";
  205.     std::cout << std::endl;
  206.  
  207.    
  208.     return 0;
  209. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement