Hej udviklere,
jeg har prøvet at få et lille program til at køre, der skal tage mod en talrække af positive og negative tal, ændre fortegnene tilfældigt og udregne summen af talrækken. Programmet skal gentage operationen 4999 gange, og så oplyse til brugeren hvor stor en del af de dannede talrækker der har en større sum end den oprindelige. Det hele er led i en statistisk randomiserings test.
Jeg har siddet med det et stykke tid, og synes det lader til at problemet ligger i den algoritme der skifter fortegn på tallene i talrækken. Den ser sådan ud:
const int permutationer = 4999;
srand((unsigned)time(0));
for (int j = 0; j!= permutationer; j++)
{
for (vector<double>::iterator i = differences.begin(); i != differences.end(); i++)
if (rand()/RAND_MAX > 0.5)
*i *= -1;
S = stat(differences);
if (S >= Sref) count++;
ranDist.push_back(S);
}
double P;
P = count/5000; // giver den one-sidede værdi
cout << "Sandsynligheden for at faa en stoerre forskel er: " << setprecision(5) << P << " paa en one-sided test" << endl
<< "Det vil altsaa sige: " << P*2 << " paa en two-sided test" << endl;
Når jeg kører programmet giver den værdien 0 for P i de fleste tilfælde, men i enkelte tilfælde værdien 1. Der er ikke tale om malplaceret afrunding, det er den numeriske værdi 0 eller 1.
Har I nogle forslag der kan hjælpe mig? Det ville være rigtig fedt!!
ps: hele programmet ligger her, hvis nu det skulle vise sig den reelle fejl lå andetsteds:
#include <iostream> //for std::cout<< og std::cin>>
#include <vector> //for std::vector<double>
#include <iterator> //for std::vector<double>::iterator
#include <fstream> //for std::ofstream
#include <algorithm> //for std::copy()
#include <cstdlib> //for std::rand() og std::srand()
#include <ctime> //for std::time()
#include <iomanip> //for std::setprecision()
using std::cout; using std::cin;
using std::endl; using std::vector;
using std::iterator; using std::ofstream;
using std::copy; using std::rand;
using std::setprecision; using std::srand;
double sum (vector<double>);
double stat (vector<double> y) {return sum(y);} // man kan udregne en anden statistic, men her lader jeg det være summen
int main()
{
double x;
vector<double> differences;
cout << "Input forskelle, afslut med Ctrl+Z" << endl;
while (cin >> x)
differences.push_back(x);
double S = 0;
double Sref = stat(differences);
int count = 0;
vector<double> ranDist;
const int permutationer = 4999;
ranDist.push_back(Sref); // include the original sample in the randomization distribution
count++; // and count it
srand((unsigned)time(0));
for (int j = 0; j!= permutationer; j++)
{
for (vector<double>::iterator i = differences.begin(); i != differences.end(); i++)
if (rand()/RAND_MAX > 0.5)
*i *= -1;
S = stat(differences);
if (S >= Sref) count++;
ranDist.push_back(S); //kan jeg gøre et eller andet for at komme uden om gentagelsen i linie 34-35?
}
double P;
P = count/5000; // giver den one-sidede værdi
//ofstream gemDist("Randomiseringsdistribution.xls");
//copy(allPermutations.begin(),allPermutations.end(), gemDist); //Det her venter vi lige med
cout << "Sandsynligheden for at faa en stoerre forskel er: " << setprecision(5) << P << " paa en one-sided test" << endl
<< "Det vil altsaa sige: " << P*2 << " paa en two-sided test" << endl;
// cout << "Den totale distribution ligger i filen \\" Randomiseringsdistribution.xls\\" i mappen" << endl;
system("PAUSE");
return EXIT_SUCCESS;
}
double sum (vector<double> x)
{
double s = 0;
for (vector<double>::iterator i = x.begin(); i != x.end(); i++)
s += *i;
return s;
}
Indlæg senest redigeret d. 08.03.2007 10:44 af Bruger #8249