Philip H Geschrieben 20. März 2012 Geschrieben 20. März 2012 Hallo alle zusammen Ich hoffe mal, dass es hier im Frorum ein paar Programmierer gibt, die sich mit C# auskennen. Ich programmiere nun seit einigen Wochen mit C#. Nun habe ich schon einige kleine Programme erstellt. Nun habe ich das Problem, dass ich bei meinem neuen Programm nicht weiss, wie ich das alles machen kann. Mein Programm: Wir haben heute in der Schule auf dem Taschenrechner in Mathe ein Programm geschrieben, welches PI nach der Monte-Carlo-Mehtode berechned. Um einen genauen Wert für PI zu erhalten braucht der Rechner allerdings etwa drei bis vier Stunden, da er etwa 150000-200000 Punkte generieren und überprüfen muss. Nun will ich das gleiche in C# programmieren. Wie kann ich die Folgenden Schritte programmieren?: - Berechnen von zwei Zufalszahlen - Überprüfen der Zahlen (auf dem rechner: if; y>wurzel(1-x^2); variable +1) - berechnen von Pi (Pi= (4*variable1)/variable2) - Anzeigen von Pi, beim rechner geht das mit " displ variable_x) Für eure Hilfe und Antworten möchte ich mich schon im Voraus recht herzlich bedanken. Mit freundlichen Grüssen Philip Helbling Zitieren
sirdir Geschrieben 20. März 2012 Geschrieben 20. März 2012 Hi!Ich hab die Tage gerade mal wieder damit begonnen Objective C zu lernen. Ist zwar nicht C# aber auf dem Level dürfte allenfalls die Zufallszahl anders zu berechnen sein, der Rest ist sicher gleich. Ich hab ne Implementation in Pascal gefunden (ich versteh nicht ganz wie das mit dem Pi berechnen geht) und das mehr oder weniger nach C umgeschrieben. Das mit dem random hab ich hingepfuscht und die Abbruchbedinung ist auch nicht so sauber... Habe auch noch ein bisschen mit long double rumgespielt aber grössere Genauigkeit scheint mir auch nicht raus zu kommen. Vielleicht hab ich auch was falsch gemacht weil ich nicht so ganz schnalle was ich da eigentlich mache ;) Vielleicht hilft's ja: // // main.m // montecarlo // // Created by Patrick Kormann on 20.03.12. // Copyright (c) 2012 __MyCompanyName__. All rights reserved. // #import <Foundation/Foundation.h> int main(int argc, const char * argv[]) { // @autoreleasepool { // double cPi = 3.1415926535897931; //Pi int i; //Counter long int n = 10; // Number of generated points long int m = 0; //Number of points inside circle double x, y; // Point (x,y) // int r = 1; //Radius of circle double pi; // pi we're going to calculate int counter = 1; // "n = 10^ ..." counter do { m=0; for (i = 0; i<= n; i++){ x=(arc4random()%1000000)/1000000.00; y=(arc4random()%1000000)/1000000.00; if (x*x + y*y <= 1) { // eigentlich <= r^2 aber 1^2 ist 1... //Add one to m (number of points inside circle) m += 1; } } pi = 4.0 * ((float)m / (float)n); //Write the number of points (n), and the result (pi): printf("n=%li = 10^%i, Pi = %f\n",n,counter,pi ); //Make number of points 10 times larger n = n * 10; //Make " n = 10^ ..." counter larger counter += 1; } while ( (int)(100000*pi) != 314159); // } return 0; } Zitieren
Lawnmower Geschrieben 21. März 2012 Geschrieben 21. März 2012 Hoi Patrick C# ist eine tolle Programmiersprache und wird dir sicher noch viel Freude machen! Ich würde dir empfehlen ein Tutorial im Netz zu suchen damit du einen ersten Einstieg hast. Es gibt auch gute Bücher auf Deutsch im Netz zu finden, z.B. http://openbook.galileocomputing.de/csharp/. Hier noch ein paar Tipps zu deinen Fragen: - Berechnen von zwei Zufalszahlen Zuerst brauchst du einen Zufallszahlengenerator. C# stellt dafür die Klasse Random zur Verfügung. den Zufallszahlengenerator kannst du so erstellen: Random zufallsgenerator = new Random(); damit kannst du nun zufällige Zahlen generieren: double x = zufallsgenerator.NextDouble(); double y = zufallsgenerator.NextDouble(); die Methode NextDouble() liefert eine Zahl zwischen 0.0 (inklusive) und 1.0 (exklusive). - Überprüfen der Zahlen (auf dem rechner: if; y>wurzel(1-x^2); variable +1) Wenn du eine (oder mehrere) Anweisungen nur in bestimmten Situationen ausführen willst, brauchst du ein "if" Block. Der sieht immer so aus: if (bedingung){ Anweisungen die nur ausgeführt werden wenn 'bedingung' erfüllt ist. } In deinem Fall: if (y > Math.Sqrt(1-x*x)){ variable++; // wird nur ausgeführt wenn (x,y) ausserhalb des Einheitskreises. } Hier wird die Sqrt Methode von der Klasse Math verwendet um die Quadratwurzel zu berechnen. - berechnen von Pi (Pi= (4*variable1)/variable2) double pi = (4 * variable1) / variable2; - Anzeigen von Pi, beim rechner geht das mit " displ variable_x) Um etwas auf der Konsole auszugeben kannst du Console.Out.WriteLine("PI ist etwa: " + pi); verwenden. Für die nicht MC-geschädigten unter den Lesern: Die Methode schätzt die Fläche des Einheitskreises (Kreis mit Radius 1 mit Zentrum im Koordinatenursprung) im ersten Quadrant (90° Pizzastück oben rechts). Da man weiss dass die Fläche des Einheitskreises PI ist (Kreisfläche = Radius^2*PI), kann man die geschätzte Fläche des Quadranten mal 4 rechnen und kriegt eine Schätzung für PI raus. Die Schätzung ist der Schlüssel zur Methode. Es werden zufällige Punkte mit x und y im Bereich 0 bis 1 generiert (also innerhalb des Rechteckes das den Quadranten umschliest). Für jeden Punkt wird nun geprüft ob er im Kreis liegt. Die Anzahl Punkte die im Kreis landen dividiert durch die totale Anzahl der Punkte gibt eine Schätzung des Flächenverhältnisses des Kreisquadranten zum Rechteck. Da die Rechtecksfläche 1 ist, entspricht das gerade der Kreisquadrantenfläche. Das ist natürlich eine sehr ineffizente Art um PI zu berechnen (man braucht enorm viele Punkte um ein paar Ziffern nach dem Komma richtig zu kriegen), aber Mathematisch elegant. Und es gibt durchaus Anwendungen wo solche Methoden benutzt werden. Z.B. um die Fläche von sehr komplexen Formen zu schätzen. P.S. du kannst dein Programm (vermutlich auch im TR) schneller machen wenn du anstatt y > Math.Sqrt(1-x*x) einfach y*y > 1-x*x verwendest (ich habe einfach auf beiden Seiten quadriert). Multiplizieren ist typischerweise sehr viel schneller als Wurzelziehen. Kenne deinen TR nicht, aber oft ist es auch schneller x*x zu schreiben als x^2. grues Stefan Zitieren
Philip H Geschrieben 21. März 2012 Autor Geschrieben 21. März 2012 Vielen Dank für die Antworten. Die haben mir sehr geholfen.:) Mit freundlichen Grüssen Philip Helbling Zitieren
Philip H Geschrieben 21. März 2012 Autor Geschrieben 21. März 2012 Hallo Ich hab das ganze bei mir mal so ausprobiert, wie es in den Antworten steht. Wenn ich nun eine Schleife einbauen will < for n(i = 0; i < 1000; i++ > kommt immer eine Fehlermeldung mit der Meldung: "The name 'i' does not exist in the current context" Was ja so viel bedeutet, wie der Befehl " i " so nicht verwendet werden kann. ich habe das Programm "Microsoft Visula C#", aber auf Englisch, wie kann ich dort die Zufallszahlen dort generieren?, wenn ich die Befehle vom Deutschen ins Englische übersetzte gibt es immer eine Fehlermeldung. Mit freundlichen Grüssen Philip helbling Zitieren
Pogo Geschrieben 21. März 2012 Geschrieben 21. März 2012 Kenne zwar C# nicht, dafür ein bisschen C++. Dort musst Du die Variable noch deklarieren, sonst weiss das System ja nicht was damit gemeint ist. Also z.B. for(int i = 0; i < 1000; i++) { ..... } Gruss Martin Zitieren
Philip H Geschrieben 21. März 2012 Autor Geschrieben 21. März 2012 Bei dem Folgenden Befehl gibt es leider immernoch Probleme: "double x = zufallsgenerator.NextDouble(); double y = zufallsgenerator.NextDouble(); " Das Wort " zufallsgenerator " wird als Fehler angezeigt. Was muss ich anstelle von zufallsgenerator eingeben? Mit freundlichen Grüssen Philip Helbling Zitieren
dschaedl Geschrieben 21. März 2012 Geschrieben 21. März 2012 Bei dem Folgenden Befehl gibt es leider immernoch Probleme:"double x = zufallsgenerator.NextDouble(); double y = zufallsgenerator.NextDouble(); " Das Wort " zufallsgenerator " wird als Fehler angezeigt. Was muss ich anstelle von zufallsgenerator eingeben? Mit freundlichen Grüssen Philip Helbling hast du ihn denn auch instanziiert wie von Stefan beschrieben? Random zufallsgenerator = new Random(); Zitieren
Philip H Geschrieben 21. März 2012 Autor Geschrieben 21. März 2012 hast du ihn denn auch instanziiert wie von Stefan beschrieben?Random zufallsgenerator = new Random(); Ja, dieser Teil funktioniert, aber der zweite Teil dieses Befehles, mit x/y funktioniert nicht. Zitieren
Lawnmower Geschrieben 23. März 2012 Geschrieben 23. März 2012 Zeig uns doch mal den Code den du bis jetzt hast. Dann finden wir das Problem schon. grues Stefan Zitieren
Empfohlene Beiträge
Dein Kommentar
Du kannst jetzt schreiben und Dich später registrieren. Wenn Du ein Konto hast, melde Dich jetzt an, um unter Deinem Benutzernamen zu schreiben.