[PYTHON] Calcul de la probabilité de concentration d'étoile FGO / valeur attendue

Mise en garde

Cet article concerne un algorithme dans un jeu social appelé FGO, Fate / Grand Order.

introduction

La critique est une grande partie de la tactique dans FGO, mais le calcul de la concentration d'étoiles critiques est un peu fastidieux.

Statut Serviteur / Caché - Destin / Grand Ordre @wiki [FGO] -Au Wiki

Les spécifications sont

Exemple de calcul

Considérez les serviteurs suivants.

Les serveurs 1 à 2, 2 à 2, 3 à 1 seront distribués, et si vous pensez aux bonus comme +0, +0, +50, +20, +20 ...

Carte de distribution Serviteur 1
Carte A
Serviteur 1
Carte B
Serviteur
Carte C
Serviteur2
Carte D
Serviteur3
Carte E
Concentration 200 200 50 50 10
Prime +0 +0 +50 +20 +20
total 200 200 100 70 30
rapport(%) 33.3 33.3 16.7 11.7 5
Carte de distribution Serviteur 1
Carte A
Serviteur 1
Carte B
Serviteur
Carte C
Serviteur2
Carte D
Serviteur3
Carte E
Concentration - 200 50 50 10
Prime - +0 +50 +20 +20
total - 200 100 70 30
rapport(%) - 50 25 17.5 7.5
Carte de distribution Serviteur 1
Carte A
Serviteur 1
Carte B
Serviteur
Carte C
Serviteur2
Carte D
Serviteur3
Carte E
Concentration - - 50 50 10
Prime - - +50 +20 +20
total - - 100 70 30
rapport(%) - - 50 35 15

……… Et la probabilité change comme ça.

Calcul

Les bonus ne changent pas pendant le processus de distribution, alors ignorez-les et généralisez-les. La probabilité que $ y $ étoiles soient distribuées à la carte $ n $ est

Est le total de. Implémentez ceci dans un programme Python.

la mise en oeuvre

fgostarcalc.py



import math
#SW de chaque carte (bonus compris): Carte 1 à Carte 5
SW = [200, 200, 100, 70, 30]

#Contient la probabilité de 0 à 10 états étoiles pour chaque carte
Probabilities = [None for _ in range(11**6)]
Probabilities[0] = 1

#Obtenez n'importe quel numéro(Nombre d'étoiles sur chaque carte)
def digitnum(decim, base, ind):
    return(math.floor((decim % (base**ind))/(base**(ind-1))))

#Somme des nombres dans chaque chiffre(Total d'étoiles)
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)))]))

#Vérification de la validité
def is_valid(decim, base, totalstar, card, holdstar):
    if digitnum(decim, base, card) == holdstar:
        if sumdigit(decim, base) == totalstar:
            return True
    return False
        
#Fonction récursive du calcul de probabilité pour chaque état
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])

#Probabilité de tenir des étoiles sur la carte lorsqu'il y a des étoiles totales
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)]))

#Probabilité de collecter plus d'étoiles Holdstar sur la carte lorsqu'il y a des étoiles Totalstar
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)

#Probabilité de collecter des étoiles inférieures ou égales à holdstar sur la carte lorsqu'il y a des étoiles totalstar
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 Nombre attendu d'étoiles à collecter sur la carte lorsqu'il y a des étoiles
def calc_expectation(totalstar,card):
    tmp=0
    for star in range(0, 11):
        tmp+=calc_probability(totalstar, card, star)*star
    return(tmp)

#Le nombre d'étoiles requis pour que le nombre d'étoiles à collecter sur la carte soit étoile(Valeur entière)
def calc_totalstar_expectation(card,star):
    if star>10:
        star=10
    for totalstar in range(50):
        if calc_expectation(totalstar,card)>star:
            return(totalstar)

tester


#échantillon(Probabilité que 8 se réunissent sur la carte 1 lorsqu'il y a 25 étoiles)
print(calc_probability(25, 1, 8))
#0.1693947010897705

#échantillon(Nombre attendu d'étoiles à collecter sur la carte 1 lorsqu'il y a 20 étoiles)
print(calc_expectation(20, 1))
#6.862519232471602

#échantillon(Nombre d'étoiles requis pour collecter 4 valeurs attendues ou plus sur la carte 1)
print(calc_totalstar_expectation(1,4))
#12

en conclusion

Ce n'est pas une implémentation très rapide, mais j'ai pu la calculer. Vous pouvez également calculer la probabilité, la valeur attendue, le nombre requis, etc. Les bonus aléatoires sont également $ \ frac {5!} {2! 2!} = 30 $, donc si vous appliquez cela, vous pouvez calculer tous les modèles.

Recommended Posts

Calcul de la probabilité de concentration d'étoile FGO / valeur attendue
[Bases des statistiques mathématiques modernes avec python] Chapitre 2: Distribution des probabilités et valeur attendue
Calcul séquentiel de la valeur moyenne avec l'algorithme en ligne
Calcul de la quantité d'informations mutuelles (valeur continue) avec numpy