Advertisement
Guest User

Untitled

a guest
Apr 16th, 2018
119
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.20 KB | None | 0 0
  1. /*
  2. * Experiment.cpp
  3. *
  4. */
  5.  
  6. #include<stdlib.h>
  7. #include<iostream>
  8.  
  9. #include "Experiment.h"
  10. #include "Distribution.h"
  11.  
  12. #define DEBUG_ON_
  13.  
  14. using namespace std;
  15.  
  16.  
  17. Experiment::Experiment(int balls, int drawsNumber) {
  18. this->balls = balls;
  19. this->drawsNumber = drawsNumber;
  20.  
  21. // najgorszy scenariusz - losowanie ze zwracaniem i
  22. // wylosowano tylko kule o najwyzszym numerze.
  23. hmax = this->drawsNumber * (balls-1);
  24.  
  25. histogram = new long[hmax];
  26. used = new bool[balls];
  27. forbidden = new bool[ balls ];
  28. for ( int i = 0; i < balls; i++ )
  29. forbidden[ i ] = false;
  30. }
  31.  
  32. void Experiment::setSamplingWithReplacement() {
  33. withReplacement = true;
  34. }
  35.  
  36. void Experiment::setSamplingWithoutReplacement() {
  37. withReplacement = false;
  38. }
  39.  
  40. void Experiment::setForbidden( int ball ) {
  41. #ifdef DEBUG_ON
  42. cout << "Zablokowano mozliwosc uzywania kuli " << ball << endl;
  43. #endif
  44. forbidden[ ball ] = true;
  45. }
  46.  
  47. void Experiment::setAllowed( int ball ) {
  48. forbidden[ ball ] = false;
  49. }
  50.  
  51. void Experiment::clearHistogram() {
  52. for (long i = 0; i < hmax; i++) {
  53. histogram[i] = 0;
  54. }
  55. }
  56.  
  57. void Experiment::allBallsToUrn() {
  58. if ( withReplacement ) return;
  59. for (int i = 0; i < balls; i++)
  60. used[i] = false;
  61. }
  62.  
  63. void Experiment::ballIsDrawn( int ball ) {
  64. if ( withReplacement ) return;
  65.  
  66. #ifdef DEBUG_ON
  67. cout << "Kula o numerze " << ball << " nie moze juz byc ponownie wybrana" << endl;
  68. #endif
  69.  
  70. used[ball] = true;
  71. }
  72.  
  73. bool Experiment::isAllowed( int ball ) {
  74. if ( forbidden[ ball ] ) return false; // tej kuli nie mozna uzywac
  75.  
  76. if ( withReplacement ) return true; // kule sa zwracane, wiec mozna ich ponownie uzywac
  77.  
  78. return ! used[ ball ];
  79. }
  80.  
  81. void Experiment::setMyMPIModule(MyMPI *mpi) {
  82. this->myMPI = mpi;
  83. }
  84.  
  85. long Experiment::singleExperimentResult() {
  86. long sum = 0;
  87. int ball;
  88. double p;
  89.  
  90. allBallsToUrn();
  91. for (int i = 0; i < drawsNumber;) {
  92. ball = (int) (((double) balls * rand()) / ( RAND_MAX + 1.0)); // rand losuje od 0 do RAND_MAX wlacznie
  93.  
  94. #ifdef DEBUG_ON
  95. cout << "Propozycja " << ball << endl;
  96. #endif
  97.  
  98. if ( ! isAllowed( ball ) ) {
  99. #ifdef DEBUG_ON
  100. cout << "Propozycja - ta kula nie moze byc uzyta " << ball << endl;
  101. #endif
  102. continue; // jeszcze raz losujemy
  103. } else {
  104. #ifdef DEBUG_ON
  105. cout << "Propozycja - OK " << ball << endl;
  106. #endif
  107. }
  108.  
  109. p = Distribution::getProbability(i + 1, ball); // pobieramy prawdopodobienstwo
  110. // wybrania tej kuli
  111.  
  112. if ((rand() / ( RAND_MAX + 1.0)) < p) // akceptacja wyboru kuli z zadanym prawdopodobienstwem
  113. {
  114. ballIsDrawn(ball);
  115. sum += ball;
  116. i++;
  117. }
  118. }
  119.  
  120. return sum;
  121. }
  122.  
  123. void Experiment::setNumberOfExperiments( long experiments ) {
  124. this->experiments = experiments;
  125. }
  126.  
  127. void Experiment::calc() {
  128. int process, processes;
  129. myMPI->MPI_Comm_rank( MPI_COMM_WORLD, &process);
  130. myMPI->MPI_Comm_size( MPI_COMM_WORLD, &processes);
  131.  
  132. myMPI->MPI_Bcast(forbidden, balls, MPI_CHAR, 0, MPI_COMM_WORLD);
  133.  
  134. int testChunk = 17;
  135.  
  136. myMPI->MPI_Bcast(&testChunk, 1, MPI_INT, 0, MPI_COMM_WORLD);
  137.  
  138. long* histogramChunk = new long[testChunk];
  139.  
  140. double start, end;
  141. start = MPI_Wtime();
  142. for (long l = 0; l < testChunk; l++) {
  143. histogramChunk[l] = singleExperimentResult();
  144. }
  145. end = MPI_Wtime();
  146. double time = 1. / ( end - start );
  147.  
  148. if ( process != 0 ) {
  149. myMPI->MPI_Send(histogramChunk, testChunk, MPI_LONG, 0, 50, MPI_COMM_WORLD);
  150. } else {
  151. getChunkHistogram(histogramChunk, testChunk);
  152. MPI_Status status;
  153. for ( int source = 1; source < processes; source++ ) {
  154. myMPI->MPI_Recv(histogramChunk, testChunk, MPI_LONG, source, 50, MPI_COMM_WORLD, &status);
  155. getChunkHistogram(histogramChunk, testChunk);
  156. }
  157. }
  158.  
  159. int* chunks;
  160. if ( process != 0 ) {
  161. myMPI->MPI_Send(&time, 1, MPI_DOUBLE, 0, 51, MPI_COMM_WORLD);
  162. } else {
  163. // receive time
  164. double* times = new double[processes];
  165. times[0] = time;
  166. for ( int source = 1; source < processes; source++ ) {
  167. MPI_Status status;
  168. myMPI->MPI_Recv(&time, 1, MPI_DOUBLE, source, 51, MPI_COMM_WORLD, &status);
  169. times[source] = time;
  170. }
  171.  
  172. // compute chunks
  173. long leftExperiments = experiments - ( processes * testChunk );
  174. chunks = getChunks(leftExperiments, times, processes);
  175. //sends chunks
  176. for ( int source = 1; source < processes; source++ ) {
  177. MPI_Status status;
  178. myMPI->MPI_Send((chunks + source), 1, MPI_INT, source, 52, MPI_COMM_WORLD);
  179. times[source] = time;
  180. }
  181. }
  182.  
  183. if (process != 0) {
  184. int chunk;
  185. MPI_Status status;
  186. myMPI->MPI_Recv(&chunk, 1, MPI_INT, 0, 52, MPI_COMM_WORLD, &status);
  187. long * histogramChunk2 = new long[chunk];
  188.  
  189. for (long l = 0; l < chunk; l++) {
  190. histogramChunk2[l] = singleExperimentResult();
  191. }
  192. myMPI->MPI_Send(histogramChunk2, chunk, MPI_LONG, 0, 53, MPI_COMM_WORLD);
  193. } else {
  194. long * histogramChunk2 = new long[chunks[0]];
  195. for (long l = 0; l < chunks[0]; l++) {
  196. histogramChunk2[l] = singleExperimentResult();
  197. }
  198. getChunkHistogram(histogramChunk2, chunks[0]);
  199. MPI_Status status;
  200. for ( int source = 1; source < processes; source++ ) {
  201. long * histogramChunk3 = new long[chunks[source]];
  202. myMPI->MPI_Recv(histogramChunk3, chunks[source], MPI_LONG, source, 53, MPI_COMM_WORLD, &status);
  203. getChunkHistogram(histogramChunk3, chunks[source]);
  204. }
  205. }
  206.  
  207. //delete[] histogramChunk;
  208. }
  209.  
  210. int* Experiment::getChunks(long leftExperiments, double times[], int size) {
  211. double sigma = 0.0;
  212. for (int i = 0; i < size; ++i) {
  213. sigma += times[i];
  214. }
  215.  
  216. int* chunks = new int[size];
  217. int chunkSigma = 0;
  218. double maxVal = 0.0;
  219. int maxIndex = 0;
  220.  
  221. for (int i = 0; i < size; ++i) {
  222. double percent = times[i] / sigma;
  223. if (percent > maxVal) {
  224. maxVal = percent;
  225. maxIndex = i;
  226. }
  227.  
  228. chunks[i] = leftExperiments * percent;
  229.  
  230. chunkSigma += chunks[i];
  231. }
  232.  
  233. int diff = leftExperiments - chunkSigma;
  234.  
  235. if (diff > 0) {
  236. chunks[maxIndex] += diff;
  237. }
  238.  
  239. return chunks;
  240. }
  241.  
  242. void Experiment::getChunkHistogram(long chunkHistogram[], int size) {
  243. for (int i = 0; i < size; ++i) {
  244. histogram[chunkHistogram[i]]++;
  245. }
  246. }
  247.  
  248. long Experiment::getHistogramSize() {
  249. return hmax;
  250. }
  251.  
  252. long *Experiment::getHistogram() {
  253. return histogram;
  254. }
  255.  
  256. Experiment::~Experiment() {
  257. delete[] histogram;
  258. delete[] used;
  259. delete[] forbidden;
  260. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement