Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*
- * Experiment.cpp
- *
- */
- #include<stdlib.h>
- #include<iostream>
- #include "Experiment.h"
- #include "Distribution.h"
- #define DEBUG_ON_
- using namespace std;
- Experiment::Experiment(int balls, int drawsNumber) {
- this->balls = balls;
- this->drawsNumber = drawsNumber;
- // najgorszy scenariusz - losowanie ze zwracaniem i
- // wylosowano tylko kule o najwyzszym numerze.
- hmax = this->drawsNumber * (balls-1);
- histogram = new long[hmax];
- used = new bool[balls];
- forbidden = new bool[ balls ];
- for ( int i = 0; i < balls; i++ )
- forbidden[ i ] = false;
- }
- void Experiment::setSamplingWithReplacement() {
- withReplacement = true;
- }
- void Experiment::setSamplingWithoutReplacement() {
- withReplacement = false;
- }
- void Experiment::setForbidden( int ball ) {
- #ifdef DEBUG_ON
- cout << "Zablokowano mozliwosc uzywania kuli " << ball << endl;
- #endif
- forbidden[ ball ] = true;
- }
- void Experiment::setAllowed( int ball ) {
- forbidden[ ball ] = false;
- }
- void Experiment::clearHistogram() {
- for (long i = 0; i < hmax; i++) {
- histogram[i] = 0;
- }
- }
- void Experiment::allBallsToUrn() {
- if ( withReplacement ) return;
- for (int i = 0; i < balls; i++)
- used[i] = false;
- }
- void Experiment::ballIsDrawn( int ball ) {
- if ( withReplacement ) return;
- #ifdef DEBUG_ON
- cout << "Kula o numerze " << ball << " nie moze juz byc ponownie wybrana" << endl;
- #endif
- used[ball] = true;
- }
- bool Experiment::isAllowed( int ball ) {
- if ( forbidden[ ball ] ) return false; // tej kuli nie mozna uzywac
- if ( withReplacement ) return true; // kule sa zwracane, wiec mozna ich ponownie uzywac
- return ! used[ ball ];
- }
- void Experiment::setMyMPIModule(MyMPI *mpi) {
- this->myMPI = mpi;
- }
- long Experiment::singleExperimentResult() {
- long sum = 0;
- int ball;
- double p;
- allBallsToUrn();
- for (int i = 0; i < drawsNumber;) {
- ball = (int) (((double) balls * rand()) / ( RAND_MAX + 1.0)); // rand losuje od 0 do RAND_MAX wlacznie
- #ifdef DEBUG_ON
- cout << "Propozycja " << ball << endl;
- #endif
- if ( ! isAllowed( ball ) ) {
- #ifdef DEBUG_ON
- cout << "Propozycja - ta kula nie moze byc uzyta " << ball << endl;
- #endif
- continue; // jeszcze raz losujemy
- } else {
- #ifdef DEBUG_ON
- cout << "Propozycja - OK " << ball << endl;
- #endif
- }
- p = Distribution::getProbability(i + 1, ball); // pobieramy prawdopodobienstwo
- // wybrania tej kuli
- if ((rand() / ( RAND_MAX + 1.0)) < p) // akceptacja wyboru kuli z zadanym prawdopodobienstwem
- {
- ballIsDrawn(ball);
- sum += ball;
- i++;
- }
- }
- return sum;
- }
- void Experiment::setNumberOfExperiments( long experiments ) {
- this->experiments = experiments;
- }
- void Experiment::calc() {
- int process, processes;
- myMPI->MPI_Comm_rank( MPI_COMM_WORLD, &process);
- myMPI->MPI_Comm_size( MPI_COMM_WORLD, &processes);
- myMPI->MPI_Bcast(forbidden, balls, MPI_CHAR, 0, MPI_COMM_WORLD);
- int testChunk = 17;
- myMPI->MPI_Bcast(&testChunk, 1, MPI_INT, 0, MPI_COMM_WORLD);
- long* histogramChunk = new long[testChunk];
- double start, end;
- start = MPI_Wtime();
- for (long l = 0; l < testChunk; l++) {
- histogramChunk[l] = singleExperimentResult();
- }
- end = MPI_Wtime();
- double time = 1. / ( end - start );
- if ( process != 0 ) {
- myMPI->MPI_Send(histogramChunk, testChunk, MPI_LONG, 0, 50, MPI_COMM_WORLD);
- } else {
- getChunkHistogram(histogramChunk, testChunk);
- MPI_Status status;
- for ( int source = 1; source < processes; source++ ) {
- myMPI->MPI_Recv(histogramChunk, testChunk, MPI_LONG, source, 50, MPI_COMM_WORLD, &status);
- getChunkHistogram(histogramChunk, testChunk);
- }
- }
- int* chunks;
- if ( process != 0 ) {
- myMPI->MPI_Send(&time, 1, MPI_DOUBLE, 0, 51, MPI_COMM_WORLD);
- } else {
- // receive time
- double* times = new double[processes];
- times[0] = time;
- for ( int source = 1; source < processes; source++ ) {
- MPI_Status status;
- myMPI->MPI_Recv(&time, 1, MPI_DOUBLE, source, 51, MPI_COMM_WORLD, &status);
- times[source] = time;
- }
- // compute chunks
- long leftExperiments = experiments - ( processes * testChunk );
- chunks = getChunks(leftExperiments, times, processes);
- //sends chunks
- for ( int source = 1; source < processes; source++ ) {
- MPI_Status status;
- myMPI->MPI_Send((chunks + source), 1, MPI_INT, source, 52, MPI_COMM_WORLD);
- times[source] = time;
- }
- }
- if (process != 0) {
- int chunk;
- MPI_Status status;
- myMPI->MPI_Recv(&chunk, 1, MPI_INT, 0, 52, MPI_COMM_WORLD, &status);
- long * histogramChunk2 = new long[chunk];
- for (long l = 0; l < chunk; l++) {
- histogramChunk2[l] = singleExperimentResult();
- }
- myMPI->MPI_Send(histogramChunk2, chunk, MPI_LONG, 0, 53, MPI_COMM_WORLD);
- } else {
- long * histogramChunk2 = new long[chunks[0]];
- for (long l = 0; l < chunks[0]; l++) {
- histogramChunk2[l] = singleExperimentResult();
- }
- getChunkHistogram(histogramChunk2, chunks[0]);
- MPI_Status status;
- for ( int source = 1; source < processes; source++ ) {
- long * histogramChunk3 = new long[chunks[source]];
- myMPI->MPI_Recv(histogramChunk3, chunks[source], MPI_LONG, source, 53, MPI_COMM_WORLD, &status);
- getChunkHistogram(histogramChunk3, chunks[source]);
- }
- }
- //delete[] histogramChunk;
- }
- int* Experiment::getChunks(long leftExperiments, double times[], int size) {
- double sigma = 0.0;
- for (int i = 0; i < size; ++i) {
- sigma += times[i];
- }
- int* chunks = new int[size];
- int chunkSigma = 0;
- double maxVal = 0.0;
- int maxIndex = 0;
- for (int i = 0; i < size; ++i) {
- double percent = times[i] / sigma;
- if (percent > maxVal) {
- maxVal = percent;
- maxIndex = i;
- }
- chunks[i] = leftExperiments * percent;
- chunkSigma += chunks[i];
- }
- int diff = leftExperiments - chunkSigma;
- if (diff > 0) {
- chunks[maxIndex] += diff;
- }
- return chunks;
- }
- void Experiment::getChunkHistogram(long chunkHistogram[], int size) {
- for (int i = 0; i < size; ++i) {
- histogram[chunkHistogram[i]]++;
- }
- }
- long Experiment::getHistogramSize() {
- return hmax;
- }
- long *Experiment::getHistogram() {
- return histogram;
- }
- Experiment::~Experiment() {
- delete[] histogram;
- delete[] used;
- delete[] forbidden;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement