Advertisement
AbraaoAllysson

grasp p-median non random

May 31st, 2017
76
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 9.97 KB | None | 0 0
  1. #include <iostream>
  2. #include <vector>
  3. #include <time.h>
  4. #include <utility>
  5. #include <stdlib.h>
  6. #include <list>
  7. #include <string.h>
  8. #include <map>
  9. #include <limits.h>
  10.  
  11.  
  12. #define LIMIT_CONSTRUCTION_VALUE 2100 //limite que poda a matriz de adjacencia
  13. #define LIMIT_NEIGHBORHOOD_FAILURE 5 // limite de falhas na melhoria externa da movimentação de vizinhança
  14. #define INITIAL_MATRIX_CEIL_VALUE 999999 //valores randomicos da matriz vão ser gerados de 1 até este valor
  15. #define GRASP_MAX_ITER 50 // numero de iterações do grasp
  16. #define GRASP_ALPHA_VALUE 0.5 //porcentagem de aleatoriedade do grasp
  17.  
  18. using namespace std;
  19.  
  20. typedef vector<vector<int> > vv;
  21. typedef vector<list<pair<int, int> > > vlp; // <node, cost>
  22.  
  23. //Auxiliar functions:
  24. void print_matrix(vv);
  25. void print_list(vlp);
  26. void print_global_solution(pair<int, vector<int> >);
  27. void print_vec(vector<int> vec);
  28. bool not_in(int, vector<int>);
  29.  
  30. //algorithm functions:
  31. void fill_matrix(vv &adj, int size){ // preenche a matrix com valores aleatórios, grafo completo e undirected
  32.  
  33.     srand(time(NULL));
  34.     vector<int> aux(size);
  35.     adj.reserve(size);
  36.  
  37.     for (int i = 0; i<size; i++) {
  38.  
  39.         for (int j = i; j<size; j++)
  40.             if (i == j)
  41.                 aux[j] = 0;
  42.             else
  43.                 aux[j] = rand() % INITIAL_MATRIX_CEIL_VALUE + 1; // valores entre 1 e 50
  44.  
  45.         adj.push_back(aux);
  46.     }
  47.  
  48.     for (int i = 0; i < size; i++) {  //espelha o triangulo superior (grafo undirected)
  49.         for (int j = 0; j < size; j++) {
  50.             adj[j][i] = adj[i][j];
  51.         }
  52.     }
  53. }
  54.  
  55. std::vector< std::vector<int> > readInput()
  56. {
  57.     int route = 0,
  58.         numberInput = 0;
  59.  
  60.     std::cin >> route;
  61.  
  62.     std::vector< std::vector<int> > mDistance;
  63.  
  64.   for (int i = 0; i < route; i++)
  65.   {
  66.       std::vector<int> vTemp;
  67.       for (int j = 0; j < route; j++)
  68.       {
  69.            std::cin >>  numberInput;
  70.            vTemp.push_back ( numberInput );
  71.       }
  72.       mDistance.push_back( vTemp );
  73.   }
  74.  
  75.  std::cout << "\n \t *************** \n" << std::endl;
  76.   // Print out the elements
  77.    for(unsigned int i = 0; i< mDistance.size(); i++)
  78.    {
  79.       for (unsigned int j = 0; j < mDistance[i].size(); j++)
  80.           std::cout << "\t" <<  mDistance[i][j] << " ";
  81.  
  82.       std::cout << std::endl;
  83.    }
  84.  
  85.    return mDistance;
  86.  
  87. }
  88.  
  89. vlp construction(vv &adj, int limit){ // converte a matriz numa lista, setando valores de distancia acima do parametro como intratáveis
  90.     int size = adj.size();
  91.     vlp adj_list(size);
  92.  
  93.     for(int i=0; i<size; i++)
  94.         for(int j=0; j<size; j++)
  95.             if(i!=j)
  96.                 if(adj[i][j] <= limit)
  97.                     adj_list[i].push_back(make_pair(j, adj[i][j]));
  98.  
  99.  
  100.     return adj_list;
  101. }
  102.  
  103. vector<int> grasp_solution(vlp adj, int P, float alpha){
  104.  
  105.     multimap<float, int> medias;
  106.     vector<int> random_set;
  107.     vector<int> solution;
  108.     float media, alpha_part;
  109.     int size_list = adj.size(), total_part, random, cont=0, random_set_size;
  110.  
  111.     print_list(adj);
  112.  
  113.     for(int i=0; i<size_list; i++){
  114.         media = 0;
  115.         for(list<pair<int, int> >::iterator it = adj[i].begin(); it!=adj[i].end(); it++){
  116.             media += it->second;
  117.         }
  118.         media /= adj[i].size();
  119.         medias.insert(make_pair(media, i));
  120.     }
  121.  
  122.     cout << "Medias ordenadas (media, nó): " << endl;
  123.     for(multimap<float, int>::iterator it = medias.begin(); it!=medias.end(); it++){
  124.         cout << "( " << it->first << " , " << it->second << " )" << endl;
  125.     }
  126.  
  127.     alpha_part = P * alpha;
  128.     total_part = P + alpha_part;
  129.     cout << "P: " << P << endl;
  130.     cout << "alpha part: " << alpha_part << endl;
  131.     cout << "total part: " << total_part << endl;
  132.  
  133.     for(int i=0; i<P; i++){
  134.         random_set_size = random_set.size();
  135.         do{
  136.             random = rand() % (total_part+1);
  137.             if(not_in(random, random_set)){
  138.                 cout << "random: " << random << endl;
  139.                 random_set.push_back(random);
  140.             }
  141.         }while(random_set_size==random_set.size());
  142.     }
  143.  
  144.     multimap<float, int>::iterator map_iter = medias.begin();
  145.  
  146.     for(int i=0; i<P; i++){
  147.         map_iter = medias.begin();
  148.         for(int j=0; j<random_set[i]; j++)
  149.             map_iter++;
  150.         solution.push_back(map_iter->second);
  151.     }
  152.  
  153.     cout << "solucao:" << endl;
  154.     print_vec(solution);
  155.  
  156.     return solution;
  157. }
  158.  
  159. // soma local com LISTA
  160. int local_sum(vlp adj, vector<int> solution){
  161.     int size_list = adj.size(), size_sol = solution.size(), min, sum=0;
  162.     bool pass;
  163.  
  164.     for(int i=0; i<size_list; i++){
  165.  
  166.         min = INT_MAX;
  167.         pass = true;
  168.         for(int g=0; g<size_sol; g++)
  169.             if(i==solution[g])
  170.                 pass = false;
  171.  
  172.         if(pass){
  173.             for(list<pair<int, int> >::iterator it = adj[i].begin(); it != adj[i].end(); it++)
  174.                 for(int g=0; g<size_sol; g++)
  175.                     if(it->first == solution[g])
  176.                         if(it->second < min)
  177.                             min = it->second;
  178.  
  179.  
  180.             if(min != INT_MAX){
  181.                 sum += min; // soma os mínimos para cada nó
  182.             }
  183.         }
  184.     }
  185.     return sum; // retorna a soma
  186. }
  187.  
  188. vector<int> random_permutation(vlp adj_list, vector<int> partial_solution){
  189.  
  190.     int adj_size = adj_list.size(), partial_size = partial_solution.size(), random[2];
  191.  
  192.     random[0] = rand() % partial_size;
  193.  
  194.     do{
  195.         random[1] = rand() % adj_size;
  196.     }while(!not_in(random[1], partial_solution));
  197.  
  198.     partial_solution[random[0]] = random[1];
  199.  
  200.     return partial_solution;
  201. }
  202.  
  203. pair<int, vector<int> > neighborhood_moviments(vlp adj_list, vector<int> initial_solution){ // essa função vai fazer as permutações e calcular as somas
  204.  
  205.     int best_local_sum = INT_MAX, init_size = initial_solution.size(), partial_sum, not_improve = 0;
  206.     vector<int> best_local_solution, partial_solution = initial_solution;
  207.     bool improve=true;
  208.  
  209.     best_local_sum = local_sum(adj_list, partial_solution); // solução inicial
  210.     best_local_solution = partial_solution;
  211.     cout << "initial sum: " << best_local_sum << endl;
  212.     cout << "initial solution: ";
  213.     print_vec(best_local_solution);
  214.     cout << endl;
  215.  
  216.     while(improve){
  217.  
  218.         initial_solution = partial_solution;
  219.  
  220.         if(not_improve>=LIMIT_NEIGHBORHOOD_FAILURE){
  221.             cout << "not_improve >= " << LIMIT_NEIGHBORHOOD_FAILURE << "... interrompendo movimentação" << endl;
  222.             break;
  223.         }
  224.  
  225.         improve = false;
  226.  
  227.         for(int i=0; i<init_size; i++){
  228.             for(list<pair<int, int> >::iterator it = adj_list[initial_solution[i]].begin(); it != adj_list[initial_solution[i]].end(); it++){
  229.  
  230.  
  231.                 if(not_in(it->first, partial_solution)){
  232.                     cout << "antes da troca: ";
  233.                     print_vec(partial_solution);
  234.                     partial_solution[i] = it->first;
  235.                 }else
  236.                     continue;
  237.                 cout << "depois da troca: ";
  238.                 print_vec(partial_solution);
  239.                 cout << "soma pos troca: ";
  240.                 partial_sum = local_sum(adj_list, partial_solution);
  241.                 cout << partial_sum;
  242.                 cout << endl;
  243.  
  244.                 if(partial_sum<best_local_sum){
  245.                     cout << "essa solução foi a melhor até agora" << endl;
  246.                     best_local_sum = partial_sum;
  247.                     best_local_solution = partial_solution;
  248.                     improve = true;
  249.                 }
  250.  
  251.             }
  252.  
  253.             partial_solution[i] = initial_solution[i];
  254.         }
  255.  
  256.         cout << "antes da permutação randomica:";
  257.         print_vec(partial_solution);
  258.         partial_solution = random_permutation(adj_list, partial_solution);
  259.         cout << "depois da permutação randomica: ";
  260.         print_vec(partial_solution);
  261.  
  262.         if(!improve){
  263.             not_improve++;
  264.             cout << "não melhorou... not_improve: " << not_improve << endl;
  265.             improve = true;
  266.         }
  267.  
  268.     }
  269.  
  270.     return make_pair(best_local_sum, best_local_solution);
  271. }
  272.  
  273. int main()
  274. {
  275.     vv adj_matrix = readInput();
  276.     vlp adj_list, original_list, heuristic_list;
  277.     int P, V;
  278.     vector<int> initial_solution;
  279.     pair<int, vector<int> > global_solution, local_solution;
  280.     global_solution.first = INT_MAX;
  281.  
  282.     /*cout << "Defina tamanho do grafo ( V ):";
  283.     cin >> V;*/
  284.  
  285.     //fill_matrix(adj_matrix, V);
  286.     original_list = construction(adj_matrix, INITIAL_MATRIX_CEIL_VALUE);
  287.     heuristic_list = construction(adj_matrix, LIMIT_CONSTRUCTION_VALUE);
  288.  
  289.     do{
  290.         cout << "defina P ( P < V and P > 0):";
  291.         cin >> P;
  292.     }while(P>=V && P<=0);
  293.  
  294.     for(int i=0; i<GRASP_MAX_ITER; i++){
  295.         //formando clusters (heuristica de construção utilizando um parâmetro que define oque é perto e o que é longe)
  296.         adj_list = heuristic_list; // (matrix, limit_value)
  297.  
  298.         //seleção gulosa de medianas
  299.         initial_solution = grasp_solution(adj_list, P, GRASP_ALPHA_VALUE);
  300.  
  301.         //essa linha retorna a lista pra o estado original da matrix
  302.         adj_list = original_list;
  303.  
  304.         //busca local (retorna a soma das distanticas dos clientes a sua facilidade mais próxima para uma dada seleção de medianas), insere o par <soma, solução> no multimap de soluções locais
  305.         local_solution = neighborhood_moviments(adj_list, initial_solution);
  306.  
  307.         //fica só com a melhor
  308.         global_solution = local_solution.first<global_solution.first?local_solution:global_solution;
  309.     }
  310.     print_global_solution(global_solution);
  311.  
  312.     return 0;
  313. }
  314.  
  315.  
  316. //implementação de funções auxiliares
  317. void print_matrix(vv adj) {
  318.  
  319.     int size = adj.size();
  320.     cout << "Matrix:" << endl;
  321.  
  322.     for (int i = 0; i<size; i++) {
  323.         for (int j = 0; j<size; j++)
  324.             cout << adj[i][j] << " ";
  325.  
  326.         cout << endl;
  327.     }
  328. }
  329.  
  330. void print_list(vlp adj_list){
  331.  
  332.     int len = adj_list.size();
  333.     typename list<pair<int, int> >::iterator it;
  334.  
  335.     cout << "List(node, cost):" << endl;
  336.  
  337.     for(int i=0; i<len; i++){
  338.  
  339.         cout << "[" << i << "] -> ";
  340.  
  341.         for(it=adj_list[i].begin(); it!=adj_list[i].end(); it++)
  342.                 cout << "(" << it->first << " , " << it->second << ") -> ";
  343.  
  344.         cout << endl;
  345.     }
  346. }
  347.  
  348. void print_global_solution(pair<int, vector<int> > result){
  349.  
  350.     int size = result.second.size();
  351.     cout << "Melhor resultado da heuristica: " << endl;
  352.     cout << "( " << result.first << " , [,";
  353.     for(int i=0; i<size; i++)
  354.         cout << result.second[i] << ",";
  355.     cout << "] )" << endl;
  356. }
  357.  
  358. void print_vec(vector<int> vec){
  359.     int size = vec.size();
  360.  
  361.     for(int i=0; i<size; i++)
  362.         cout << vec[i] << ",";
  363.     cout << endl;
  364. }
  365.  
  366. bool not_in(int test, vector<int> vec){
  367.     int size = vec.size();
  368.     for(int i=0; i<size; i++)
  369.         if(test==vec[i])
  370.             return false;
  371.     return true;
  372. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement