[PYTHON] Berechnung der FGO-Sternkonzentrationswahrscheinlichkeit / des erwarteten Wertes

Hinweis

Dieser Artikel handelt von einem Algorithmus in einem sozialen Spiel namens FGO, Fate / Grand Order.

Einführung

Kritisch ist ein großer Teil der Taktik in FGO, aber die Berechnung der Konzentration kritischer Sterne ist etwas mühsam.

Diener / Versteckter Status - Schicksal / Großauftrag @wiki [FGO] - Im Wiki

Die Spezifikationen sind

Berechnungsbeispiel

Betrachten Sie die folgenden Diener.

Die Diener 1 bis 2, 2 bis 2, 3 bis 1 werden verteilt, und wenn Sie sich die Boni als +0, +0, +50, +20, +20 vorstellen ...

Verteilerkarte Diener 1
Karte A.
Diener 1
Karte B.
Diener
Karte C.
Diener2
Karte D.
Diener3
Karte E.
Konzentration 200 200 50 50 10
Bonus +0 +0 +50 +20 +20
gesamt 200 200 100 70 30
Verhältnis(%) 33.3 33.3 16.7 11.7 5
Verteilerkarte Diener 1
Karte A.
Diener 1
Karte B.
Diener
Karte C.
Diener2
Karte D.
Diener3
Karte E.
Konzentration - 200 50 50 10
Bonus - +0 +50 +20 +20
gesamt - 200 100 70 30
Verhältnis(%) - 50 25 17.5 7.5
Verteilerkarte Diener 1
Karte A.
Diener 1
Karte B.
Diener
Karte C.
Diener2
Karte D.
Diener3
Karte E.
Konzentration - - 50 50 10
Bonus - - +50 +20 +20
gesamt - - 100 70 30
Verhältnis(%) - - 50 35 15

……… Und die Wahrscheinlichkeit ändert sich so.

Berechnung

Boni ändern sich während des Verteilungsprozesses nicht. Ignorieren Sie sie und verallgemeinern Sie sie. Die Wahrscheinlichkeit, dass $ y $ Sterne auf die Karte $ n $ verteilt werden, ist

Ist die Summe von. Implementieren Sie dies in einem Python-Programm.

Implementierung

fgostarcalc.py



import math
#SW jeder Karte (einschließlich Bonus): Karte 1 bis Karte 5
SW = [200, 200, 100, 70, 30]

#Enthält die Wahrscheinlichkeit von 0 bis 10 Sternzuständen für jede Karte
Probabilities = [None for _ in range(11**6)]
Probabilities[0] = 1

#Holen Sie sich eine beliebige Ziffernummer(Anzahl der Sterne auf jeder Karte)
def digitnum(decim, base, ind):
    return(math.floor((decim % (base**ind))/(base**(ind-1))))

#Summe der Zahlen in jeder Ziffer(Sternensumme)
def sumdigit(decim, base):
    if decim == 0:
        return 0
    else:
        return(sum([digitnum(decim, base, i) for i in range(1, 2+math.ceil(math.log(decim, base)))]))

#Gültigkeitsprüfung
def is_valid(decim, base, totalstar, card, holdstar):
    if digitnum(decim, base, card) == holdstar:
        if sumdigit(decim, base) == totalstar:
            return True
    return False
        
#Rekursive Funktion der Wahrscheinlichkeitsberechnung für jeden Zustand
def calc_starprob(decim, base, totalstar, card, holdstar):
    #print(decim, base, totalstar, card, holdstar)
    starweights = [0 if digitnum(decim, base, x+1)
                   == base-1 else SW[x] for x in range(5)]
    starprob = [SW[x]/(sum(starweights)-starweights[x]+SW[x])
                for x in range(5)]
    starweights[card] = SW[card]
    if decim < 0 or totalstar < 0 or holdstar < 0:
        print("Error: ", decim, base, totalstar, card, holdstar)
        raise
    if Probabilities[decim] != None:
        return(Probabilities[decim])
    else:
        tmp = [0]
        for x in range(5):
            if digitnum(decim, base, x+1) == 0:
                continue
            else:
                if x+1 == card and holdstar > 0:
                    tmp += [calc_starprob(decim-base**x, base,
                                          totalstar-1, card, holdstar-1)*starprob[x]]
                elif x+1 != card:
                    tmp += [calc_starprob(decim-base**x, base,
                                          totalstar-1, card, holdstar)*starprob[x]]
        Probabilities[decim] = sum(tmp)
        return(Probabilities[decim])

#Wahrscheinlichkeit, dass sich Sternsterne auf der Karte sammeln, wenn sich insgesamt Sternsterne befinden
def calc_probability(totalstar,card,holdstar):
    return(sum([calc_starprob(x, 11, totalstar, card, holdstar)
                 for x in range(11**5) if is_valid(x, 11, totalstar, card, holdstar)]))

#Wahrscheinlichkeit, mehr als Holdstar-Sterne auf der Karte zu sammeln, wenn Totalstar-Sterne vorhanden sind
def calc_moreprobability(totalstar,card,holdstar):
    tmp=0
    for star in range(holdstar, 11):
        tmp+=sum([calc_starprob(x, 11, totalstar, card, star)
                for x in range(11**5) if is_valid(x, 11, totalstar, card, star)])
    return(tmp)

#Wahrscheinlichkeit, Sterne zu sammeln, die kleiner oder gleich Holdstar auf der Karte sind, wenn Totalstar-Sterne vorhanden sind
def calc_lessprobability(totalstar,card,holdstar):
    tmp=0
    for star in range(0,holdstar+1):
        tmp+=sum([calc_starprob(x, 11, totalstar, card, star)
                for x in range(11**5) if is_valid(x, 11, totalstar, card, star)])
    return(tmp)

#totalstar Erwartete Anzahl von Sternen, die auf der Karte gesammelt werden, wenn Sterne vorhanden sind
def calc_expectation(totalstar,card):
    tmp=0
    for star in range(0, 11):
        tmp+=calc_probability(totalstar, card, star)*star
    return(tmp)

#Die Anzahl der Sterne, die erforderlich sind, damit die erwartete Anzahl der Sterne auf der Karte als Stern gesammelt werden kann(Integer Wert)
def calc_totalstar_expectation(card,star):
    if star>10:
        star=10
    for totalstar in range(50):
        if calc_expectation(totalstar,card)>star:
            return(totalstar)

Prüfung


#Stichprobe(Wahrscheinlichkeit, dass sich 8 auf Karte 1 versammeln, wenn 25 Sterne vorhanden sind)
print(calc_probability(25, 1, 8))
#0.1693947010897705

#Stichprobe(Erwartete Anzahl von Sternen auf Karte 1, wenn 20 Sterne vorhanden sind)
print(calc_expectation(20, 1))
#6.862519232471602

#Stichprobe(Anzahl der Sterne, die erforderlich sind, um 4 oder mehr erwartete Werte auf Karte 1 zu sammeln)
print(calc_totalstar_expectation(1,4))
#12

abschließend

Es ist keine sehr schnelle Implementierung, aber ich konnte sie berechnen. Sie können auch die Wahrscheinlichkeit, den erwarteten Wert, die erforderliche Anzahl usw. berechnen. Zufällige Boni sind ebenfalls $ \ frac {5!} {2! 2!} = 30 $. Wenn Sie dies anwenden, können Sie alle Muster berechnen.

Recommended Posts

Berechnung der FGO-Sternkonzentrationswahrscheinlichkeit / des erwarteten Wertes
[Grundlagen der modernen mathematischen Statistik mit Python] Kapitel 2: Wahrscheinlichkeitsverteilung und Erwartungswert
Sequentielle Berechnung des Durchschnittswertes mit Online-Algorithmus
Berechnung der gegenseitigen Informationsmenge (kontinuierlicher Wert) mit numpy