Advertisement
sir_timyp

8

Mar 12th, 2019
32
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 6.99 KB | None | 0 0
  1. // Salesman.cpp : Defines the entry point for the console application.
  2. //
  3.  
  4. #include "pch.h"
  5. #include "stdio.h"
  6. #include "Windows.h"
  7. #include "time.h"
  8. #include "math.h"
  9.  
  10. int M[6][6] =
  11. {
  12.     {-1, 1, 4, 5, -1, -1},
  13.     {1, -1, -1, 2, -1, 6},
  14.     {4, -1, -1, -1, 2, -1},
  15.     {5, 2, -1, -1, -1, 3},
  16.     {-1, -1, 2, -1, -1, 2},
  17.     {-1, 6, -1, 3, 2, -1}
  18. };
  19.  
  20. /*
  21. int M[5][5] =
  22. {
  23.     {-1, 20, 18, 12, 8},
  24.     {5, -1, 14, 7, 11},
  25.     {12, 18, -1, 6, 11},
  26.     {11, 17, 11, -1, 12},
  27.     {5, 5, 5, 5, -1},
  28. };
  29. */
  30. const float k = 0.8; //скорость испарения
  31. const int n = 8;//количество ребер
  32. const int m = 6;//количество вершин
  33. const int numAnts = 5000;
  34.  
  35. struct Rib
  36. {
  37.     int num[2];
  38.     int weight;
  39.     float pheromoune;
  40.     float chance;
  41. };
  42.  
  43. struct Ant
  44. {
  45.     int isAlive;
  46.     int currentPeak;
  47.     int tabuList[m+1];
  48. };
  49.  
  50. //Находится ли вершина peak в табу-листе
  51. int HasInTabu(int peak, Ant *ant)
  52. {
  53.     for (int i = 0; i < m+1; i++)
  54.     {
  55.         if (ant->tabuList[i] == peak) return 1;
  56.     }
  57.     return 0;
  58. }
  59.  
  60. //Проверяет, может ли данный муравей пройти куда нибудь
  61. int CanAntMove(Ant *ant)
  62. {
  63.     for (int i = 0; i < m; i++)
  64.     {
  65.         if ((M[ant->currentPeak][i] > 0) && !HasInTabu(i, ant)) return 1;
  66.     }
  67.  
  68.     return 0;
  69. }
  70.  
  71.  
  72. float UpdatePheromoune(const float k, Rib *currentRib)
  73. {
  74.     return (1.0f - k)*currentRib->pheromoune + (1.0f / currentRib->weight);
  75.    
  76. }
  77.  
  78. float CalcChance(Rib *rib, Rib *edgesOfI, int countEdges)
  79. {
  80.     float sum = 0;
  81.     for (int i = 0; i < countEdges; i++)
  82.     {
  83.         sum += edgesOfI[i].pheromoune + 1.0f / edgesOfI[i].weight;
  84.     }
  85.     rib->chance = (rib->pheromoune + 1.0f / rib->weight) / sum;
  86.     return rib->chance * 100;
  87. }
  88.  
  89. //Возвращает ребро из списка по номерам вершин
  90. Rib* GetRib(int firstPeak, int secondPeak, Rib *ribs, int count)
  91. {
  92.     for (int i = 0; i < count; i++)
  93.     {
  94.         if(((ribs[i].num[0] == firstPeak) && (ribs[i].num[1] == secondPeak) ||
  95.             ((ribs[i].num[0] == secondPeak) && (ribs[i].num[1] == firstPeak))))
  96.             return &ribs[i];
  97.     }
  98.     return NULL;
  99. }
  100.  
  101.  
  102. //создаем ребра по матрице
  103. int RibsAuto(Rib ribs[n], int weights[][m])
  104. {
  105.     int count = 0;
  106.     for (int i = 0; i < m; i++)
  107.     {
  108.         if (count == n) break;
  109.  
  110.         for (int j = 0 + i; j < m; j++)
  111.         {
  112.             if (weights[i][j] > 0)
  113.             {
  114.                 ribs[count].num[0] = i;
  115.                 ribs[count].num[1] = j;
  116.                 ribs[count].pheromoune = 0;
  117.                 ribs[count].chance = 0;
  118.                 ribs[count].weight = weights[i][j];
  119.                 count++;
  120.                
  121.             }
  122.         }
  123.     }
  124.     return count;
  125. }
  126.  
  127. int CalcLength(int *list, Rib *ribs, Ant *ant)
  128. {
  129.     int length = 0;
  130.  
  131.     for (int i = 0; i < m; i++)
  132.     {
  133.         if(list[i+1] > -1)
  134.             length += GetRib(list[i], list[i + 1], ribs, n)->weight;
  135.     }
  136.     return length;
  137. }
  138.  
  139.  
  140. //решает, что будет делать муравей
  141. int AntSolute(Ant *ant, Rib *ribs)    
  142. {
  143.     //проверяем можно ли нам куда идти с помощью табу, или не достигнем начала;
  144.     //ИЛИ ВЫЧИСЛЯЕМ ВЕРОЯТНОСТЬ ПОСЛЕ ИССЛЕДОВАНИЯ!!!
  145.  
  146.     if (!CanAntMove(ant))
  147.     {
  148.         ant->isAlive = 0;//убиваем муравья
  149.        
  150.         //обновить феромоны на всем пути
  151.  
  152.         for (int i = 0; i < m+1; i++)
  153.         {
  154.             if (ant->tabuList[i] == -1)
  155.             {
  156.                 ant->tabuList[i] = ant->currentPeak;
  157.                 break;
  158.             }
  159.         }
  160.         for (int i = 0; i < m + 1; i++)
  161.         {
  162.             if (ant->tabuList[i] == -1)
  163.             {
  164.                 if (GetRib(ant->currentPeak, ant->tabuList[0], ribs, n))
  165.                 {
  166.                     ant->tabuList[i] = ant->tabuList[0];
  167.                     break;
  168.                 }
  169.                 return 0;
  170.             }
  171.         }
  172.        
  173.         int length = CalcLength(ant->tabuList, ribs, ant);
  174.  
  175.         for (int i = 0; i < m; i++)
  176.         {
  177.             if (ant->tabuList[i + 1] > -1)
  178.             {
  179.                 Rib *temp = GetRib(ant->tabuList[i], ant->tabuList[i + 1], ribs, n);
  180.                 temp->pheromoune = UpdatePheromoune(k, temp);
  181.             }
  182.         }
  183.         for (int i = 0; i < m+1; i++)
  184.             if (ant->tabuList[i] > -1)printf("%d - ", ant->tabuList[i] + 1);
  185.         printf(" Length = %d\n", length);
  186.         memset(&ant->tabuList, -1, sizeof(ant->tabuList)); //обнуляем табу-лист
  187.         return 0;
  188.     }
  189.     else
  190.     {
  191.         int peaks[m-1];
  192.         int count = 0;
  193.  
  194.         for (int i = 0; i < m; i++)
  195.         {
  196.             if (M[ant->currentPeak][i] > 0 && !HasInTabu(i, ant))
  197.             {
  198.                 peaks[count] = i;
  199.                 count++;
  200.             }
  201.         }
  202.  
  203.         Rib edgesFromCity[m-1];
  204.         //заполняем массив ребер возможных из данного города
  205.         for (int i = 0; i < count; i++)
  206.             edgesFromCity[i] = *GetRib(ant->currentPeak, peaks[i], ribs, n);
  207.        
  208.         int nextPeak = 0;
  209.         int chances[n];
  210.         chances[0] = CalcChance(GetRib(ant->currentPeak, peaks[0], ribs, n), edgesFromCity, count);
  211.  
  212.         for (int i = 1; i < count-1; i++)
  213.             chances[i] = chances[i-1] + CalcChance(GetRib(ant->currentPeak, peaks[i], ribs, n), edgesFromCity, count);
  214.         chances[count - 1] = 100;
  215.         //сортировка массива
  216.         for (int i = 0; i < count - 1; i++)
  217.         {
  218.             for (int j = 0; j < count - i - 1; j++)
  219.             {
  220.                 if (chances[j] > chances[j+1])
  221.                 {
  222.                     int temp = chances[j];
  223.                     chances[j] = chances[j + 1];
  224.                     chances[j + 1] = temp;
  225.                 }
  226.             }
  227.         }
  228.  
  229.         int random = rand() % 100;
  230.  
  231.         for (int i = 0; i < count; i++)
  232.         {
  233.             if (random < chances[i])
  234.             {
  235.                 nextPeak = peaks[i];
  236.                 break;
  237.             }
  238.         }
  239.  
  240.         //заносим следующую вершину в табу-лист
  241.         for (int i = 0; i < m+1; i++)
  242.         {
  243.             if (ant->tabuList[i] == -1)
  244.             {
  245.                 ant->tabuList[i] = ant->currentPeak;
  246.                 break;
  247.             }
  248.         }
  249.         //переходим туда
  250.         ant->currentPeak = nextPeak;
  251.         return 1;
  252.     }
  253. }
  254.  
  255. //Проверяет, есть ли живые муравьи в массиве ants
  256. int HasAntAlive(Ant *ants, int quantityAnt)
  257. {
  258.     for (int i = 0; i < quantityAnt; i++)
  259.         if (ants[i].isAlive) return 1;
  260.    
  261.     return 0;
  262. }
  263.  
  264. int main()
  265. {
  266.    
  267.  
  268.     Rib ribs[n];
  269.     RibsAuto(ribs, M);
  270.  
  271.     //delete &agents[1];
  272.  
  273.     srand(time(NULL));
  274.     /*
  275.     //оживляем муравьев
  276.     for (int i = 0; i < 6; i++)
  277.     {
  278.         agents[i].isAlive = 1;
  279.         agents[i].currentPeak = 0;
  280.         memset(&agents[i].tabuList, -1, sizeof(agents[i].tabuList));
  281.     }
  282.  
  283.     //исследование
  284.     while (HasAntAlive(agents, 6))
  285.     {
  286.         //выбираем муравьев и решаем куда им идти
  287.         for (int i = 0; i < 6; i++)
  288.         {
  289.             if (agents[i].isAlive == 1)
  290.                 AntSolute(&agents[i], ribs);
  291.         }
  292.         //обновляем феромоны?
  293.         for (int i = 0; i < n; i++)
  294.             if (ribs[i].pheromoune > 0) UpdatePheromoune(k, &ribs[i]);
  295.  
  296.     }*/
  297.     Ant superAgents[numAnts];
  298.     for (int i = 0; i < numAnts; i++)
  299.     {
  300.         superAgents[i].isAlive = 1;
  301.         superAgents[i].currentPeak = 2;
  302.         memset(&superAgents[i].tabuList, -1, sizeof(superAgents[i].tabuList));
  303.     }
  304.  
  305.     //исследование
  306.     while (HasAntAlive(superAgents, numAnts))
  307.     {
  308.         //выбираем муравьев и решаем куда им идти
  309.         for (int i = 0; i < numAnts; i++)
  310.         {
  311.             if (superAgents[i].isAlive == 1)
  312.                 AntSolute(&superAgents[i], ribs);
  313.         }
  314.  
  315.     }
  316.     system("pause");
  317.  
  318.     return 0;
  319. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement