Advertisement
Guest User

Untitled

a guest
Dec 7th, 2019
135
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.05 KB | None | 0 0
  1. /*
  2.  * Experiment.cpp
  3.  *
  4.  *  Created on: 16 maj 2016
  5.  *      Author: oramus
  6.  */
  7.  
  8. #include <stdlib.h>
  9. #include <iostream>
  10. #include <omp.h>
  11.  
  12. #include "Experiment.h"
  13. #include "Distribution.h"
  14.  
  15. #define DEBUG_ON_
  16.  
  17. using namespace std;
  18.  
  19. Experiment::Experiment(int balls, int drawsNumber) {
  20.   this->balls = balls;
  21.   this->drawsNumber = drawsNumber;
  22.  
  23.   hmax = 0;  // wyznaczamy maksymalna sume
  24.   hmin = 0;  // i najmniejsza sume
  25.   for (int i = 0; i < drawsNumber; i++) {
  26.     hmax += balls - i;
  27.     hmin += i + 1;  // 1 + 2 + 3 + ... liczba losowan
  28.   }
  29.  
  30.   cout << "Histogram min: " << hmin << " max: " << hmax << endl;
  31.  
  32.   histogram = new long[hmax + 1];
  33.  
  34.   for (long i = 0; i < hmax + 1; i++) histogram[i] = 0;
  35. }
  36.  
  37. void Experiment::clearUsed(bool* used) {
  38.   for (int i = 0; i < balls; i++) {
  39.     used[i] = false;
  40.   }
  41. }
  42.  
  43. long Experiment::singleExperimentResult(drand48_data* drandBuf, bool* used) {
  44.   long sum = 0;
  45.   int ball;
  46.   double p, randomBall, randomProbability;
  47.  
  48.   clearUsed(used);
  49.   for (int i = 0; i < drawsNumber;) {
  50.     drand48_r(drandBuf, &randomBall);
  51.     ball = 1 + (int)((double)balls * randomBall);
  52.  
  53.     if (used[ball - 1]) continue;
  54.  
  55.     p = Distribution::getProbability(
  56.         i + 1, ball);  // pobieramy prawdopodobienstwo wylosowania tej kuli
  57.  
  58.     drand48_r(drandBuf, &randomProbability);
  59.     if (randomProbability < p)  // akceptacja wyboru kuli z zadanym prawdopodobienstwem
  60.     {
  61. #ifdef DEBUG_ON
  62.       cout << "Dodano kule o numerze " << ball << endl;
  63. #endif
  64.       used[ball - 1] = true;
  65.       sum += ball;  // kule maja numery od 1 do balls wlacznie
  66.       i++;
  67.     }
  68.   }
  69.  
  70.   ///   cout << "Suma = " << sum << endl;
  71.  
  72.   return sum;
  73. }
  74.  
  75. Result* Experiment::calc(long experiments) {
  76. #pragma omp parallel
  77.   {
  78.     long* privateHistogram = new long[hmax + 1];
  79.     bool* used = new bool[balls];
  80.  
  81.     int threadId = omp_get_thread_num();
  82.     int totalThreads = omp_get_num_threads();
  83.  
  84.     int chunkSize = (int)(experiments / totalThreads);
  85.     int startIdx = threadId * chunkSize;
  86.     int endIdx;
  87.     if (threadId == totalThreads - 1) {
  88.       endIdx = experiments;
  89.     } else {
  90.       endIdx = (threadId + 1) * chunkSize;
  91.     }
  92.  
  93.     struct drand48_data drandBuf;
  94.     int seed = 1202107158 + threadId * 1999;
  95.     srand48_r(seed, &drandBuf);
  96.  
  97. #pragma omp for
  98.     for (long l = startIdx; l < endIdx; l++) {
  99.       privateHistogram[singleExperimentResult(&drandBuf, used)]++;
  100.     }
  101.  
  102. #pragma omp critical
  103.     {
  104.       for (int i = 0; i < hmax + 1; i++) {
  105.         histogram[i] += privateHistogram[i];
  106.       }
  107.     }
  108.   }
  109.  
  110.   long maxID = 0;
  111.   long minID = 0;
  112.   long maxN = 0;
  113.   long minN = experiments;
  114.   double sum = 0.0;
  115.   long values = 0;
  116.  
  117.   for (long idx = hmin; idx <= hmax; idx++) {
  118.     if (maxN < histogram[idx]) {
  119.       maxN = histogram[idx];
  120.       maxID = idx;
  121.     }
  122.     sum += idx * histogram[idx];
  123.     values += histogram[idx];
  124.   }
  125.   // indeks to wartosc, histogram -> liczba wystapien
  126.   return new Result(maxID, maxN, sum / values, values);
  127. }
  128.  
  129. Experiment::~Experiment() { delete[] histogram; }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement