daily pastebin goal
46%
SHARE
TWEET

Untitled

a guest Apr 16th, 2018 84 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  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. }
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top