Pi berechnen mit Monte Carlo Methode

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
Gipsyjack
User
Beiträge: 23
Registriert: Samstag 13. November 2010, 20:19

Hallo, wie gesagt ich sollte mit Python Pi berechnen mit der Monte Carlo Methode,
hab im Inet auch schon tausende Sachen gefunden wollts aber net abschreiben sondern selbst was mache, jedoch komme ich jetzt nicht mehr weiter irgendwo muss ein fehler sein ich weiß aber nicht wo, hoffe Ihr könnt mir helfen:

Code: Alles auswählen

#!/usr/bin/python

# Berechnen von Pi via Monte-Carlo

from random import random

maxsteps = 100000

step = 0
sum = 0

while step < maxsteps:

	x = random()

	y = random()
	
	if x*x+y*y < 1:
	
		sum = sum + 1

step = step + 1

estimate = 4 * sum / maxsteps

print "Abschaetzung fuer pi nach",step,"Schritten:",estimate
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Hallo Gipsyjack,

bitte benutze doch die speziellen Python-Code-Tags für Deinen Quellcode - das liest sich besser :-) Außerdem könntest Du dann noch die vielen Leerzeilen entfernen; das liest sich so nicht wirklich besser, eher schlechter.

Zur Frage: Bitte poste doch mal die Fehlermeldung bzw. erkläre, was nicht so funktioniert, wie Du es Dir vorstellst.

In diesem Falle solltest Du Dir mal die Einrückung von

Code: Alles auswählen

step = step + 1
angucken ;-)

Das kann man übrigens so kürzer schreiben:

Code: Alles auswählen

step += 1
Da Du die exakte Anzahl an Durchläufen der Schleife kennst, solltest Du hier besser auf eine for-Schleife zurückgreifen:

Code: Alles auswählen

for _ in xrange(10000):
    pass
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
Benutzeravatar
numerix
User
Beiträge: 2696
Registriert: Montag 11. Juni 2007, 15:09

Denk mal darüber nach:

Code: Alles auswählen

>>> 22/7
3
Gipsyjack
User
Beiträge: 23
Registriert: Samstag 13. November 2010, 20:19

Hallo, danke mal für die Hilfe soweit,
ok das mit den Leerzeichen werde ich beachten genauso wie das step +=1

Fehler gibt es nicht wirklich einen ich lass es in der shell (Ubuntu 10.10; bash) laufen und es passiert einfach nichts...

es wurde gesagt es soll mit einer if schleife gemacht werden, um auch die gneuigkeit zu überprüfen wenn man es mit mehrer werten macht

weil dann ändert sich die variable ja nur in maxsteps = input, hab das mal weggelassen


wegen der Division, muss dann schreiben: 4.0 * sum / maxsteps

weil sonst werden ja nur ganze zahlen ausgegeben oder?
Benutzeravatar
numerix
User
Beiträge: 2696
Registriert: Montag 11. Juni 2007, 15:09

Gipsyjack hat geschrieben:es wurde gesagt es soll mit einer if schleife gemacht werden
Eine meiner Lieblingsseiten im Netz: http://www.if-schleife.de/

Wie Hyperion schon sagte: Die Einrückung stimmt so nicht. Dein Programm macht nicht nichts, es macht und macht und macht ... aber es kommt nicht am Ende an.
Gipsyjack hat geschrieben:wegen der Division, muss dann schreiben: 4.0 * sum / maxsteps
Einen Schritt bist du schonmal weiter.
nomnom
User
Beiträge: 487
Registriert: Mittwoch 19. Mai 2010, 16:25

Gipsyjack hat geschrieben:Hallo, danke mal für die Hilfe soweit,
ok das mit den Leerzeichen werde ich beachten genauso wie das step +=1

Fehler gibt es nicht wirklich einen ich lass es in der shell (Ubuntu 10.10; bash) laufen und es passiert einfach nichts...
Kein Wunder :mrgreen: Du hast da ne `while`-Schleife, die niemals endet (du erhöhst step ja nicht im Loop!)
EDIT: Mist, numerix war schneller
Gipsyjack
User
Beiträge: 23
Registriert: Samstag 13. November 2010, 20:19

Ok danke an alle für die nette und schnelle Hilfe!

funktioniert einwandfrei :)

Kann mir jemand noch vllt ein gutes Buch empfehlen, wo wirklich NUR die Grundlagen erläutert werden, werd mich Leider net allzu sehr mit Python beschäftigen denk ich hab aber leider nur ein Skript dem ich folgen kann... hätte halt noch gern n Buch zum nachschlagen.


MfG und schönes WE noch!!
Benutzeravatar
numerix
User
Beiträge: 2696
Registriert: Montag 11. Juni 2007, 15:09

Gipsyjack hat geschrieben:Kann mir jemand noch vllt ein gutes Buch empfehlen, wo wirklich NUR die Grundlagen erläutert werden, werd mich Leider net allzu sehr mit Python beschäftigen denk ich hab aber leider nur ein Skript dem ich folgen kann... hätte halt noch gern n Buch zum nachschlagen.
Ich verstehe nicht, was du willst. WILLST du dich mich Python beschäftigen oder MUSST du und WILLST NICHT? Willst du etwas lernen oder geht es dir darum, irgendwie die Aufgaben, die dir irgendjemand stellt und die du für irgendetwas brauchst, lösen zu können und das möglichst schnell hinter dich zu bringen? Falls letzteres der Fall ist, nützt dir ein Buch wohl nichts, denn ohne ernsthafte Lektüre bringt es nix.
Benutzeravatar
/me
User
Beiträge: 3555
Registriert: Donnerstag 25. Juni 2009, 14:40
Wohnort: Bonn

Gipsyjack hat geschrieben:Kann mir jemand noch vllt ein gutes Buch empfehlen, wo wirklich NUR die Grundlagen erläutert werden, werd mich Leider net allzu sehr mit Python beschäftigen denk ich hab aber leider nur ein Skript dem ich folgen kann... hätte halt noch gern n Buch zum nachschlagen.
Ein Buch habe ich jetzt nicht im Angebot, aber die offizielle Python-Dokumentation. Für Basiswissen empfiehlt sich da erst einmal das Durcharbeiten des angebotenen Tutorials.
Gipsyjack
User
Beiträge: 23
Registriert: Samstag 13. November 2010, 20:19

Was ich genau will, weiß ich noch nicht werd dieses Semester noch 2 andere Programmiersprachen "anschneiden", ich möchte aber trotzdem über das geforderte hinaus etwas lernen, weil so wie das gemacht wird ist es nichts halbes und nichts ganzes.

Was ich suche ist ein Buch das wirklich nur die Basics vermittelt, die Python Dokumentation werd ich mir mal anschauen, danke dafür.

Ich mein wir haben innerhalb von 4 Wochen die Linux Grundlagen gemacht, wobei ich denke das man das nicht Grundlagen nennen kann, hab mir da auch noch Literatur besorgt, aber ich will nicht schon wieder 'n Batzen mit 1000 oder mehr Seiten haben...
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Dann ist das offizielle Tutorial wohl genau das richtige für Dich! Dort werden vor allem die Basics angesprochen und vermittelt, etwa die grundlegenden Kontrollstrukturen und die wichtigsten grundlegenden Datenstrukturen. Auch fortgeschrittenere Themen werden dort behandelt; um diese komplett zu durchdringen ist es aber vermutlich ein wenig "knapp". Aber laut Deinen Aussagen sollte das ideal für Dich sein.
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
Gipsyjack
User
Beiträge: 23
Registriert: Samstag 13. November 2010, 20:19

Mit offizielles Tutorial ist dieses hier gemeint http://docs.python.org/tutorial/ oder?

Danke für die Antworten soweit.


Habe allerdings nochmal eine Frage und will keinen neuen Thread aufmachen.
Wollte zur genaueren Bestimmung von pi und um allgemein Flächeninhalte unter Kurven auszurechnen das Skript verbessern.
ich will in n-Schritten ein gleichmäßiges Gitter ziehen und dann die Funktionswerte aufberechnen, jedoch schaff ich das nicht die Funktionswerte aufzurechnen bei mir kommt immer die Anzahl der Schritte als ergebnis raus.

Code: Alles auswählen

#!/usr/bin/python

from random import random
import math

maxsteps = 1000000

step = 0
sum = 0
i=0

while step < maxsteps :

	x = 0+step/maxsteps
	y = math.sqrt(1-(x*x))
	
	step = step + 1
	i += y

	if x*x+y*y<= 1:
    
		sum += y
		


estimate = sum

print "Abschaetzung fuer pi nach ",step,"Schritten:",estimate

hoffe ihr könnt mir nochmal helfen :)
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Wieso nutzt Du immer noch eine for-Schleife?

Schau Dir doch noch mal die Hinweise zur Division an!

Was soll das "i" bezwecken?
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
Gipsyjack
User
Beiträge: 23
Registriert: Samstag 13. November 2010, 20:19

Eine Division brauche ich doch nicht da ich alle Werte einfach nur aufsummiere, etwas anderes macht doch eine Integration auch nicht oder?

Und wenn ich das mit einer for schleife mache, wie kreig ich es dann hin das er die x gleichmäßig macht?

Code: Alles auswählen

#!/usr/bin/python

from random import random
import math

maxsteps =1000000
sum = 0
i=0
step=0

for i in range(0,1000000):

	x = 0+step/maxsteps
	y = math.sqrt(1-(x*x))
	
	step = step + 1

	if x*x+y*y<= 1:
    
		sum = sum + 1
		


estimate = 4.0*sum/maxsteps

print "Abschaetzung fuer pi nach ",maxsteps,"Schritten:",estimate

habs jetz soweit aber es kommt wieder nur 4.0*1 raus...
ich blicks grad auf keinem Auge mehr ...

EDIT: i sollte als variable sein, welches die summe repräsentiert der aufgezählten Funktionswerte
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

In der Zeile wo Du x berechnest steht doch eine Division!

Was meinst Du mit "gleichmäßig"?

range() startet immer bei "0", den Startparameter kannst Du damit weglassen.
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
BlackJack

@Gipsyjack: Lass Dir doch einfach mal `sum` und `maxsteps` ausgeben. Dann sollte klar sein, warum da 4 heraus kommt.

Edit: Falls Du `x` und `x` gleichmässig statt zuvällig über die Fläche verteilen wolltest, dann ginge das zum Beispiel so:

Code: Alles auswählen

#!/usr/bin/python
# -*- coding: utf-8 -*-
from math import sqrt
from random import random

max_steps = 1000000
steps_per_dimension = int(sqrt(max_steps))
hits = 0
for i in xrange(steps_per_dimension):
    for j in xrange(steps_per_dimension):
        x = 1.0 / steps_per_dimension * i
        y = 1.0 / steps_per_dimension * j
        if x * x + y * y <= 1:
            hits += 1

estimation = 4.0 * hits / steps_per_dimension**2

print 'Abschaetzung fuer pi nach ', steps_per_dimension**2, 'Schritten:', estimation
Gipsyjack
User
Beiträge: 23
Registriert: Samstag 13. November 2010, 20:19

ich weiß sum ist die anzahl an schritten die gemacht wurden und maxsteps auch als 1/1 =1
range wurde auch verbessert in:

Code: Alles auswählen

for i in range(1000000):
hab das mit der division gemacht also einfach:

Code: Alles auswählen

	x = 0.0+step/maxsteps
aber wie kriege ich es jetzt hin das die Ergebnisse aufsummiert werden?
Benutzeravatar
/me
User
Beiträge: 3555
Registriert: Donnerstag 25. Juni 2009, 14:40
Wohnort: Bonn

Gipsyjack hat geschrieben:hab das mit der division gemacht also einfach:

Code: Alles auswählen

	x = 0.0+step/maxsteps
aber wie kriege ich es jetzt hin das die Ergebnisse aufsummiert werden?
Zuerst einmal eine Anmerkung zum vorher gezeigten Code. Du solltest besser keinen Bezeichner mit dem Namen sum verwenden. sum() ist bereits eine eingebaute Funktion und wird damit überschrieben. Verwende doch einfach estimate, schließlich ist das der Bezeichner, dem du hinterher ohnehin dein sum zuweist.

Dein konkretes Problem hier liegt darin, dass du den Tipp mit den testweisen print-Ausgaben nicht beherzigt hast. In dem Fall wäre dir nämlich etwas sehr interessantes aufgefallen. Vielleicht mal als kurzer und knapper Hinweis:

Code: Alles auswählen

print 1/2
Was erwartest du als Ergebnis? Was stellst du fest, wenn du es laufen lässt?
Benutzeravatar
mkesper
User
Beiträge: 919
Registriert: Montag 20. November 2006, 15:48
Wohnort: formerly known as mkallas
Kontaktdaten:

Damit man nicht immer auf die merkwürdige Division achten muss, empfiehlt sich ein

Code: Alles auswählen

from __future__ import division
am Beginn des Codes.
Gipsyjack
User
Beiträge: 23
Registriert: Samstag 13. November 2010, 20:19

Hallo,

Entschuldigung, dass ich ich mich vorher nicht gemeldet hatte. Hatte ne anstrengede Woche und nicht wirklich Zeit gefunden.
Nochmal danke für die Hilfe an alle!!

wollte nochmal meine Endgültige Lösung posten:

Code: Alles auswählen

#!/usr/bin/python

from random import random
import math

maxsteps=100000
sum=0.0
step=0.0

for i in range(100000):
		x = 0.0+step/maxsteps
		y= math.sqrt(1.0-x*x)

		step= step +1.0

		sum= sum +y

estimate = 4.0*sum/maxsteps

print "Abschaetzung fuer pi nach",maxsteps,"Schritten:", estimate

MfG

und noch ein schönes WE!
Antworten