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:
Python-Code
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()
Python-Code
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()