Ich suche einen effizienten Algorithmus für das Problem:
Eingabe : Die positive ganze Zahl (als Bits gespeichert) für eine ganze Zahl . n ≥ 0
Ausgabe : Die Nummer .
Frage : Können wir aus den Bits von in Zeit berechnen ?3 n O ( n )
Dies ist eine theoretische Frage, die durch meine Antwort auf eine math.SE- Frage motiviert ist. Wie finde ich eine Formel für diese Bijektion? . In dieser Frage wollte der Autor eine Bijektion aus und den natürlichen Zahlen . Ich schlug als Lösung vor. Eine andere Antwort dort behauptete "es gibt keine einfache Formel", was mich fragen lässt, wie (rechnerisch) einfach meine vorgeschlagene Lösung ist.N = { 1 , 2 , … } 2 m 3 n ↦ 2 m ( 2 n + 1 )
Wenn wir mit meiner vorgeschlagenen Lösung und , können wir leicht berechnen (schreiben Sie die Binärziffern von gefolgt von gefolgt von Nullen). Dies dauert .m 2 m ( 2 n + 1 ) n 1 m O ( n + m )
Das Finden von aus den Bits von läuft darauf hinaus, das niedrigstwertige Bit zu finden (das berechnet werden kann, indem die richtigen Bitverschiebungen gezählt werden und im Speicher verbleiben ). Dies dauert Zeit.2 m 3 n 3 n O ( m )
Wir müssen jedoch auch finden , was schwieriger sein könnte. Es wäre möglich, durch wiederholtes Teilen durch , aber dies scheint verschwenderisch. Es erfordert Divisionsoperationen, von denen jede Zeit benötigt, also ist dies insgesamt Zeit. [Tatsächlich nimmt die Anzahl der Stellen nach jeder Iteration linear ab, dies führt jedoch immer noch zu einer -Zeit.]n 3 n O ( n ) O ( n 2 ) O ( n 2 )
Es scheint, als sollten wir in der Lage sein, das Wissen auszunutzen, dass die Eingabe eine Potenz von .
quelle
Antworten:
Der offensichtliche Ansatz ist:
(1) Berechnen Sie eine Näherung an . Sie können es auf einen additiven Fehler von 1 approximieren, indem Sie die Anzahl der Bits in der angegebenen Binärdarstellung zählen, und auf einen additiven Fehler von indem Sie zusätzlich das obere Bits der Eingabe. Es sollte ausreichen, einen konstanten Wert von zu wählen , damit (nach Kombination mit dem Fehler in Schritt (2)) das Endergebnis innerhalb eines additiven Fehlers von der korrekten endet .ϵ O ( log 1log2(3n) ϵ & epsi;1/2O(log1ϵ) ϵ 1/2
(2) Berechnen Sie eine Annäherung an . Ich bin mit den Algorithmen dafür nicht vertraut, aber ich gehe davon aus, dass sie in der Anzahl der benötigten Genauigkeitsbits ein Zeitpolynom benötigen und dass Sie nur Genauigkeitsbits benötigen .O ( log n )log2(3) O(logn)
(3) Teilen Sie die Antwort auf (1) durch die Antwort auf (2) und runden Sie auf die nächste ganze Zahl.
Der erste Schritt benötigt also lineare Zeit (in den meisten Berechnungsmodellen, obwohl dies bei einigen leistungsschwachen Modellen wie Einkopf-Turing-Maschinen möglicherweise nicht der Fall ist), und die verbleibenden Schritte sollten polylogarithmisch sein.
quelle
Für jede ganze Zahl erfordert das Schreiben von in Binärform genau Bits. Einige elementare Algebra impliziert, dass Für jede Bitlänge gibt es höchstens eine ganze Zahl in diesem Bereich. Bei einer ganzzahligen Potenz von , die Bits lang ist, muss der Exponent die ganze Zahln>0 3n L=⌈log2(3n)+1⌉ L≥13Ln=⌊L-1
quelle
Hier ist ein anderer Ansatz. Bei den niedrigen Ziffern von können Sie und damit lernen . Es sieht so aus, als ob ein Generatormodulo (dh hat die Reihenfolge ).k 3n 3nmod10k 3nmod5k 3 5k 3 φ(5k)=5k−1×4
Daher sollten Sie mit diskretem Log und Hensel-Lifting in der Lage sein, aus den niedrigen Ziffern von sehr effizient zu berechnen . Mit anderen Worten, Sie beginnen mit der Berechnung von aus der niedrigen Ziffer von , indem Sie das diskrete Protokoll von zur Basis , Modulo ; Dies zeigt und kann in -Zeit erfolgen. Dann finden Sie das diskrete Protokoll von zur Basis , modulo ; Dies zeigt und kann in durchgeführt werdennmodφ(5k) k 3n nmod4 3n 3nmod5 3 5 nmod4 O(1) 3nmod25 e 25 nmod20 O(1) Zeit (unter Ausnutzung des Wissens von gibt es nur Möglichkeiten, die Sie ausprobieren müssen). Iterieren. Bei jedem Schritt verwenden Sie das Wissen von , um das diskrete Protokoll von effizient zu berechnen , wobei Sie die Tatsache nutzen, dass es nur gibt mögliche Werte für .nmod4 5 nmodφ(5k−1) 3nmod5k n mod φ ( 5 k )5 nmodφ(5k)
Lassen Sie einfach groß genug sein, und dies zeigt .nk n
Sie müssen herausfinden, ob die Laufzeit , aber es sieht für mich so aus. Ich vermute, es reicht aus, , und ich vermute, Sie können jede Iteration in -Zeit für insgesamt -Zeit durchführen.k = O ( n ) O ( 1 ) O ( n )O(n) k=O(n) O(1) O(n)
quelle