ich versuch schon seit geraumer Zeit gleichverteilte Zufallszahlen zu erzeugen um damit endlich ein paar Primzahlen zu finden. Doch leider ist es anscheinend nicht sehr leicht, oder kann man ein Transistorrauschen nachahmen?
Ich kenne die Funktion rand(), welche aber nur Pseudozufallszahlen erzeugt, zudem gibt es ja srand(), doch das krieg ich nicht zum laufen
Aber, ich habe in einen schlauen Buch eine Klasse gefunden zum erzeugen von Zufallszahlen, hab aber noch nie mit Klassen gearbeitet und weis daher nicht wie man die richtig in einen Code einbaut. Das Ding sah\sieht so aus:
Code:
#include <iostream.h>
#include <stdlib.h>
#include <math.h>
#include <utility>
#include <map>
class Randint
{
unsigned long randx;
public:
Randint (long s=0)
{
randx=s;
}
void seed (long s)
{
randx=s;
}
long abs (long x)
{
return x&0x7fffffff;
}
static double max()
{
return 2147483648.0;
}
long draw()
{
return randx=randx*1103515245+12345;
}
double fdraw()
{
return abs(draw())/max();
}
long operator()()
{
return abs(draw());
};
};
class Urand : public Randint
{
long n;
public:
Urand (long nn)
{
n=nn;
}
long operator()()
{
long r=n*fdraw();
return (r==n) ? n-1 : r;
}
};
class Erand : public Randint
{
long mittelwert;
public:
Erand (long m)
{
mittelwert=m;
}
long operator()()
{
return -mittelwert*log((max()-draw())/max()+.5);
}
};
int main()
{
Urand draw(10);
map<int,int> eimer;
for(int i=0; i<1000000;i++) eimer[draw()]++;
for(int j=0; j<10;j++) cout<<eimer[j]<<endl;
cin.get();
};
Hoffe ich hab keine Tippfehler beim abschrieben aus den Buch gemacht. Auf jedenfall macht er dies beim kompilieren nicht. Verwende microsoft visual C++ 6.0
Stell mal meinen Code rein, den ich bis jetzt geschafft habe, aber er spuckt als Zufallszahl immer nur die 1 raus?
int Zufallszahl(int n)
{
/*
int zufall=(double(srand(time(NULL)))/RAND_MAX )*n;
*/
srand(time(NULL));
int zufall=rand()%n;
cout<<"Zufall rand()="<<zufall<<endl;
if(zufall==0)
{
zufall=1;
return zufall;
}
else
{
return zufall;
};
return 0;
}
wenn du sagst, dass du immer ne 1 als Zufallzahl bekommst, heisst das, dass die 1. if-Abfrage immer erfüllt ist und damit "zufall == 0" ist, da du zufall als modulo von der rand()-zahl und einer Zahl n nimmst und es sehr unwahrscheinlich ist, dass n "zufällig" immer dieselbe Zahl ist, die auch rand() erzeugt, schliesse ich daraus, dass rand() immer auch 0 liefert, da ja 0 % n immer Null liefern wird
leider kenne ich mich mit zufallszahlen nicht so aus, habe sie wenn dann nur unter Delphi verwendet, da allerdings gab es sowas wie ne Initialisierungsfunktion, die du aufrufen musstest, damit die eigentlich rand-funktion auch zufallszahlen ermittelte, sonst kam immer das raus, was du grad beschrieben hast, der grund hierfür war, dass man den Zahlenbereich einschränken konnte und die Initialisierung die Systemzeit ermittelte, kannst ja mal schauen, ob man bei rand() in C sowas auch braucht.
hab mal deinen Code überflogen und wundere mich, dass der überhaupt kompiliert wird, denn soweit ich das richtig verstanden habe, definierst du ja hier ein Array
Zitat:
int Zufallszahlen[Versuche_Gesamt];
und Versuche_Gesamt hat den Wert 7, also hat das Array ja die Indizies 0...6 und in der ersten for scheife willst du es ja mit Nullen vorbelegen, dabei weist du mit h=1 den ersten Index als "1" für das Array, lässt aber bis "7" zählen, da aber das Array keinen 7te Index hat, sollte es hier zu ner Veletzung kommen und der kompiler sollte da meckern, hmm komisch komisch
Ja das mit dem Array war so mein letzter noch nicht ausgebauter Gedanke, wollte einfach ein paar Zahlen generieren und diese in einen Array auslagern und wenn ich eine bräuchte hätte ich eine da raus genommen. Hab es jetzt aber auch hin bekommen und zwar so Zeile 6:
Code:
for(Primzahl_Frage;Primzahl_Frage<Primzahl_Test_Gesamt_n;Primzahl_Frage++)
{
int h=1;
while(Versuche_k<=Versuche_Gesamt||Zeugen_nicht_Primzahl_a<=(Primzahl_Frage-1)*0.5)
{
Zufallszahl_z=rand()%(Primzahl_Frage - 1)+1;
cout<<Zufallszahl_z<<"=Zufall Zeile 56"<<endl;
if(ggT(Zufallszahl_z,Primzahl_Frage)==1)
{
cout<<"ggT=1 von z und n; Zeile 58"<<endl;
Versuche_k++;
}
else
{
cout<<"ggT>1 von z und n; Zeile 63"<<endl;
Zeugen_nicht_Primzahl_a++;
};
cout<<"Runde vorbei Zeile 66"<<endl;
h++;
};
if(Versuche_k>=Versuche_Gesamt)
{
cout<<Primzahl_Frage<<" ist eine Primzahl"<<endl;
};
if(Zeugen_nicht_Primzahl_a>=(Primzahl_Frage-1)*0.5)
{
cout<<Primzahl_Frage<<" ist keine Primzahl"<<endl;
};
};
Es klappt zwar noch nicht das Hauptproblem mit den Primzahlen, aber das dürfte denk ich kein Problem mehr sein.
Wenn wir schon mal bei Array´s sind, kannst du mir vielleicht erklären warum es bei folgenden Ding zu einen Stack Overflow kommt:
Code:
void main()
{
int Zahl[260000],j=0,o=2,Max=30,Min=0;
for(int k=Min;k<Max;k++) // Zahlen einlesen lassen
{
Zahl[k]=k+2;
};
cout<<"Mit Enter Primzahlen ausgeben lassen"<<endl;
cin.get();
clock_t t1,t2;
t1=clock();
while(j<Max*0.5) // Hauptschleife zur Prüfung ob die letzte Zahl!=0 kleiner Max/2 ist
{
for(int i=2;i<sqrt(Max);i++)
{
for(j=i-2;j<Max;j=j+i)
{
Zahl[j]=0;
};
};
};
cout<<2<<endl;
cout<<3<<endl;
for(int u=0;u<Max;u++) // Zahlen die noch ungleich 0 sind auf dem Bildschirm ausgeben
{
if(Zahl[u]!=0)
{
cout<<Zahl[u]<<endl;
};
};
t2=clock();
float tdiff=(float)(t2-t1)/CLOCKS_PER_SEC; // Dauer des Algo´s ausgeben:)
cout<<tdiff<<endl;
cin.get();
};
Ich kann es nur daran erklären, dass das Array einfach überfüllt ist, aber bei anderen Programmen wie Matlab kann ich Array erstellen die um einiges größer sind, warum?
In das Array werden dann nur die Zahlen von 2-260000 eingetragen und auf Primeigenschaften getestet. Weis selbst leider nicht ob Zahlen solcher größe mehr als 64k nehmen. Ändert sich das wenn ich ein double Array nehme?
das amcht dein compiler?
hinter die for schleife kommte keine semmel
was soll dasüberhaupt machen?
das schreibt in ein 260000 felder array. 30 werte?von 2 bis 31? oder steh ich jetzt aufm schlauch?
while(j<Max*0.5) // Hauptschleife zur Prüfung ob die letzte Zahl!=0 kleiner Max/2 ist
{
for(int i=2;i<sqrt(Max);i++)
{
for(j=i-2;j<Max;j=j+i)
{
Zahl[j]=0;
};
};
};
was machst du da?
j=i-2 ok aber j=j+i?!? hö? was hat das fürn nen sinn? warum so viele schleifen?
da sind auch ganz viele semikolonne.n vergelcuih ist da nirgends
while(j<Max*0.5) // Hauptschleife zur Prüfung ob die letzte Zahl!=0 kleiner Max/2 ist
{
for(long i=2;i<sqrt(Max);i++)
{
for(j=i-2;j<Max;j=j+i)
{
Zahl[j]=0;
}
}
};
Dies ist das Prinzip des Siebes von Erasthosthenes. Man nimmt zum Beispiel die 2( ist Primzahl) und markiert alle echten Vielfachen davon( in meinen Fall mit 0 markiert) und dies bewerkstelligen die 2 Schleifen. Bin halt nen Semmi-Fan, der Compiler meckert nicht wenn se da sind oder nicht, außer bei denen wo wirklich eins hin muss
Hatte ja auch mal die Idee, das Array einfach mit weiteren Zahlen zu überschrieben mit "Min=Max und Max=2*Max"( im Code hätte ich nur k varieren müssen), aber da macht das Sieb nicht mehr mit.
Um vielleicht mal die Dimensionen der Menge an Zahlen zu verdeutlichen, mit einen andern Code bekam ich innerhalb von 30min alle Primzahlen zwischen 2 und 100.000.000 raus. Mittels Siebes könnt dies auf 10min schrumpfen oder noch stärker.
ja dann solltest du das arra yuahc als long deklarieren!
int kann nur bis 64k oder bin ich jetzt in der falschen programmiersprache sorry ich hab in letzter zeit einige durch
int ist abhängig vom OS und bei neuen 32Bit Rechnern ist int = long, also von 2,... milliarden bis -2,... milliarden
wobei ich mir aber nicht sicher bin, ist ob du wirklich ein array mit 260000 Felder erstellen kannst, denn ob du int, long, double davor schreibst ist egal, denn das sollte ja nur den Typ der Felder angeben, also den der Inhalt eines einzelnen Feldes hat
probier mal statt 260000 zum test mal nur 1000 oder so zu nehmen, wenns kompiliert dann haben wir den übeltäter, dann musste wohl leider mit mehreren Feldern arbeiten...
Bei niedrigeren Werten funktioniert ja das Ganze, bloß das Komische ist, dass z.B. in Matlab ein Array erstellt wird was um einieges größer ist, darum frag ich mich ja warum es nicht geht?
du könntest auch ne Matrix der form Array [512][512] erstellen, das wären dann 262144 felder und kompilierbar sollte das auch sein, nur würde dann deine schleifen noch ein wenig komplizierter werden
Ich hatte auch an Vektoren gedacht, doch als ich dann den Aufwand sah solch ein Vektor richtig zu handhaben, war erstmal schluss. In nen Buch war ein Weg über ne klasse gezeigt wurden am Beispiel eines Telefonbuches, ließe sich bestimmt auch hierauf übertragen, aber hab halt noch nie mit klassen gearbeitet.
Und 262144 Felder, sind halt immernoch nicht das wahre, wenn es aber nun gar nicht mehr klappen sollte hab ich zum Glück noch nen anderes System zum finden von Primzahlen auf´n Tisch. Blos ist dies noch von der mathematischen Seite her nicht sehr leicht zu verstehen.
Aber vielleicht kommt ja BomberD mit ner Klasse Idee noch um das Ganze auszutricksen