Probleme mit der Zeitmessung

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
rabenstein
User
Beiträge: 8
Registriert: Sonntag 5. Dezember 2010, 14:41

kaum bin ich da schon liefer ich probleme^^
ich hab ein skript programiert das mir die fibonacci zahlen berechnet -->funktioniert
aber: ich will jetzt die zeit für jede zahl einzelln berechnen...
dh. ich will die zahlen von n=4 bis n=17 in einem durchgang berechnen und für jeden wert die zeit einzelln messen und als tuppel mit dem ergebniss in eine liste speicher...
das problem ist nur das ich die zeitfunktion nicht richtig eingebaut bekomm^^
hoff mir kann jemand helfen

hier mal mein skript bisher:

Code: Alles auswählen

#!/usr/bin/python
import time
step = 0
m = []

def fib1(n):
	t = clock.tick()
	global step
	while step < 1000:
		if n <= 1: return 1
		return fib1(n-1)+fib1(n-2)
		return fib1(n)			
		step = step + 1
	


for i in range(4, 17):		
	fib1(i)
	u = "%i %f" %(fib1(i), t)
	m.append(u)
Zuletzt geändert von Anonymous am Sonntag 5. Dezember 2010, 15:18, insgesamt 1-mal geändert.
Grund: Quelltext in Python-Code-Tags gesetzt.
Dauerbaustelle
User
Beiträge: 996
Registriert: Mittwoch 9. Januar 2008, 13:48

Und was ist jetzt dein Problem?
rabenstein
User
Beiträge: 8
Registriert: Sonntag 5. Dezember 2010, 14:41

das mit der zeit hab ich inzwischen relativ gut gelöst...das nächste problem is das ploten weil es keine ordentliche kurve ausgibt
rabenstein
User
Beiträge: 8
Registriert: Sonntag 5. Dezember 2010, 14:41

Code: Alles auswählen

#!/usr/bin/python

import math
import timeit
import numpy as np
import matplotlib
import matplotlib.pyplot as pyplot
import time

step = 0
m=[]

while step < 10000:
        def fib1(n):
                if n <= 1: return 1
                return fib1(n-1)+fib1(n-2)
        step = step + 1
i = 4
for i in range(4, 18):
     t1 = timeit.Timer("for i in xrange(4, 17): fib1(i)", "from __main__ import fib1")
     u = t1.timer()
     m.append(u)


bild = pyplot.figure()
graph_normal = bild.add_subplot(221, title="Rechenzeit")
graph_normal.plot(fib1())
graph_normal.set_xlim(4,17)
graph_normal.set_ylim(m[0], m[16])
pyplot.show()
dabei bekomm ich keine grafik...wenn ich wenigstens wüßte in welcher zeile der fehler liegt könnte ich besser nach lösungen suchen...
Dauerbaustelle
User
Beiträge: 996
Registriert: Mittwoch 9. Januar 2008, 13:48

Ähm... sicher, dass du in einer Schleife Funktionen definieren willst?

Und: was ist das Problem genau jetzt? Magst du vielleicht nen Traceback zeigen oder sowas?
rabenstein
User
Beiträge: 8
Registriert: Sonntag 5. Dezember 2010, 14:41

ich bin totaler anfänger mit python und das is mein erster versuch was zu ploten^^

was ist das probelm wenn ich versuch deine funktion in einer schleife zu definieren? die werte die mir ausgegeben werden stimmen...

und das ploten:
ich will die kurve der funktion zeichnen aus der ersichtlich ist wie die bearbeitungszeit für jedes n ansteigt
Dauerbaustelle
User
Beiträge: 996
Registriert: Mittwoch 9. Januar 2008, 13:48

Funktionen und Hauptprogrammlogik gehören nicht zusammen. Funktionen werden im oberen Bereich eines Python-Modules definiert (ebenso Klassen, Konstanten etc).

Hauptprogrammlogik kommt drunter, mit einem

Code: Alles auswählen

if __name__ == '__main__': ...
Konstrukt.

Außerdem kostet das Definieren von Funktionen Zeit, viel Zeit. Du musst dir bewusst machen, dass jedes Mal, wenn irgendwie ein "def ...." steht, der Python-Interpreter eine *neue* Funktion erstellt. Was du also da machst ist eine Funktion erstellen, einmal benutzen, wegwerfen, und gleich darauf die gleiche Funktion wieder erstellen. Nicht besonders sinnvoll.

Abgesehen davon macht es den Code einfach unübersichtlich.

Zum Plotten: Dir wird keiner helfen können, wenn du nicht beschreibst, was *genau* dein Problem ist (Fehlermeldungen, was *genau* geht nicht). Niemand hier kann Fehler erraten, zumindest nicht solche.
BlackJack

@rabenstein: Das da die richtigen Zeiten gemessen werden, wage ich zu bezweifeln, denn Du willst ja sicher nicht 14 mal messen wie lange es dauert *alle* Fibonacci-Zahlen von 4 bis 16 zu berechnen, sondern die Zeiten für die einzelnen Zahlen vergleichen bzw. plotten.

Das ganze sieht nach wildem Rumprobieren aus, statt nach überlegtem Vorgehen. Letzteres ist beim Programmieren aber wichtig -- strukturiert an ein Problem heran zu gehen ist das Wesentliche beim Programmieren. Dazu gehört auch, dass man nicht einfach etwas so stehen lässt, was man nicht wirklich erklären kann, und einfach froh ist, dass es irgendwie schon funktioniert.

Was uns wieder zu der ``while``-Schleife bringt. Erkläre doch bitte mal was die machen soll und wie sie das erreicht.

Und die Zeile in der Du `plot()` aufrufst könntest Du auch mal erklären. Was sagt die Dokumentation was diese Methode an Argumenten erwartet und warum denkst Du dass Du diese Erwartungen erfüllst? Was übergibst Du da?
rabenstein
User
Beiträge: 8
Registriert: Sonntag 5. Dezember 2010, 14:41

so...hab das ganze heute nochmal überarbeitet und versucht eure anmerkungen umzusetzen

@BlackJack
wie gesagt ich bin anfänger mit Python. Selbstverständlich hab ich eine grundidee wie mein Programm arbeiten soll und versuch auch diese umzusetzen. aber wenn mir gesagt wird ich soll dazu time.clock() verwenden dann such ich infos zu dem modul und probiers dann eben aus was wann wie passiert...und wenn ich dabei einen fehler mach dann weiß ich nächstesmal immerhin wie es nicht geht...^^

Code: Alles auswählen

#!/usr/bin/python

import math
import matplotlib
import matplotlib.pyplot as pyplot
import time

step = 0
m=[]


def fib1(n):
	if n <= 1: return 1
	return fib1(n-1)+fib1(n-2)
n = 4
while len(m) < 14:
	if n <= 17:
		if n >= 4:
			t1 = time.clock()
			step = 0
			while step < 10000:
				g = fib1(n)
				step = step + 1
			t2 = time.clock()
			tend = t2 - t1
			m.append((n, tend))
			n = n + 1 
print m


bild = pyplot.figure()
graph_normal = bild.add_subplot(221, title="Rechenzeit")
graph_normal.plot()
graph_normal.set_xlim(4,17)
graph_normal.set_ylim(0.0000001 , 0.002 , 0.00001)
pyplot.show()
ausgabe:

Code: Alles auswählen

[(4, 0.030000000000000027), (5, 0.049999999999999989), (6, 0.07999999999999996), (7, 0.12), (8, 0.20000000000000007), (9, 0.32000000000000006), (10, 0.53999999999999981), (11, 0.85999999999999988), (12, 1.4400000000000004), (13, 2.3099999999999996), (14, 3.6899999999999995), (15, 5.8500000000000014), (16, 9.1699999999999982), (17, 14.739999999999998)]
als erklärung:

ich hab jetzt die def der funktion aus der schleife raus gezogen. über die Länge der Liste in der meine ergebnisse gespeichert werden setz ich dei grenze für meine schleife zum berechnen. Die funktion in der schleife berechnet die fib werte von 4 bis 17 jeweils 10000mal und misst jedesmal die zeit.
die zeit und der wert von n wird dann als tuppel in die Liste m gespeichert.

so die zeiten die da rauskommen erscheinen mir diesmal sehr viel realistischer als vorher^^
das ploten unten steht bis jetzt nur dran weils da sein muss...wie genau man das programiert damit es das tut es es tun soll find ich jetzt mal raus...^^
BlackJack

@rabenstein: Das sieht schon wesentlich besser aus.

Zur Formatierung: Du rückst ziemlich weit ein -- üblich sind vier Leerzeichen (kein Tab!) pro Ebene. Und eine einzelne Anweisung kann man zwar nach einem Doppelpunkt platzieren, aber es ist übersichtlicher wenn man auch dafür eine eingerückte Zeile verwendet. Das betrifft das ``return 1`` in der `fib1()`-Funktion.

Das mit der ``while``-Schleife die von der Länge von `m` abhängt und den beiden verschachtelten ``if``\s ist sehr unübersichtlich und auch fehleranfällig wenn man die Grenzen ändern möchte. Da handelt man sich schnell eine Endlosschleife ein, wenn man nicht aufpasst. Wenn man vor Eintritt in eine Schleife weiss wie oft der Schleifenkörper durchlaufen werden soll, dann ist die ``for``-Schleife das Mittel der Wahl. Das gilt ensprechend auch für die innere Schleife.

Ich würde übrigens doch zu `timeit` raten, denn die Auflösung von `time.clock()` beziehungsweise `time.time()` hängt vom System ab. Im `timeit`-Modul wird automatisch die genauere Variante gewählt.

Die `set_xlim()`/`set_ylim`-Methoden solltest Du nicht aufrufen müssen. Da werden normalerweise automatisch sinnvolle Werte für die geplotteten Daten ausgewählt.
rabenstein
User
Beiträge: 8
Registriert: Sonntag 5. Dezember 2010, 14:41

okay
danke für die tipps...mir wurde gesagt man soll sich entscheiden ob man leerzeichen oder tabs benutzt...hab mich dann für tabs entschieden weil das nicht so fehleranfällig ist...also da fällt es schneller auf wenn ich ausversehn 2 statt 1 tab benutz^^


an dem letzten schliff fürs ploten sitz ich grade noch...
soll das so ploten das es ein 4er plot gibt...also
1. den normalen
2. semilogx
3. semilogy
4. loglog

das wird mich glaub noch einen moment beschäftigen^^

aber ich bin euch schonmal sehr dankbar für eure hilfe =)
rabenstein
User
Beiträge: 8
Registriert: Sonntag 5. Dezember 2010, 14:41

so jetzt wirds lang:

Code: Alles auswählen

#!/usr/bin/python

import math
import matplotlib
import matplotlib.pyplot as pyplot
import time

step = 0
m=[]
u=[]

def fib1(n):
	if n <= 1: return 1
	return fib1(n-1)+fib1(n-2)
n = 4
while len(m) < 14:
	if n <= 17:
		if n >= 4:
			t1 = time.clock()
			step = 0
			while step < 10000:
				g = fib1(n)
				step = step + 1
			t2 = time.clock()
			tend = t2 - t1
			m.append(tend)
			n = n + 1 


def fib2(i, a=1, b=1):
    if i == 0: return a
    elif i == 1: return b
    else: return fib2(i-1, b, a+b)

i = 4
while len(u) < 37:
	if i <= 40:
		if i >= 4:
			t3 = time.clock()
			step = 0
			while step < 100000:
				y = fib2(i)
				step = step + 1
			t4 = time.clock()
			tende = t4 - t3
			u.append(tende)
			i = i + 1



bild = pyplot.figure()
graph_normal = bild.add_subplot(221, title="Rechenzeit")
graph_normal.plot(m, "g")
graph_normal.plot(u, "b")
graph_normal.set_xlim(4,41)
graph_normal.set_ylim(0.003 , 25.002 , 2.5)

graph_semilogx = bild.add_subplot(222, title="x logarithmisch")
graph_semilogx.plot(m, "g")
graph_semilogx.plot(u, "b")
graph_semilogx.set_xscale("log")
graph_semilogx.set_ylim(0.003, 20, 2.5)

graph_semilogy = bild.add_subplot(223, title="y logarithmisch")
graph_semilogy.plot(m, "g")
graph_semilogy.plot(u, "b")
graph_semilogy.set_xlim(4,41)
graph_semilogy.set_yscale("log")

graph_semilogxy = bild.add_subplot(224, title="y und x logarithmisch")
graph_semilogxy.plot(m, "g")
graph_semilogxy.plot(u, "b")
graph_semilogxy.set_xscale("log")
graph_semilogxy.set_yscale("log")

pyplot.show()
das is das endergebniss meiner arbeit

das skript vergleicht die laufzeiten von 2 verschiedenen methoden die Fib Zahlen zu berechnen...
am ende werden Grafiken bezeichnet...jeweils mit einer anderen skalierung^^
Antworten