Seite 1 von 1

Algorithmus Riemannscher Umordnungssatz

Verfasst: Freitag 21. Oktober 2022, 22:06
von daveidix
Hallo,

ich schreibe gerade ein Programm mit dem ich versuche den Riemannschen Umordnungssatz für eine beliebige Zahl nachzuweisen bis auf eine bestimmte Genauigkeit. Dabei habe ich erstmal den folgenden Code geschrieben:

Code: Alles auswählen

k = 1

ziel = 2

summe = 0

while k < 10:
    
    z = (-1) ** k / k
    
    if summe < ziel:
        
            if z >= 0:
                summe = summe + z
                print(summe)
            
            else:
                nz = z
                
    else:
        summe = summe + nz
        print(summe)
                
    k = k + 1
    

print(summe)
Ich habe nun das Problem, dass "nz" ja immer überschrieben wird falls die Summe kleiner als das gewünschte Ziel ist. Um das zu umgehen würde mir jetzt nur einfallen die ganzen "nz" in eine Liste zu schreiben. Gibt es aber nicht noch eine bessere und elegantere Möglichkeit?

Re: Algorithmus Riemannscher Umordnungssatz

Verfasst: Samstag 22. Oktober 2022, 00:38
von __blackjack__
@daveidix: Falls Du die Werte später noch brauchst, musst Du sie dir halt merken. Falls die Reihenfolge der Verarbeitung wichtig ist, wäre eine `collections.deque` eventuell sinnvoll. Vielleicht suchst Du auch so etwas wie `more_itertools.partition()`‽

Zur Verständlichkeit/Lesbarkeit: Es ist etwas uneinheitlich eingerückt und es sind ein paar Leerzeilen deren Sinn ich nicht sehe.

Die ``while``-Schleife ist eigentlich eine ``for``-Schleife. Dann sieht man gleich, dass `k` in der Schleife nicht verändert wird. Also über das einfach hochzählen hinaus.

Die `z`\s könnte man in einen Generatorausdruck stecken, dann ist `k` ganz aus dem Schleifenkörper raus und es ist klar das `z` pro Schleifendurchlauf ”fest” ist.

Code: Alles auswählen

#!/usr/bin/env python3


def main():
    ziel = 2
    k = 1
    summe = 0
    for z in ((-1) ** k / k for k in range(10)):
        if summe < ziel:
            if z >= 0:
                summe += z
                print(summe)
            else:
                nz = z
        else:
            summe += nz
            print(summe)

    print(summe)


if __name__ == "__main__":
    main()

Re: Algorithmus Riemannscher Umordnungssatz

Verfasst: Samstag 22. Oktober 2022, 23:47
von __blackjack__
Falls ich das richtig verstanden habe, könnte man das so ausdrücken:

Code: Alles auswählen

#!/usr/bin/env python3
from itertools import count

from more_itertools import partition


def is_positive(value):
    return value >= 0


def main():
    werte = ((-1) ** k / k for k in count(1))

    negative_werte, positive_werte = partition(is_positive, werte)
    ziel = 2
    summe = 0
    for _ in range(100):
        summe += next(positive_werte if summe < ziel else negative_werte)
    print(summe)


if __name__ == "__main__":
    main()

Re: Algorithmus Riemannscher Umordnungssatz

Verfasst: Sonntag 23. Oktober 2022, 20:24
von daveidix
Vielen Dank für die Antwort. Ich denke deque ist für meinen Fall auf jeden Fall besser als eine einfache Liste. Meine Frage wäre bloß noch je nachdem wie genau mein Ergebnis werden soll kann es ja sein, dass ich eine sehr große Anzahl an Einträgen habe. Wäre dann eine Listenform immer noch das sinnvollste?

Re: Algorithmus Riemannscher Umordnungssatz

Verfasst: Sonntag 23. Oktober 2022, 22:56
von __blackjack__
Also allgemein würde ich einfach `more_itertools.partition()` verwenden. Falls Du davon ausgehen kannst, dass jedes zweite Element positiv bzw. negativ ist, kann man natürlich auch einfach direkt `positive_werte` und `negative_werte` über den Startwert und die optionale Schrittweite von `itertools.count()` erzeugen. Dann braucht man gar nichts zwischenspeichern.