Python :: Aufgabe #205
2 Lösungen
Random Walk der Liouville Serie
Fortgeschrittener - Python
von hollst
- 16.01.2019 um 16:20 Uhr
Die Liouville Serie ist eine Zahlenfolge, die nur aus den Zahlen +1 und -1 besteht.
Sie beginnt mit {1, -1, -1, 1, -1, 1, -1, -1, 1, 1, -1, -1 ...}. Die ersten 10.000
Glieder sind in der Datei liouville_folge.txt gespeicher und könnten meinetwegen eingelesen werden.
Wer die Glieder der Folge L(n) selber berechnen will, muss wie folgt vorgehen:
1.) Per Definition wird L(1) => +1 gesetzt.
2.) Man zerlege n in all seine Primfaktoren (z. B. 14 = 2 * 7 oder 32 = 2 * 2 * 2 * 2 * 2).
3.) L(n) => +1, falls die Anzahl der Primfaktoren eine gerade Zahl ist, ansonsten L(n) => -1
(also L(14) => +1; L(32) => -1).
Man fasse nun L(n) als eine Schrittfolge auf, die eine Weg in der x-y-Ebene beschreibt.
Ausgehend von der Koordinate (x = 0, y = 0) wird zunächt der x-Wert um Eins erhöht
(entsprechend L(1) = 1), anschließend wird der y-Wert um Eins erniedrigt (entsprechend L(2) = -1)
und immer so fort bis zu L(nmax) (nmax von mir aus 10.000 oder mehr).
Der sich so ergebene Weg (siehe Bild 1 für nmax = 100.000, die Pixelfarbe wechselt zur besseren Illustration alle 10.000 Schritte)
ist gefühlsmäßig ein Zufallsweg (Random Walk). Ob dem wirklich so ist, weiß man bis heute nicht.
Die Programmieraufgabe bestehe nun darin, den Liouville-Weg graphisch darzustellen.
Falls jemand fragt "Was soll der Unfug?": Nun, man geht davon aus, das die Liouville Serie ein Schlüssel
zur Lösung der Riemann-Hypothese (RH) sein könnte. Bekanntlich sind zum Beweis bzw. zur Widerlegung der RH
noch immer eine Million US-Dollar ausgeschrieben.
Also, dann viel Erfolg! Ich drücke die Daumen für den Einemilliongewinn.
Sie beginnt mit {1, -1, -1, 1, -1, 1, -1, -1, 1, 1, -1, -1 ...}. Die ersten 10.000
Glieder sind in der Datei liouville_folge.txt gespeicher und könnten meinetwegen eingelesen werden.
Wer die Glieder der Folge L(n) selber berechnen will, muss wie folgt vorgehen:
1.) Per Definition wird L(1) => +1 gesetzt.
2.) Man zerlege n in all seine Primfaktoren (z. B. 14 = 2 * 7 oder 32 = 2 * 2 * 2 * 2 * 2).
3.) L(n) => +1, falls die Anzahl der Primfaktoren eine gerade Zahl ist, ansonsten L(n) => -1
(also L(14) => +1; L(32) => -1).
Man fasse nun L(n) als eine Schrittfolge auf, die eine Weg in der x-y-Ebene beschreibt.
Ausgehend von der Koordinate (x = 0, y = 0) wird zunächt der x-Wert um Eins erhöht
(entsprechend L(1) = 1), anschließend wird der y-Wert um Eins erniedrigt (entsprechend L(2) = -1)
und immer so fort bis zu L(nmax) (nmax von mir aus 10.000 oder mehr).
Der sich so ergebene Weg (siehe Bild 1 für nmax = 100.000, die Pixelfarbe wechselt zur besseren Illustration alle 10.000 Schritte)
ist gefühlsmäßig ein Zufallsweg (Random Walk). Ob dem wirklich so ist, weiß man bis heute nicht.
Die Programmieraufgabe bestehe nun darin, den Liouville-Weg graphisch darzustellen.
Falls jemand fragt "Was soll der Unfug?": Nun, man geht davon aus, das die Liouville Serie ein Schlüssel
zur Lösung der Riemann-Hypothese (RH) sein könnte. Bekanntlich sind zum Beweis bzw. zur Widerlegung der RH
noch immer eine Million US-Dollar ausgeschrieben.
Also, dann viel Erfolg! Ich drücke die Daumen für den Einemilliongewinn.
Lösungen:
import tkinter
class Coord_System(tkinter.Canvas):
def __init__(self, root, width, height, x_offset, y_offset):
self.x_offset=x_offset
self.y_offset=y_offset
super().__init__(root, width=width, height=height)
class GI():
def __init__(self, width, height):
self.width=width
self.height=height
self.main_frame = tkinter.Tk()
self.main_frame.geometry(f"{width}x{height}")
def coord_system(self, x_posit, x_neg, y_posit, y_neg, scale):
x_length = (abs(x_posit)+abs(x_neg))*scale
y_length = (abs(y_posit)+abs(y_neg))*scale
y_pos = 30
x_pos = self.height-30
if y_neg < 0:
x_pos+=y_neg*scale
if x_neg < 0:
y_pos-=x_neg*scale
can = Coord_System(self.main_frame, width=self.width, height=self.height, x_offset=30, y_offset=770-y_length)
can.pack()
can.create_line(30, x_pos, x_length+30, x_pos, fill="#000000")
can.create_line(y_pos, 770-y_length, y_pos, 770, fill="#000000")
for i in range(30, x_length+30+scale, scale):
can.create_line(i, x_pos-10,i,x_pos+10)
x=i+scale/10
while x<i+scale and i<x_length+30:
can.create_line(x, x_pos-3, x, x_pos+3)
x+=scale/10
for i in range(770-y_length,x_pos+y_pos+scale,scale):
can.create_line(y_pos-10,i,y_pos+10,i)
y=i+scale/10
while y<i+scale and i<770:
can.create_line(y_pos-3, y, y_pos+3, y)
y += scale / 10
return can
def draw(self):
self.main_frame.mainloop()
is_prime = lambda x:[i for i in range(2,x) if x%i==0]
def add_prime(pf):
if type(pf)==int:
return [pf]
else:
return pf
def prime_factors(n):
if not is_prime(n):
return n
for i in range(2, n+1):
if(n%i==0):
return add_prime([prime_factors(i)])+add_prime(prime_factors(int(n/i)))
def length(n):
if type(n)==int:
return 1
else:
return len(n)
def liouville_num(n):
if n%2==0:
return 1
else:
return -1
if __name__=='__main__':
z = int(input("Bis zu welcher Stelle soll die Reihe berechnet werden?"))
arr=[1]
for i in range(2,z+1):
arr.append(liouville_num(length(prime_factors(i))))
print(arr)
GI = GI(800, 800)
coord_system = GI.coord_system(x_posit=10,x_neg=0,y_posit=10, y_neg=0, scale=50)
x_off=coord_system.x_offset
y_off=coord_system.y_offset
for p in range(0, len(arr)):
if (p+1)%2==0:
y_off+=arr[p]
coord_system.create_oval(x_off,y_off,x_off,y_off,fill="#5588aa")
else:
x_off-=arr[p]
coord_system.create_oval(x_off, y_off, x_off, y_off, fill="#5588aa")
GI.draw()def primfaktorzerlegung(zahl):
prims = []
grenze = zahl
status = True
while status:
for i in range(2, grenze + 1):
if zahl % i == 0:
prims.append(i)
zahl = int(zahl / i)
break
if zahl == 1:
status = False
if len(prims) % 2 == 0:
a = 1
else:
a = -1
return a
x_achse = [1]
y_achse = [1]
start = 1
x = 1
for i in range(2, 10000):
start = start + primfaktorzerlegung(i)
y_achse.append(start)
import matplotlib.pyplot as plt
plt.plot(y_achse)
plt.show()