Berechnen Sie eine Wahrscheinlichkeit genau


9

Bei dieser Aufgabe geht es darum, Code zu schreiben, um eine Wahrscheinlichkeit genau zu berechnen. Die Ausgabe sollte eine genaue Wahrscheinlichkeit sein, die als Bruch in ihrer am meisten reduzierten Form geschrieben wird. Das heißt, es sollte nie ausgegeben werden 4/8, sondern 1/2.

nBetrachten Sie für eine positive Ganzzahl eine gleichmäßig zufällige Zeichenfolge mit einer Länge von 1s und -1s nund nennen Sie sie A. Verketten Sie nun mit Aihrem ersten Wert. Das heißt, A[1] = A[n+1]wenn die Indizierung von 1. Ajetzt Länge hat n+1. Nun auch eine zweite zufällige Zeichenfolge der Länge betrachten , nderen erste nWerte -1, 0 oder 1 , mit einer Wahrscheinlichkeit von 1 / 4,1 / 2, 1/4 und jedes nennen es B.

Betrachten Sie zum Beispiel n=3. Mögliche Werte für Aund Bkönnten A = [-1,1,1,-1]und sein B=[0,1,-1]. In diesem Fall sind die beiden inneren Produkte 0und 2.

Betrachten Sie nun das innere Produkt von A[1,...,n]und Bund das innere Produkt von A[2,...,n+1]und B.

Ihr Code muss die Wahrscheinlichkeit ausgeben, dass beide inneren Produkte Null sind.

Für n=1diese Wahrscheinlichkeit ist klar 1/2.

Es macht mir nichts aus, wie nim Code angegeben ist, aber es sollte sehr einfach und offensichtlich sein, wie man es ändert.

Sprachen und Bibliotheken

Sie können jede Sprache und Bibliothek verwenden, die Sie mögen. Ich möchte Ihren Code ausführen, daher geben Sie bitte eine vollständige Erklärung an, wie Sie Ihren Code unter Linux ausführen / kompilieren können, wenn dies überhaupt möglich ist.


2
Testfälle für die ersten paar nwären hilfreich. Vielleicht hilft auch ein explizites Beispiel für A, B und die beiden inneren Produkte.
Martin Ender

Wenn wir die Ganzzahl harcodieren, n=4zählt sie dann als null, zwei oder drei Bytes? Muss die Ausgabe genau sein a/b oder wäre [a b]zB erlaubt?
Dennis

@ Tennis Es muss genau sein. Wenn Sie die Ganzzahl fest codieren, muss ich sie dann nur an einer Stelle ändern, um sie zu ändern n? Ansonsten denke ich, dass das nicht erlaubt ist.

Ja, mein Programm verwendet die Ganzzahl nur einmal, um eine kartesische Potenz zu berechnen. Alles andere wird aus dem resultierenden Array abgeleitet.
Dennis

Antworten:


7

Pyth, 48 47 46 44 Bytes

K,smlf!|Fms*Vd.>Tk2^,1_1Q^+0tM3Q^8Qj\//RiFKK

Probieren Sie es online aus: Demonstration

Die Online-Version berechnet wahrscheinlich nicht n=6. Auf meinem Laptop (Offline-Version) dauert es ungefähr 45 Sekunden.

Brute-Force-Ansatz.

Erläuterung:

smlf!|Fms*Vd.>Tk2^,1_1Q^+0tM3Q   implicit: Q = input number
                          tM3    the list [-1, 0, 1]
                        +0       add zero, results in [0, -1, 0, 1]
                       ^     Q   all possible lists of length Q using these elements
 m                               map each list d (B in Lembik's notation) to:
                  ,1_1              the list [1, -1]
                 ^    Q             all possible lists of length Q
   f                                filter for lists T (A in Lembik's notation),
                                    which satisfy:
       m        2                      map each k in [0, 1] to:
        s*Vd.>Tk                          scalar-product d*(shifted T by k)
    !|F                                not or (True if both scalar-products are 0)      
  l                                 determine the length                
s                                add all possibilities at the end

K,...^8QQj\//RiFKK   
 ,...^8Q             the list [result of above, 8^Q]
K                    store it in K
              iFK    determine the gcd of the numbers in K
            /R   K   divide the numbers in K by the gcd
         j\/         join the two numbers by "/" and print

dang, vergaß gcd, wusste, dass es etwas gab, das ich vermisste
Maltysen

+0r1_2ist kürzer als /R2r2_2.
isaacg

Ich denke, um fair zu sein, sollte es die 89/512-Version sein, die Sie zählen.

@Lembik Ok Geändert.
Jakube

Ich muss zugeben, mir ist nie in den Sinn gekommen, dass dies in 47 Zeichen möglich ist!

8

Mathematica, 159 100 87 86 85 Bytes

n=3;1-Mean@Sign[##&@@Norm/@({1,0,0,-1}~t~n.Partition[#,2,1,1])&/@{1,-1}~(t=Tuples)~n]

Zum Ändern ändern Sie neinfach die Variablendefinition am Anfang.

Da es sich um Brute Force handelt, ist es ziemlich langsam, aber hier sind die ersten acht Ergebnisse:

n   P(n)
1   1/2
2   3/8
3   7/32
4   89/512
5   269/2048
6   903/8192
7   3035/32768
8   169801/2097152

Der letzte hat bereits 231 Sekunden gedauert und die Laufzeit ist schrecklich exponentiell.

Erläuterung

Wie gesagt, es ist rohe Gewalt. Im Wesentlichen zähle ich nur alle möglichen Punkte auf Aund Bberechne die beiden Punktprodukte für jedes mögliche Paar und finde dann den Bruchteil der Paare, die sich ergeben haben {0, 0}. Die kombinatorischen und linearen Algebra-Funktionen von Mathematica waren dabei sehr hilfreich:

{1,-1}~(t=Tuples)~n

Dies erzeugt alle n-Tupel, die 1oder enthalten -1, dh alle möglichen A. Denn n = 3das ist:

{{1, 1, 1}, 
 {1, 1, -1}, 
 {1, -1, 1}, 
 {1, -1, -1}, 
 {-1, 1, 1}, 
 {-1, 1, -1}, 
 {-1, -1, 1}, 
 {-1, -1, -1}}

Um zu berechnen, machen Bwir fast dasselbe:

{1,0,0,-1}~t~n

Durch Wiederholen 0duplizieren wir jedes Tupel für jedes 0darin enthaltene, wodurch die 0Wahrscheinlichkeit doppelt so hoch wie 1oder wird -1. Wieder am n = 3Beispiel:

{{-1, -1, -1},
 {-1, -1, 0}, {-1, -1, 0},
 {-1, -1, 1},
 {-1, 0, -1}, {-1, 0, -1},
 {-1, 0, 0}, {-1, 0, 0}, {-1, 0, 0}, {-1, 0, 0},
 {-1, 0, 1}, {-1, 0, 1},
 {-1, 1, -1},
 {-1, 1, 0}, {-1, 1, 0},
 {-1, 1, 1},
 {0, -1, -1}, {0, -1, -1},
 {0, -1, 0}, {0, -1, 0}, {0, -1, 0}, {0, -1, 0},
 {0, -1, 1}, {0, -1, 1},
 {0, 0, -1}, {0, 0, -1}, {0, 0, -1}, {0, 0, -1},
 {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0},
 {0, 0, 1}, {0, 0, 1}, {0, 0, 1}, {0, 0, 1},
 {0, 1, -1}, {0, 1, -1},
 {0, 1, 0}, {0, 1, 0}, {0, 1, 0}, {0, 1, 0},
 {0, 1, 1}, {0, 1, 1},
 {1, -1, -1},
 {1, -1, 0}, {1, -1, 0},
 {1, -1, 1},
 {1, 0, -1}, {1, 0, -1},
 {1, 0, 0}, {1, 0, 0}, {1, 0, 0}, {1, 0, 0},
 {1, 0, 1}, {1, 0, 1},
 {1, 1, -1},
 {1, 1, 0}, {1, 1, 0},
 {1, 1, 1}}

Nun Awollen wir für jedes Mögliche das Punktprodukt jedes Möglichen B, sowohl mit A[1 .. n]als auch A[2 .. n+1]. Wenn unser Strom beispielsweise Aist {1, 1, -1}, möchten wir das Punktprodukt mit beiden {1, 1, -1}und mit {1, -1, 1}. Da alle unsere Bbereits bequemerweise die Zeilen einer Matrix sind, möchten wir die beiden Unterlisten Aals Spalten einer anderen Matrix, damit wir ein einfaches Punktprodukt zwischen ihnen berechnen können. Aber das Transponieren {{1, 1, -1}, {1, -1, 1}}gibt einfach {{1, 1}, {1, -1}, {-1, 1}}nur eine Liste aller zyklischen 2-Element-Unterlisten von A. Das macht das:

Partition[#,2,1,1]

Also berechnen wir das und nehmen das Punktprodukt mit unserer Liste von B. Da wir jetzt eine verschachtelte Liste erhalten (da jede mögliche Aeinen eigenen Vektor ergibt), reduzieren wir diese mit ##&@@.

Um herauszufinden, ob es sich um ein Paar {x, y}handelt {0, 0}, berechnen wir, Sign[Norm[{x,y}]] wo es Normgibt √(x²+y²). Dies gibt 0oder 1.

Da wir jetzt nur die Brüche von 1s in einer Liste von 0s und 1s kennen wollen, brauchen wir nur das arithmetische Mittel der Liste. Dies ergibt jedoch die Wahrscheinlichkeit, dass beide mindestens ein Punktprodukt ungleich Null sind, sodass wir es subtrahieren 1, um das gewünschte Ergebnis zu erhalten.


6

Pyth - 65 55 Bytes

Fehler mit Bruchreduzierung auf Kosten von einem Byte behoben.

Verwendet Brute-Force-Ansatz und kann enorm Golf gespielt werden, wollte aber nur etwas rausholen. Sehr langsam

*F-KP/Jmms*Vked,thdPhd*makhk^,1_1Q^[1ZZ_1)Q,ZZ2/lJ^2/K2

Es verwendet kartesische Produkte, um beides zu generieren, Aund Bführt die variablen Wahrscheinlichkeiten aus, indem es 0zweimal in der Quellliste angezeigt wird, und zählt dann diejenigen, die das innere Produkt sind, auf Null. Das innere Produkt wird durch den Vsyntaktischen Zucker der Ektorisierung erleichtert. Die Vereinfachung der Fraktion hat mich anfangs erschreckt, aber mit der PRaureiffaktorisierungsfunktion und der Erkenntnis, dass wir nur um Potenzen von 2 reduzieren müssen, war es ziemlich einfach .

Probieren Sie es hier online aus .


Wie ändere ich mich n?

@Lembik Das Pyth-Programm fordert eine Benutzereingabe an, die im zweiten Textfeld angegeben ist (wenn Sie den Online-Compiler verwenden).
Jakube

@ Jakube Oh danke! Und es scheint auch zu funktionieren :)

6

CJam, 58 57 54 51 46 Bytes

WX]m*Zm*_{~.+2,@fm<\f.*::+0-!},,__~)&:T/'/@,T/

Fügen Sie zum Ausführen die gewünschte Ganzzahl zwischen WX]und ein m*.

Vielen Dank an @ jimmy23013 für das bisschen Magie und für das Golfen von 5 Bytes!

Probieren Sie es online im CJam-Interpreter aus .

Idee

Die meisten Teile dieser Antwort sind unkompliziert, aber es werden zwei nette Tricks verwendet:

  • Anstatt alle Vektoren von {-1, 1} n mit allen Vektoren von {-1, 0, 1} n mit den gewünschten Wahrscheinlichkeiten zu paaren , wird die Anzahl der Tripletts von Vektoren in {-1, 1} n berücksichtigt , die erfüllen eine bestimmte Bedingung.

    Wenn wir die letzten beiden Vektoren eines Tripletts addieren, ist das Ergebnis ein Vektor von {-2, 0, 2} n .

    Da (-1) + 1 = 0 = 1 + (-1) , treten 0 s doppelt so oft auf wie -2 s und 2 s.

    Das Teilen jeder Komponente durch 2 würde einen Vektor von {-1, 0, 1} n mit den gewünschten Wahrscheinlichkeiten ergeben.

    Da wir nur interessiert sind, ob das Skalarprodukt 0 ist oder nicht, können wir die Division durch 2 überspringen .

  • Nachdem wir alle Drillinge gezählt haben, die die Bedingung der Frage und die Gesamtzahl der Drillinge erfüllen, müssen wir den resultierenden Bruch reduzieren.

    Anstatt die GCD beider Zahlen zu berechnen, reicht es aus, beide Zahlen durch die höchste Potenz von 2 zu teilen, die den Zähler teilt, da der Nenner immer eine Zweierpotenz ist.

    Um die höchste Potenz von 2 zu erhalten, die x teilt , können wir das bitweise UND von x und ~ x + 1 nehmen .

    ~ x kehrt alle Bits von x um , sodass alle nachfolgenden 0 s zu 1 s werden. Durch Hinzufügen von 1 zu ~ x werden diese 1 s wieder zu 0 s und die letzte 1 in ~ x + 1 stimmt mit der letzten 1 in x überein .

    Alle anderen Bits sind entweder beide 0 von verschieden, also gibt das bitweise UND die ganze Zahl zurück, die aus der letzten 1 von x und allen darauf folgenden 0 s besteht. Dies ist die höchste Potenz von 2, die x teilt .

Code

WX]    e# Push the array [-1 1].
       e# Insert N here.
m*     e# Cartesian product: Push the array of all vectors of {-1,1}^N.
Zm*    e# Cartesian product: Push the array of all triplets of these vectors.
_      e# Copy the array.
{      e# Filter; for each triplet of vectors U, V and W in {-1,1}^N:
  ~    e#   Dump U, V and W on the stack.
  .+   e#   Compute X := V + W, a vector of {-2,0,2}^N, where each component is
       e#   zero with probability 1/2.
  2,@  e#   Push [0 1]. Rotate U on top of it.
  fm<  e#   Push [U U'], where U' is U rotated one dimension to the left.
  \f.* e#   Push [U*X and U'*X], where * denotes the vectorized product.
  ::+  e#   Add the components of both products.
  0-   e#   Remove zeroes.
       e#   Push the logical NOT of the array.
},     e#   If the array was empty, keep the triplet.
,      e# Push X, the length of the filtered array.
__~)&  e# Push X & ~X + 1.
:T     e# Save the result in T and divide X by T.
'/     e# Push a slash.
@,T/   e# Dividet he length of the unfiltered array by T.

WX]m*Zm*_{~.+2,@fm<\f.*::+0-!},,__W*&:T/'/@,T/.
Jimmy23013

@ Jimmy23013: Das ist ein beeindruckendes bisschen Magie. Vielen Dank!
Dennis
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.