Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*
- * Experiment.cpp
- *
- * Created on: 16 maj 2016
- * Author: oramus
- */
- #include <stdlib.h>
- #include <iostream>
- #include <omp.h>
- #include "Experiment.h"
- #include "Distribution.h"
- #define DEBUG_ON_
- using namespace std;
- struct drand48_data drand_buf;
- #pragma omp threadprivate(drand_buf)
- long **localHistograms;
- bool *used;
- #pragma omp threadprivate(used)
- Experiment::Experiment(int balls, int drawsNumber)
- {
- this->balls = balls;
- this->drawsNumber = drawsNumber;
- hmax = 0; // wyznaczamy maksymalna sume
- hmin = 0; // i najmniejsza sume
- for (int i = 0; i < drawsNumber; i++)
- {
- hmax += balls - i;
- hmin += i + 1; // 1 + 2 + 3 + ... liczba losowan
- }
- cout << "Histogram min: " << hmin << " max: " << hmax << endl;
- histogram = new long[hmax + 1];
- for (long i = 0; i < hmax + 1; i++)
- histogram[i] = 0;
- #pragma omp parallel
- {
- srand48_r(1202107158 + omp_get_thread_num() * 1999, &drand_buf);
- used = new bool[balls];
- #pragma omp single
- {
- localHistograms = new long *[omp_get_num_threads()];
- for (long i = 0; i < omp_get_num_threads(); i++)
- localHistograms[i] = new long[hmax + 1];
- }
- }
- }
- void Experiment::clearUsed(bool *used)
- {
- for (int i = 0; i < balls; i++)
- used[i] = false;
- }
- long Experiment::singleExperimentResult()
- {
- // cout << "Wykonywanie single przez: " << omp_get_thread_num() << endl;
- long sum = 0;
- int ball;
- double p;
- double probability;
- double ballRand;
- clearUsed(used);
- for (int i = 0; i < drawsNumber;)
- {
- //cout << x << endl;
- drand48_r(&drand_buf, &ballRand);
- ball = 1 + (int)((double)balls * ballRand);
- if (used[ball - 1])
- continue;
- p = Distribution::getProbability(i + 1, ball); // pobieramy prawdopodobienstwo wylosowania tej kuli
- drand48_r(&drand_buf, &probability);
- if (probability < p) // akceptacja wyboru kuli z zadanym prawdopodobienstwem
- {
- #ifdef DEBUG_ON
- cout << "Dodano kule o numerze " << ball << endl;
- #endif
- used[ball - 1] = true;
- sum += ball; // kule maja numery od 1 do balls wlacznie
- i++;
- }
- }
- /// cout << "Suma = " << sum << endl;
- return sum;
- }
- Result *Experiment::calc(long experiments)
- {
- long maxID = 0;
- long maxN = 0;
- double sum = 0.0;
- long values = 0;
- #pragma omp parallel
- {
- long threadCount = omp_get_num_threads();
- long *threadHistogram = localHistograms[omp_get_thread_num()];
- for (long i = 0; i < hmax + 1; i++)
- threadHistogram[i] = 0;
- #pragma omp for schedule(dynamic)
- for (long l = 0; l < experiments; l++)
- threadHistogram[singleExperimentResult()]++;
- long localMaxN = 0;
- long localMaxID = 0;
- long localValues = 0;
- double localSum = 0;
- #pragma omp for nowait
- for (long l = 0; l <= hmax; l++)
- {
- for (long k = 0; k < threadCount; k++)
- {
- histogram[l] += localHistograms[k][l];
- }
- localSum += l * histogram[l];
- localValues += histogram[l];
- if (localMaxN < histogram[l])
- {
- localMaxN = histogram[l];
- localMaxID = l;
- }
- }
- #pragma omp critical
- {
- sum += localSum;
- values += localValues;
- if (localMaxN > maxN)
- {
- maxN = localMaxN;
- maxID = localMaxID;
- }
- }
- }
- // indeks to wartosc, histogram -> liczba wystapien
- return new Result(maxID, maxN, sum / values, values);
- }
- Experiment::~Experiment()
- {
- delete[] histogram;
- #pragma omp parallel
- {
- delete[] localHistograms[omp_get_thread_num()];
- delete[] used;
- }
- delete[] localHistograms;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement