Fakultät in logarithmischer Lauftzeit berechnen



  • Die Frage ist dann wiederum wie berechne ich den Logarithmus schnell. Und dafür brauche ich vor allem Zahlen die Nachkommastellen können und das ist irgendwie ärgerlich, wenn ich sonst nur einfache Integers habe, weil dann wieder die Rechengenauigkeit eine Frage wird.

    MfG Jester



  • (dumme) Idee:
    gegeben sei ein array A mit allen primazahlen <=n.

    Psydocode:

    for a=1 to |A| do
    	for i=A[a] to n step A[a] do // *
     		B[A[a]]+=berechne wie oft i durch a teilbar; //*
    	od
    od
    n=1
    for b=1 to |B| do
    	n=(A[b]^B[b])*n;
    od
    

    *= vielleicht gibt es hier eine geschlossene Formel??

    ich denke, wenn das überhaupt funzt, ist das Problem A zu erstellen...Aber selbst dann wäre das nicht O(logn)....

    Nicht haua machen wenn flasch sein 😃 🙄



  • WebFritzi schrieb:

    Ich weiß nun nicht genau, wie die Laufzeit berechnet wird. Ich denke mal, dass es die Anzahl der Multiplikationen in Abh. von n sind. Dann habe ich auf jeden Fall einen Algo gefunden, der die Fakultät in O(n/2) ausrechnet (wenn man das Multiplizieren mit 2 nicht mitrechnet 🙄 ). Es ist ja z.B.

    8! = 5 * ((5-1)(5+1)) * ((5-2)(5+2)) * ((5-3)(5+3))
       = 5 * (25-1²) * (25-2²) * (25-3²)
    

    Mit q = (n/2 + 1) gilt allgemein

    n! = q * (q²-1²) * (q²-2²) * ... * (q²-(q-2)²)
    

    Setzen wir nun
    ak=q2k2,a_k = q^2 - k^2,
    dann gilt
    ak+1=(q2k2)2k1=ak(2k+1).a_{k+1} = (q^2 - k^2) - 2k - 1 = a_k - (2k + 1).
    Wenn wir nun die Multiplikation mit 2 vernachlässigen, so können wir also ak+1 aus ak ohne Aufwand berechnen. Da nun
    n! = q \cdot a\_1 \cdot a\_2 \cdot \dots \cdot a_{q-2},
    haben wir
    q2=n2+12=n21q-2 = \frac{n}{2} + 1 - 2 = \frac{n}{2} - 1
    Multiplikationen.

    EDIT: Bei ungeradem n kommt noch eine Multiplikation mit n dazu.

    Könnte man a! in 2 Polynome mit grad n aufspalten so könnte man diese mit der FFT (Fast Fourier TRafo.) ind O(nlogn) multipizieren.....



  • xroads42 schrieb:

    ich denke, wenn das überhaupt funzt, ist das Problem A zu erstellen...Aber selbst dann wäre das nicht O(logn)....

    jo. zwischen 1 und n gibt es circa n/ln(n) primzahlen.
    alle primzahlmultiplizierer brauchen also mindestens O(n/ln(n)) und das ist leider viel großer als O(ln(n)).



  • Na ich bin jedenfalls gespannt, wie der Prof aus der Sache wieder rauskommt. 😉

    Bye, TGGC



  • also ich bin auch mal gespannt ... weil denke nicht, daß ich bis Freitag eine Lösung habe ... muss auch noch bis Donnerstag nen Vortrag zum Thema VPN für eine andere Vorlesung vorbereiten und habe einfach genug zu tun ...

    habe mich aber trotzdem nochmal ein wenig beschäftigt mit der ganzen Sache und habe mal drüber nachgedacht ... es gab mal einen Algorithmus mit dem ich 2 natürliche Zahlen in logarithmischer Laufzeit berechnen kann ... aber das brachte mich dann wieder auch nicht weiter ... wollte die Zahlen dann variabel lassen und die Zahlen für die Fakultät einsetzen aber dadurch hat das ganze ja wieder keine logarithmische Laufzeit 😞



  • Wollte den Thread mal wieder nach vorn holen ... heute ist doch die Antwort fällig, ne?

    Gruß



  • 😃 Hab heut morgen auch schon dran gedacht.



  • *gespanntsei*



  • *Trommelwirbel*

    Und hier präsentier ich euch die Lösung 😃 ...

    also ihr werdet es kaum glauben ... also der Prof sprach mich heute an und fragte, ob ich die Aufgabe geschafft hätte ... ich sagte mit herabgesenktem Kopf nein ... fragte aber auch gleich wie man die Fakultät in logarithmischer Laufzeit berechne ... er schaute nur etwas verdutzt und fragte, ob er wirklich Fakultät gesagt hätte ... das wurde ihm dann von mehreren Leuten bestätigt ... er entschuldigte sich höflich ... was er eigentlich wollte war ein Algorithmus um die Fibonacci-Zahlen in logarithmischer Lauftzeit ...

    *lach* naja sorry Leute ... aber war nicht meine Schuld ... jetzt muss ich mir mal Gedanken über die neue "richtige" Aufgabe machen 🙄



  • Ich weiß die Lösung! 🙂 ...ich weiß sogar 2 Lösungen! 🙂



  • du meinst jetzt für die Fibonacci-Zahlen in logarithmischer Laufzeit ?? 😮 .... her damit 😃



  • Du sollst ja auch noch etwas zu tun haben, aber ich gebe dir nen Tipp:

    Es gibt für die Fibonaccizahlen eine explizite Formel (die also nicht rekursiv ist). Ich denke, dass man diese Formel leicht so implementieren kann, dass sie in logarithmischer Zeit berechnet werden kann.

    ...jetzt mußt du nur noch die Formel herausfinden! 🙂

    ...die zweite Lösung war natürlich:

    Alles vorher ausrechnen und in nem Array speichern. Bei den 46 (glaube ich, mich zu erinnern) Fibonaccizahlen, die man auf herkömmlichen Wegen darstellen kann, ist das IMHO immer noch eine vollkommen legitime, richtige und natürliche Lösung. Es ist sogar die beste Lösung.



  • THX ... muss dazu sagen, die Formel für die Fibonacci-Zahlen habe ich schon ... jetzt muss ich nur nochmal nen Prog dazu schreiben und das in logarithmischer Zeit ... aber das mach ich erst morgen oder so ... muss mich noch ein wenig um meine HP´s kümmern und Tagesguck schauen 😃 ...

    war nur auf die zweite Lösung gespannt ... 😉



  • Ich machs in O(1) *gg*



  • das würde dann ja nicht der Aufgabenstellung entsprechen :p 😃



  • Gregor schrieb:

    Alles vorher ausrechnen und in nem Array speichern.
    [...],ist das IMHO immer noch eine vollkommen legitime, richtige und natürliche Lösung. Es ist sogar die beste Lösung.

    Für einen Programmiere/Softwareentwickler ja, für einen Informatiker nicht. Begründung: s.o.

    MfG Jester



  • viel ist die repetitive form schneller:

    fac(n) = facrep(n,1)

    facrep(n,x) = if n > 0 then facrep(n-1, x*n) else x

    Aber obs reicht, probiers mal aus!



  • Wo ist die Begründung? Ich seh sie nicht. 😞



  • Jester schrieb:

    Für einen Programmiere/Softwareentwickler ja, für einen Informatiker nicht. Begründung: s.o.

    Doch, selbstverständlich ist das auch für einen Informatiker die beste Lösung. Es ist der effizienteste Algorithmus für den gewünschten Wertebereich. Warum sollte sich ein Informatiker mit etwas minderwertigem abfinden? Damit es "mathematischer" aussieht? ...BTW: Ich habe sogar ein Skript aus einer Informatikvorlesung, in dem genau dieses Beispiel vorkommt. Dort wird auch eindeutig gesagt, dass dies die beste Lösung.

    Du scheinst dich auf den Standpunkt zu stellen, dass man so eine Art "allgemeingültige" Lösung als Informatiker finden muss. Das ist nicht richtig. Ein Informatiker ist sich durchaus darüber im klaren, dass ein Computer, als das Werkzeug, auf dem der Algorithmus irgendwann mal läuft, Beschränkungen hat. Entsprechend beachtet er diese Beschränkungen auch bei der Konstruktion von Algorithmen. Deine Sichtweise ist eher die Sichtweise eines Mathematikers.

    das würde dann ja nicht der Aufgabenstellung entsprechen :p 😃

    Wie du weiter oben an der Definition der O-Notation schon gesehen hast, ist O(1) eine Teilmenge von O(log(n)). Es entspricht also durchaus der Aufgabenstellung. Wenn ein Algorithmus eine Laufzeit von O(1) hat, dann hat er auch eine Laufzeit von O(log(n)).


Anmelden zum Antworten