PageRenderTime 26ms CodeModel.GetById 16ms RepoModel.GetById 0ms app.codeStats 0ms

/Habitats.hpp

https://gitlab.com/natural-computing-optimization/ecological-inspired-algorithm-cpp
C++ Header | 420 lines | 369 code | 38 blank | 13 comment | 80 complexity | 0fc29698fc62312f4b9523ca7aeb170d MD5 | raw file
  1. #ifndef HABITATS_H
  2. #define HABITATS_H
  3. #include <math.h>
  4. #include <fstream>
  5. #include "Configuration.hpp"
  6. #include "Aleatory.hpp"
  7. #include "Specie.hpp"
  8. #include "./src-clstr/cluster.h"
  9. #define MINVAL 0.01 //1% of chance to NOT link two populations. Gives 1% of chance to the closest populations not belong to the same habitat.
  10. #define MAXVAL 0.99 //1% of chance to link. This gives 1% of chance to the farest populations belong to the same habitat.
  11. struct habitat {
  12. int h_sp_count; //Contains how many species are in each habitat.
  13. int *h_sp; //This vector contains which species are in each habitat. h_sp[SP_NUMBER]
  14. } *H; //struct that contains the habitats H[SP_NUMBER]
  15. unsigned short int g_habitatsSize = 0;
  16. double ** g_distances;
  17. Node * g_tree;
  18. int * sp_int;
  19. int ** sp_adj;
  20. //=========================================================================================
  21. // Reserva memória para as variaveis
  22. //=========================================================================================
  23. void initHabitats(int size)
  24. {
  25. unsigned short int a = 0;
  26. g_distances = (double**) malloc(size*sizeof(double*));
  27. for(a = 0; a < size; a++)
  28. {
  29. g_distances[a] = (double*) malloc(size*sizeof(double));
  30. }
  31. H = (struct habitat*) malloc(size * sizeof(struct habitat));
  32. for (a = 0; a < size; a++)
  33. {
  34. H[a].h_sp = (int*)malloc (sizeof(int)*size );
  35. H[a].h_sp_count = 0;
  36. }
  37. sp_int = (int*) malloc (size * sizeof(int));
  38. sp_adj = (int**)malloc (size * sizeof(int*));
  39. for (a = 0; a < size; a++)
  40. {
  41. sp_adj[a] = (int*)malloc (size * sizeof(int));
  42. }
  43. }
  44. //=========================================================================================
  45. // Libera a memória
  46. //=========================================================================================
  47. void destroyHabitats(int size)
  48. {
  49. unsigned short int a = 0;
  50. for(a = 0; a < size; a++)
  51. {
  52. free(g_distances[a]);
  53. }
  54. free(g_distances);
  55. for (a = 0; a < size; a++)
  56. {
  57. free(H[a].h_sp);
  58. }
  59. free(H);
  60. free(sp_int);
  61. for (a = 0; a < size; a++)
  62. {
  63. free(sp_adj[a]);
  64. }
  65. free(sp_adj);
  66. }
  67. //=========================================================================================
  68. // Calcula a matriz de distância e normaliza os valores
  69. //=========================================================================================
  70. void buildDistanceMatrix(int size, int dimensions, Specie species[])
  71. {
  72. double euclid_max = 0;
  73. double euclid_sum = 0;
  74. double temp = 0;
  75. unsigned short int a = 0;
  76. unsigned short int b = 0;
  77. unsigned short int d = 0;
  78. Organism centroid[size];
  79. for(a = 0; a < size; a++)
  80. {
  81. centroid[a] = species[a].getCentroid();
  82. }
  83. for(a = 0; a < size; a++)
  84. {
  85. g_distances[a][a] = 0;
  86. for(b = a + 1 ; b < size; b++)
  87. {
  88. for(d = 0; d < dimensions; d++)
  89. {
  90. euclid_sum += pow(fabs(centroid[a][d] - centroid[b][d]),2.0);
  91. }
  92. g_distances[a][b] = sqrt(euclid_sum);
  93. g_distances[b][a] = g_distances[a][b];
  94. if (euclid_max < g_distances[a][b])
  95. {
  96. euclid_max = g_distances[a][b];
  97. }
  98. euclid_sum = 0.0;
  99. }
  100. }
  101. for(a = 0; a < size; a++)
  102. {
  103. for(int b = a +1; b < size; b++)
  104. {
  105. g_distances[a][b] = g_distances[a][b] / euclid_max;
  106. g_distances[b][a] = g_distances[a][b];
  107. }
  108. }
  109. }
  110. //=========================================================================================
  111. // Gerar o dendograma com o algoritmo singlelinkclustering
  112. //=========================================================================================
  113. void buildDendogram(int size, int dimensions)
  114. {
  115. double maxrange;
  116. double minrange;
  117. unsigned short int i = 0;
  118. g_tree = treecluster(size, size, 0, 0, 0, 0, 'e', 's', g_distances);
  119. if(!g_tree)
  120. {
  121. std::cout << " Erro ao gerar dendograma" << std::endl;
  122. return;
  123. }
  124. maxrange = -1;
  125. for (i = 0; i < size-1;i++)
  126. {
  127. if (maxrange < g_tree[i].distance)
  128. {
  129. maxrange = g_tree[i].distance;
  130. }
  131. }
  132. minrange = maxrange;
  133. for (i = 0; i < size-1; i++)
  134. {
  135. if (minrange > g_tree[i].distance)
  136. {
  137. minrange = g_tree[i].distance;
  138. }
  139. }
  140. for (i = 0 ;i < size-1;i++)
  141. {
  142. g_tree[i].distance=(MAXVAL-MINVAL)/(double)(maxrange-minrange)*g_tree[i].distance-(MAXVAL-MINVAL)/(double)(maxrange-minrange)*minrange+MINVAL;
  143. }
  144. }
  145. void printDendogram(std::string fileName, int size)
  146. {
  147. std::ofstream output(fileName.c_str());
  148. output << "MATLAB: ==== Pairwise single linkage clustering using NORMALIZED DIST MATRIX." << std::endl;
  149. for(unsigned short int i=0; i< (size - 1); i++)
  150. {
  151. if (g_tree[i].left >= 0 && g_tree[i].right >= 0)
  152. output << g_tree[i].left+1 << g_tree[i].right+1 << " " << g_tree[i].distance << std::endl;
  153. if (g_tree[i].left >= 0 && g_tree[i].right < 0)
  154. output << g_tree[i].left+1 << (-1*g_tree[i].right)+size << " " << g_tree[i].distance << std::endl;
  155. if (g_tree[i].left < 0 && g_tree[i].right >= 0)
  156. output << (-1*g_tree[i].left)+size << g_tree[i].right+1 << " " << g_tree[i].distance << std::endl;
  157. if (g_tree[i].left < 0 && g_tree[i].right < 0)
  158. output << (-1*g_tree[i].left)+size << (-1*g_tree[i].right)+size << " " << g_tree[i].distance << std::endl;
  159. }
  160. }
  161. void buildHabitats(int size)
  162. {
  163. unsigned short int i = 0;
  164. unsigned short int j = 0;
  165. unsigned short int k = 0;
  166. unsigned short int sum_tabu = 0;
  167. int cur_node = size - 1;
  168. int cur_habitat = 0;
  169. unsigned short int cur_node_index = 0;
  170. double sum_left = 0.0;
  171. double sum_right = 0.0;
  172. double dist_aux = 0.0;
  173. Aleatory aleatory;
  174. g_habitatsSize = 0;
  175. for (i = 0; i < size; i++)
  176. {
  177. H[i].h_sp_count = 0;
  178. }
  179. while (sum_tabu < size-1)
  180. {
  181. if ( aleatory.nextDouble() >= g_tree[cur_node-1].distance) //link those two itens
  182. {
  183. if (cur_node == size-1) //first iteration.
  184. {
  185. H[cur_habitat].h_sp[ H[cur_habitat].h_sp_count ] = g_tree[cur_node-1].left;
  186. H[cur_habitat].h_sp[ H[cur_habitat].h_sp_count+1 ] = g_tree[cur_node-1].right;
  187. H[cur_habitat].h_sp_count = 2;
  188. sum_tabu++;
  189. }
  190. else
  191. {
  192. if (cur_node == 1)
  193. {
  194. H[cur_habitat].h_sp[ cur_node_index ] = g_tree[0].left;
  195. H[cur_habitat].h_sp[ H[cur_habitat].h_sp_count ] = g_tree[0].right;
  196. H[cur_habitat].h_sp_count += 1;
  197. sum_tabu++;
  198. }
  199. else
  200. {
  201. H[cur_habitat].h_sp[ cur_node_index ] = g_tree[cur_node-1].left;
  202. H[cur_habitat].h_sp[ H[cur_habitat].h_sp_count ] = g_tree[cur_node-1].right;
  203. H[cur_habitat].h_sp_count += 1;
  204. sum_tabu++;
  205. }
  206. }
  207. }
  208. else
  209. {
  210. if (cur_node == size-1)
  211. {
  212. H[cur_habitat].h_sp[ H[cur_habitat].h_sp_count ] = g_tree[cur_node-1].left;
  213. g_habitatsSize++;
  214. H[g_habitatsSize].h_sp[ H[g_habitatsSize].h_sp_count ] = g_tree[cur_node-1].right;
  215. H[cur_habitat].h_sp_count += 1;
  216. H[g_habitatsSize].h_sp_count += 1;
  217. sum_tabu++;
  218. }
  219. else
  220. {
  221. if (H[cur_habitat].h_sp_count == 1 && H[cur_habitat].h_sp[0] < 0)
  222. {
  223. H[cur_habitat].h_sp[ cur_node_index ] = g_tree[cur_node-1].left;
  224. g_habitatsSize++;
  225. H[g_habitatsSize].h_sp[ H[g_habitatsSize].h_sp_count ] = g_tree[cur_node-1].right;
  226. H[g_habitatsSize].h_sp_count += 1;
  227. sum_tabu++;
  228. }
  229. if (g_tree[cur_node-1].left >= 0 && g_tree[cur_node-1].right >= 0 && H[cur_habitat].h_sp_count > 1)
  230. {
  231. sum_left = sum_right = 0.0;
  232. for (i = 0; i < H[cur_habitat].h_sp_count; i++)
  233. {
  234. if (H[cur_habitat].h_sp[ i ] >= 0)
  235. {
  236. sum_left += g_distances[ H[cur_habitat].h_sp[ i ] ][ g_tree[cur_node-1].left ];
  237. sum_right += g_distances[ H[cur_habitat].h_sp[ i ] ][ g_tree[cur_node-1].right ];
  238. }
  239. }
  240. if (sum_left <= sum_right)
  241. {
  242. H[cur_habitat].h_sp[ cur_node_index ] = g_tree[cur_node-1].left;
  243. g_habitatsSize++;
  244. H[g_habitatsSize].h_sp[ H[g_habitatsSize].h_sp_count ] = g_tree[cur_node-1].right;
  245. }
  246. else
  247. {
  248. H[cur_habitat].h_sp[ cur_node_index ] = g_tree[cur_node-1].right;
  249. g_habitatsSize++;
  250. H[g_habitatsSize].h_sp[ H[g_habitatsSize].h_sp_count ] = g_tree[cur_node-1].left;
  251. }
  252. H[g_habitatsSize].h_sp_count += 1;
  253. sum_tabu++;
  254. }
  255. else if (g_tree[cur_node-1].left < 0 && g_tree[cur_node-1].right < 0 && H[cur_habitat].h_sp_count > 1)
  256. {
  257. if ( g_tree[cur_node-1].left < g_tree[cur_node-1].right )
  258. {
  259. H[cur_habitat].h_sp[ cur_node_index ] = g_tree[cur_node-1].left;
  260. g_habitatsSize++;
  261. H[g_habitatsSize].h_sp[ H[g_habitatsSize].h_sp_count ] = g_tree[cur_node-1].right;
  262. }
  263. else
  264. {
  265. H[cur_habitat].h_sp[ cur_node_index ] = g_tree[cur_node-1].right;
  266. g_habitatsSize++;
  267. H[g_habitatsSize].h_sp[ H[g_habitatsSize].h_sp_count ] = g_tree[cur_node-1].left;
  268. }
  269. H[g_habitatsSize].h_sp_count += 1;
  270. sum_tabu++;
  271. }
  272. else if (H[cur_habitat].h_sp_count > 1)
  273. {
  274. if (g_tree[cur_node-1].left >= 0)
  275. {
  276. H[cur_habitat].h_sp[ cur_node_index ] = g_tree[cur_node-1].left;
  277. g_habitatsSize++;
  278. H[g_habitatsSize].h_sp[ H[g_habitatsSize].h_sp_count ] = g_tree[cur_node-1].right;
  279. }else
  280. {
  281. H[cur_habitat].h_sp[ cur_node_index ] = g_tree[cur_node-1].right;
  282. g_habitatsSize++;
  283. H[g_habitatsSize].h_sp[ H[g_habitatsSize].h_sp_count ] = g_tree[cur_node-1].left;
  284. }
  285. H[g_habitatsSize].h_sp_count += 1;
  286. sum_tabu++;
  287. }
  288. }
  289. }
  290. i = 0;
  291. cur_habitat = -1;
  292. j = 0;
  293. while (i <= g_habitatsSize && cur_habitat < 0)
  294. {
  295. while (j < H[i].h_sp_count && cur_habitat < 0)
  296. {
  297. if (H[i].h_sp[j] < 0)
  298. {
  299. cur_habitat = i;
  300. }
  301. else j++;
  302. }
  303. i++;
  304. j = 0;
  305. }
  306. if (cur_habitat >= 0)
  307. {
  308. i = 0;
  309. while (H[cur_habitat].h_sp[i] >= 0)
  310. i++;
  311. cur_node = -1*H[cur_habitat].h_sp[i];
  312. cur_node_index = i;
  313. }
  314. }
  315. g_habitatsSize++;
  316. for (i = 0; i < size; i++)
  317. {
  318. sp_int[i] = 0;
  319. for (j = 0; j < size; j++)
  320. {
  321. sp_adj[i][j] = -1;
  322. }
  323. }
  324. for ( i = 0; i < g_habitatsSize; i++)
  325. {
  326. if (H[i].h_sp_count == 1)
  327. {
  328. //update nothing
  329. }else if ((H[i].h_sp_count == 2))
  330. {
  331. sp_adj[ H[i].h_sp[0] ][0] = H[i].h_sp[1];
  332. sp_int[H[i].h_sp[0]]++;
  333. sp_adj[ H[i].h_sp[1] ][0] = H[i].h_sp[0];
  334. sp_int[H[i].h_sp[1]]++;
  335. }
  336. else
  337. {
  338. for (j=0;j<H[i].h_sp_count;j++)
  339. {
  340. k = aleatory.nextInt(H[i].h_sp_count);
  341. while (sp_int[H[i].h_sp[j]] == 0)
  342. {
  343. if (g_distances[ H[i].h_sp[j] ][ H[i].h_sp[k] ] == 1.0)//give a small chance to choose
  344. {
  345. dist_aux = 0.99;
  346. }
  347. else
  348. {
  349. dist_aux = g_distances[ H[i].h_sp[j] ][ H[i].h_sp[k] ];
  350. }
  351. if ( (j != k) && aleatory.nextDouble() >= dist_aux)
  352. {
  353. sp_adj[ H[i].h_sp[j] ][sp_int[H[i].h_sp[j]]] = H[i].h_sp[k];
  354. sp_int[H[i].h_sp[j]]++;
  355. k = H[i].h_sp_count;
  356. }
  357. else
  358. {
  359. k = aleatory.nextInt(H[i].h_sp_count);
  360. }
  361. }
  362. }
  363. }
  364. }
  365. }
  366. void printPairwiseInteractions(std::string fileName, int size)
  367. {
  368. unsigned short int i = 0;
  369. unsigned short int j = 0;
  370. std::ofstream output;
  371. output.open(fileName.c_str(), std::ios_base::app);
  372. for(i = 0; i < size; i++)
  373. {
  374. output << "Specie :: " << i << " => ";
  375. for(j = 0; j < sp_int[i]; j++)
  376. {
  377. output << sp_adj[i][j] << "; ";
  378. }
  379. output << "" << std::endl;
  380. }
  381. }
  382. #endif