Advertisement
OvidiuF

Colonii de furnici v2

May 10th, 2018
77
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 7.47 KB | None | 0 0
  1. //Optimizarea cu colonii de furnici
  2. #pragma warning (disable:4996)
  3. #include <stdio.h>
  4. #include <conio.h>
  5. #include <math.h>
  6. #include <time.h>
  7. #include <stdlib.h>
  8.  
  9. // Am declarat aici variabilele constante care sunt prestabilite inaintea programului
  10. #define alfa 1
  11. #define beta 1
  12. #define grad_eva 0.01
  13. #define nr_furnici 100
  14.  
  15. double functie_euristica(int oras1, int oras2, int m[20][20]) {
  16. // functia returneaza nij unde nij = 1 / (d(i, j)/10).
  17. return double(1 / (double(m[oras1][oras2]/10)));
  18. }
  19.  
  20. int algoritm_ruleta(double q[20]) {
  21. //Se genereaza un numar random intre 0 si 1 si se alegere orasul
  22. double r = double(rand() % 100);
  23. r = r / 100;
  24.  
  25. int i = 0;
  26. while (q[i] < r)
  27. i++;
  28. i++;
  29. return i;
  30. }
  31.  
  32. void initializare_tau(double tau[20][20]) {
  33. for (int i = 0; i < 20; i++)
  34. for (int j = 0; j < 20; j++)
  35. tau[i][j] = 1;
  36. }
  37.  
  38. void initializare_a(double a[20][20]) {
  39. for (int i = 0; i < 20; i++)
  40. for (int j = 0; j < 20; j++)
  41. a[i][j] = 0;
  42. }
  43.  
  44. void colonii_de_furnici(int plecare, int sosire, int m[20][20], char *oras[]) {
  45. //Majoritatea variabilelor au nume sugestive
  46. //nr_noduri[nr_furnici] memoreaza numarul de orase parcurse de cele nr_furnici la fiecare iteratie
  47. int nod, lista_tabu[nr_furnici][20], nr_noduri[nr_furnici], nr_q, iteratia = 0, noduri[20], nr_nod, Vizitate[20], Parinte[20], vector_solutie[20], nr_vector_solutie = 21;
  48. double a[20][20], q[20], tau[20][20];
  49.  
  50. // Initial nivelul de feromon, tau[i][j], este 1 pentru orice drum
  51. initializare_tau(tau);
  52.  
  53. //Se poate modifica 10-le daca dorim sa ruleze pentru mai multe iteratii
  54. while (iteratia != 10) {
  55. //La inceput nu exista niciun oras parcurs
  56. for (int i = 0; i < nr_furnici; i++)
  57. nr_noduri[i] = 0;
  58.  
  59. //Pentru fiecare furnica
  60. for (int i = 0; i < nr_furnici; i++) {
  61. // La inceput nu avem niciun nod in noduri[20] deci nr_nod=0 si niciun oras nu e vizitat
  62. nr_nod = 0;
  63. for (int i = 0; i < 20; i++)
  64. Vizitate[i] = 0;
  65. Vizitate[plecare] = 1;
  66. nod = plecare;
  67.  
  68. //Cat timp stare_curenta!=stare_tinta (nod!=sosire)
  69. while (nod != sosire) {
  70. //Se initializeaza a-ul cu 0
  71. initializare_a(a);
  72.  
  73. // nr - numarul de vecini ai orasului nod
  74. // suma_a este numitorul lui a
  75. int nr = 0;
  76. double suma_a = 0;
  77.  
  78. //Se calculeaza numitorul lui a[nod][j] dupa formula si se salveaza in suma_a si in acelas timp se adauga in fiecare a[nod][j] numaratorul
  79. for (int j = 0; j < 20; j++)
  80. if ((m[nod][j] != 0) && (Vizitate[j] == 0)) {
  81. nr++;
  82. suma_a = suma_a + pow(tau[nod][j], alfa)*pow(functie_euristica(nod, j, m), beta);
  83. a[nod][j] = pow(tau[nod][j], alfa)*pow(functie_euristica(nod, j, m), beta);
  84. }
  85. //Daca orasul are vecini, se imparte numaratorul (a[nod][j]) la numitorul calculat anterior (suma_a)
  86. //Se adauga in noduri toti vecini,se marcheaza ca vizitati si se salveaza parinti fiecarui vecin
  87. for (int j = 0; j < 20; j++)
  88. if (a[nod][j] != 0) {
  89. a[nod][j] = a[nod][j] / suma_a;
  90. Vizitate[j] = 1;
  91. noduri[nr_nod++] = j;
  92. Parinte[j] = nod;
  93. }
  94.  
  95. // Se afla q-ul pentru fiecare a
  96. nr_q = 0;
  97. while (nr_q != nr) {
  98. int gasit = 0;
  99.  
  100. q[nr_q] = 0;
  101. for (int j = 0; j < 20; j++)
  102. if ((a[nod][j] != 0) && (nr_q + 1 != gasit)) {
  103. gasit++;
  104. q[nr_q] = q[nr_q] + a[nod][j];
  105. }
  106. nr_q++;
  107. }
  108.  
  109. //selectat va reprezenta orasul selectat dupa ce s-a generat un numar random iar alegere_oras va memora acel oras selectat
  110. int selectat = algoritm_ruleta(q), alegere_oras = 0;
  111.  
  112. for (int j = 0; j < 20; j++) {
  113. if (a[nod][j] != 0)
  114. alegere_oras++;
  115. if (alegere_oras == selectat) {
  116. alegere_oras = j;
  117. break;
  118. }
  119. }
  120. //Daca nr=0 inseamna ca nod nu are vecini deci s-a blocat si luam un nou nod, primul din noduri[0]
  121. //Stergem noduri[0] dupa ce il salvam in alegere_oras
  122. if (nr == 0) {
  123. alegere_oras = noduri[0];
  124. for (int k = 1; k < nr_nod; k++)
  125. noduri[k - 1] = noduri[k];
  126. }
  127. else {
  128. //Daca nr nu e 0 atunci stergem nodul alegere_oras din noduri[20]
  129. int poz;
  130. for (int k = 0; k < nr_nod; k++)
  131. if (alegere_oras == noduri[k]) {
  132. poz = k;
  133. break;
  134. }
  135. for (int k = poz; k < nr_nod - 1; k++)
  136. noduri[k] = noduri[k + 1];
  137. }
  138. nr_nod--;
  139. //Adaugam in nod orasul ales
  140. nod = alegere_oras;
  141. }
  142. // Dupa ce am gasit o solutie o punem in lista_tabu in mod invers
  143. int solutie[20], n = 0;
  144. int sol = sosire;
  145.  
  146. while (sol != plecare) {
  147. solutie[n++] = sol;
  148. sol = Parinte[sol];
  149. }
  150. solutie[n++] = plecare;
  151. for (int k = n - 1; k >= 0; k--)
  152. lista_tabu[i][nr_noduri[i]++] = solutie[k];
  153.  
  154. //Daca cumva solutia costul drumului unei furnici(n) este mai mic decat costul drumului vector_solutie (nr_vector_solutie) atunci salvam drumul mai bun
  155. if (n < nr_vector_solutie) {
  156. nr_vector_solutie = 0;
  157. for (int k = n - 1; k >= 0; k--)
  158. vector_solutie[nr_vector_solutie++] = solutie[k];
  159. }
  160. //Depunerea feromonului pe arce
  161. double cost_tabu;
  162.  
  163. for (int i = 0; i < nr_furnici; i++) {
  164. cost_tabu = 0;
  165. for (int j = 0; j < nr_noduri[i] - 1; j++)
  166. cost_tabu = cost_tabu + (m[lista_tabu[i][j]][lista_tabu[i][j + 1]] / 10);
  167. for (int j = 0; j < nr_noduri[i] - 1; j++)
  168. tau[lista_tabu[i][j]][lista_tabu[i][j + 1]] += 1 / cost_tabu;
  169. }
  170.  
  171. }
  172. //Evaporarea feromonului
  173. for (int i = 0; i < 20; i++)
  174. for (int j = 0; j < 20; j++)
  175. tau[i][j] = (1 - grad_eva)*tau[i][j];
  176. iteratia++;
  177. }
  178. // Afisarea cel mai bun drum parcurs dintre cele x furnici in cele x iteratii
  179. printf("\nDrumul parcurs de ultima furnica este: ");
  180. for (int i = 0; i < nr_vector_solutie; i++)
  181. printf("%s ", oras[vector_solutie[i]]);
  182. }
  183.  
  184. void main() {
  185.  
  186. char *oras[] = { "Alba Iulia","Arad","Baia Mare","Bistrita","Braila","Brasov","Bucuresti","Cluj Napoca",
  187. "Constanta","Craiova","Iasi","Oradea","Piatra Neamt","Pitesti","Satu Mare","Sibiu","Suceava","Targu Mures",
  188. "Timisoara","Tulcea" };
  189. int m[20][20], plecare, sosire;
  190.  
  191. time_t t;
  192. srand((unsigned)(time(&t)));
  193. // In matrice am pus -0 daca nu exista drum intre cele 2 orase si nr de km - daca exista drum
  194.  
  195. for (int i = 0; i < 20; i++)
  196. for (int j = 0; j < 20; j++)
  197. m[i][j] = 0;
  198. m[10][12] = m[12][10] = 129;
  199. m[5][15] = m[15][5] = 141;
  200. m[5][12] = m[12][5] = 238;
  201. m[0][18] = m[18][0] = 217;
  202. m[11][7] = m[7][11] = 159;
  203. m[14][2] = m[2][14] = 62;
  204. m[2][7] = m[7][2] = 148;
  205. m[14][11] = m[11][14] = 139;
  206. m[11][1] = m[1][11] = 114;
  207. m[7][1] = m[1][7] = 268;
  208. m[1][18] = m[18][1] = 58;
  209. m[18][9] = m[9][18] = 341;
  210. m[9][13] = m[13][9] = 121;
  211. m[9][0] = m[0][9] = 295;
  212. m[0][7] = m[7][0] = 98;
  213. m[7][3] = m[3][7] = 108;
  214. m[7][17] = m[17][7] = 111;
  215. m[0][15] = m[15][0] = 74;
  216. m[15][17] = m[17][15] = 114;
  217. m[17][3] = m[3][17] = 93;
  218. m[3][16] = m[16][3] = 195;
  219. m[16][10] = m[10][16] = 147;
  220. m[5][13] = m[13][5] = 137;
  221. m[13][6] = m[6][13] = 118;
  222. m[6][8] = m[8][6] = 227;
  223. m[6][12] = m[12][6] = 352;
  224. m[6][4] = m[4][6] = 218;
  225. m[4][12] = m[12][4] = 255;
  226. m[4][19] = m[19][4] = 95;
  227. m[19][8] = m[8][19] = 138;
  228. m[17][5] = m[5][17] = 169;
  229. m[5][6] = m[6][5] = 170;
  230. printf("Alegeti orasul de plecare si de sosire.\n");
  231. for (int i = 0; i < 20; i++)
  232. printf("%d.%s\n", i, oras[i]);
  233. printf("Introduce numarul orasului de plecare:");
  234. scanf("%d", &plecare);
  235. printf("Introduce numarul orasului de sosire:");
  236. scanf("%d", &sosire);
  237.  
  238. colonii_de_furnici(plecare, sosire, m, oras);
  239. _getch();
  240. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement