Advertisement
Guest User

Untitled

a guest
Jun 20th, 2018
69
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 8.64 KB | None | 0 0
  1. #include "stdafx.h"
  2. #include <stdlib.h>
  3. #include <stdio.h>
  4. #include <time.h>
  5.  
  6. #define FUNC_PARAMS_DIM 6
  7. #define NUMBER_OF_PARTICLES 100
  8. #define NUMBER_OF_ITERATIONS 100000
  9. #define ACTIVE_THRESHOLD 3000
  10. #define LOWER_ACTIVE_THRESHOLD 500
  11.  
  12. // #define DEBUG
  13.  
  14. typedef struct vector {
  15. int dimensionCount;
  16. double* coordinates;
  17. } vector;
  18.  
  19. typedef struct dataPoint {
  20. vector position;
  21. double value;
  22. } dataPoint;
  23.  
  24. typedef struct dataSeed {
  25. int numberOfPoints;
  26. dataPoint* points;
  27. } dataSeed;
  28.  
  29. typedef struct particle {
  30. vector currentPos;
  31. int isActive;
  32. } particle;
  33.  
  34. typedef struct swarmType {
  35. int numberOfParticles;
  36. particle** particles;
  37. } swarmType;
  38.  
  39. typedef double(*funcPtr)(vector* parameters, vector* position);
  40.  
  41. double calculatePolynomial1d(vector* parameters, vector* position) {
  42. double value = 0.0;
  43. int i = 0;
  44.  
  45. for (; i < parameters->dimensionCount; i++)
  46. {
  47. value *= position->coordinates[0];
  48. value += parameters->coordinates[i];
  49. }
  50. return value;
  51. }
  52.  
  53. double leastSquares(dataSeed* tab, funcPtr func, vector* parameters)
  54. {
  55. double squares = 0.0;
  56. for (int i = 0; i < tab->numberOfPoints; i++)
  57. {
  58. dataPoint* currentPoint = &tab->points[i];
  59. double currentDistance = currentPoint->value - func(parameters, &currentPoint->position);
  60. squares += currentDistance * currentDistance;
  61. }
  62. return squares;
  63. }
  64.  
  65. void PrintfParticle(dataSeed * seed, particle * bestParticle)
  66. {
  67. int i;
  68. printf("Squared distance: %lf\n", leastSquares(seed, &calculatePolynomial1d, &bestParticle->currentPos));
  69.  
  70. for (i = 0; i < bestParticle->currentPos.dimensionCount; i++)
  71. {
  72. double coord = bestParticle->currentPos.coordinates[i];
  73. printf("%c: %e\n", 'A' + i, coord);
  74. }
  75. }
  76.  
  77.  
  78. double getRandom(double min, double max)
  79. {
  80. return (double)rand() / (double)RAND_MAX * (max - min) + min;
  81. }
  82.  
  83. void assignPosition(vector* dest, vector* src)
  84. {
  85. if (dest->dimensionCount != src->dimensionCount)
  86. {
  87. fprintf(stderr, "assigningPosition of the different dimensions points\n");
  88. exit(1);
  89. }
  90.  
  91. for (int i = 0; i < dest->dimensionCount; i++)
  92. {
  93. dest->coordinates[i] = src->coordinates[i];
  94. }
  95. }
  96.  
  97. particle* initializeParticle(int dimensionNumber, double* minimums, double* maximums)
  98. {
  99. struct particle* singleParticle = (particle*)malloc(sizeof(particle));
  100. singleParticle->currentPos.coordinates = (double*)malloc(dimensionNumber * sizeof(double));
  101. singleParticle->currentPos.dimensionCount = dimensionNumber;
  102. singleParticle->isActive = 0;
  103.  
  104. for (int i = 0; i < dimensionNumber; i++)
  105. {
  106. singleParticle->currentPos.coordinates[i] = getRandom(minimums[i], maximums[i]);
  107. }
  108. return singleParticle;
  109. }
  110.  
  111. swarmType* initializeSwarm(funcPtr func, int numberOfParticles, int dimensionNumber, double* minimums, double* maximums, dataSeed* seed)
  112. {
  113. swarmType* swarm = (swarmType*)malloc(sizeof(swarmType));
  114. swarm->numberOfParticles = numberOfParticles;
  115. swarm->particles = (particle**)malloc(numberOfParticles * sizeof(particle*));
  116.  
  117. for (int i = 0; i < numberOfParticles; i++) {
  118. swarm->particles[i] = initializeParticle(dimensionNumber, minimums, maximums);
  119. }
  120.  
  121. return swarm;
  122. }
  123.  
  124. void freeParticle(particle* singleParticle)
  125. {
  126. free(singleParticle->currentPos.coordinates);
  127. }
  128.  
  129. void freeSwarm(swarmType* swarm)
  130. {
  131. for (int i = 0; i < swarm->numberOfParticles; i++)
  132. {
  133. freeParticle(swarm->particles[i]);
  134. }
  135. free(swarm->particles);
  136. free(swarm);
  137. }
  138.  
  139. dataSeed* initializeSeed(FILE* file)
  140. {
  141. int i;
  142. dataSeed* seed = (dataSeed*)malloc(sizeof(dataSeed));
  143. fscanf(file, "%d", &seed->numberOfPoints);
  144. seed->points = (dataPoint*)malloc(seed->numberOfPoints * sizeof(dataPoint));
  145.  
  146. for (i = 0; i < seed->numberOfPoints; i++)
  147. {
  148. seed->points[i].position.dimensionCount = 1;
  149. seed->points[i].position.coordinates = (double*)malloc(sizeof(double));
  150. fscanf(file, "%lf;%lf", &(seed->points[i].position.coordinates[0]), &(seed->points[i].value));
  151. }
  152. return seed;
  153. }
  154.  
  155. void freeSeed(dataSeed* seed)
  156. {
  157. int i;
  158. for (i = 0; i < seed->numberOfPoints; i++)
  159. {
  160. free(seed->points[i].position.coordinates);
  161. }
  162. free(seed->points);
  163. free(seed);
  164. }
  165.  
  166. void RerollLastParameter(particle* currentParticle, double* minimums, double* maximums)
  167. {
  168. int lastDimNumber = currentParticle->currentPos.dimensionCount - 1;
  169. currentParticle->currentPos.coordinates[lastDimNumber] = getRandom(minimums[lastDimNumber], maximums[lastDimNumber]);
  170. }
  171.  
  172. void RerollAllParameters(particle* currentParticle, double* minimums, double* maximums)
  173. {
  174. int i;
  175. int numberOfIterations = currentParticle->currentPos.dimensionCount;
  176. for (i = 0; i < numberOfIterations; i++) {
  177. currentParticle->currentPos.coordinates[i] = getRandom(minimums[i], maximums[i]);
  178. }
  179. }
  180.  
  181. void TryRerollAnyParameter(dataSeed* seed, funcPtr func, particle* currentParticle, double* minimums, double* maximums)
  182. {
  183. int numberOfDimentsions = currentParticle->currentPos.dimensionCount;
  184. int i = (int)((double)rand() / (double)RAND_MAX * (double)numberOfDimentsions);
  185.  
  186. double oldParam = currentParticle->currentPos.coordinates[i];
  187. double oldValue = leastSquares(seed, func, &currentParticle->currentPos);
  188.  
  189. currentParticle->currentPos.coordinates[i] = getRandom(minimums[i], maximums[i]);
  190. double newValue = leastSquares(seed, func, &currentParticle->currentPos);
  191.  
  192. if (newValue > oldValue) {
  193. currentParticle->currentPos.coordinates[i] = oldParam;
  194. }
  195. }
  196.  
  197. int IsActive(particle* currentParticle, dataSeed* seed, funcPtr func)
  198. {
  199. double currentSquaredDiferencesSum = leastSquares(seed, func, &currentParticle->currentPos);
  200.  
  201. if (currentSquaredDiferencesSum < LOWER_ACTIVE_THRESHOLD)
  202. {
  203. PrintfParticle(seed, currentParticle);
  204. }
  205.  
  206. return currentSquaredDiferencesSum < ACTIVE_THRESHOLD;
  207. }
  208.  
  209. void CopyParameters(particle* currentParticle, particle* buddy)
  210. {
  211. int i;
  212. for (i = 0; i < currentParticle->currentPos.dimensionCount; i++) {
  213. currentParticle->currentPos.coordinates[i] = buddy->currentPos.coordinates[i];
  214. }
  215. }
  216.  
  217. void Iterate(funcPtr func, swarmType* swarm, dataSeed* seed, double* minimums, double* maximums)
  218. {
  219. int i;
  220. for (i = 0; i < swarm->numberOfParticles; i++)
  221. {
  222. particle* currentParticle = swarm->particles[i];
  223. if (currentParticle->isActive) {
  224. TryRerollAnyParameter(seed, func, currentParticle, minimums, maximums);
  225. }
  226. else {
  227. int buddyIndex = (int)((double)rand() / (double)RAND_MAX * (double)(swarm->numberOfParticles - 1));
  228. particle* buddy = swarm->particles[buddyIndex];
  229. if (buddy->isActive) {
  230. CopyParameters(currentParticle, buddy);
  231. RerollLastParameter(currentParticle, minimums, maximums);
  232. }
  233. else {
  234. RerollAllParameters(currentParticle, minimums, maximums);
  235. }
  236. }
  237. }
  238. for (i = 0; i < swarm->numberOfParticles; i++)
  239. {
  240. particle* currentParticle = swarm->particles[i];
  241. currentParticle->isActive = IsActive(currentParticle, seed, func);
  242. }
  243. }
  244.  
  245. particle* GetBestParticle(dataSeed* seed, funcPtr func, swarmType* swarm)
  246. {
  247. int i;
  248. particle* bestParticle = swarm->particles[0];
  249. double bestSquaredDiferencesSum = leastSquares(seed, func, &swarm->particles[0]->currentPos);
  250.  
  251. for (i = 1; i < swarm->numberOfParticles; i++)
  252. {
  253. particle* currentParticle = swarm->particles[i];
  254.  
  255. double currentSquaredDiferencesSum = leastSquares(seed, func, &currentParticle->currentPos);
  256.  
  257. if (currentSquaredDiferencesSum < bestSquaredDiferencesSum)
  258. {
  259. bestSquaredDiferencesSum = currentSquaredDiferencesSum;
  260. bestParticle = currentParticle;
  261. }
  262. }
  263.  
  264. return bestParticle;
  265. }
  266.  
  267. int main(int argc, char** argv)
  268. {
  269. srand(time(NULL));
  270.  
  271. double minimums[] = { -1e-15, -1e-10, -1e-10, -1e-4, -1e-4, -3.5 };
  272. double maximums[] = { 1e-15, 1e-10, 1e-10, 1e-4, 1e-4, 0 };
  273.  
  274. #ifdef DEBUG
  275. printf("Opening File: %s\n", argv[1]);
  276. #endif
  277.  
  278. FILE* inFile = fopen("dane.txt", "r");
  279.  
  280. #ifdef DEBUG
  281. printf("Initializing Seed\n");
  282. #endif
  283.  
  284. dataSeed* seed = initializeSeed(inFile);
  285.  
  286. #ifdef DEBUG
  287. printf("Seed Initialized with size: %d\n", seed->numberOfPoints);
  288. #endif
  289.  
  290. fclose(inFile);
  291.  
  292. swarmType* swarm = initializeSwarm(&calculatePolynomial1d,
  293. NUMBER_OF_PARTICLES,
  294. FUNC_PARAMS_DIM,
  295. minimums,
  296. maximums,
  297. seed);
  298.  
  299.  
  300. #ifdef DEBUG
  301. printf("Swarm initialized with size: %d\nIterating...\n", swarm->numberOfParticles);
  302. #endif
  303.  
  304. int i;
  305.  
  306. for (i = 0; i < NUMBER_OF_ITERATIONS; i++)
  307. {
  308. #ifdef DEBUG
  309. printf(".");
  310. #endif
  311.  
  312. if (!(i % (NUMBER_OF_ITERATIONS / 10))) {
  313. printf("%.1lf%%\n", (double)i * 100.0 / (double)NUMBER_OF_ITERATIONS);
  314. }
  315. Iterate(&calculatePolynomial1d, swarm, seed, minimums, maximums);
  316. }
  317.  
  318. printf("\nResults:");
  319.  
  320. particle* bestParticle = GetBestParticle(seed, &calculatePolynomial1d, swarm);
  321.  
  322. PrintfParticle(seed, bestParticle);
  323.  
  324. printf("\n");
  325. getchar();
  326. return 0;
  327. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement