La façon la plus efficace de calcul de la moyenne à la volée (moyenne mobile)?
Je viens avec ce
n=1;
curAvg = 0;
loop{
curAvg = curAvg + (newNum - curAvg)/n;
n++;
}
Je pense que les faits saillants de cette façon sont les suivants:
- Il évite les grands nombres (et de débordement possible si vous somme et ensuite diviser)
- vous enregistrez un registre (pas besoin de stocker somme)
Le problème pourrait être avec sommation d'erreur - mais je suppose que, généralement, il doit être équilibré numéros de rond et rond vers le bas afin que l'erreur ne doit pas résumer de façon spectaculaire.
Voyez-vous des pièges dans cette solution?
Avez-vous une meilleure proposition?
- Je ne comprends pas votre formule. Pour
1 2
et3
ensuite, vous feriezcurAvg = 1.5 + (3 - 1.5)/2 = 1.5 + 0.75 = 2.25
, ce qui serait faux? - Question similaire: stackoverflow.com/questions/12636613/...
- boucle 1: curAvg=0+(1-0)/1=1; n=2<br> boucle 2: curAvg=1+(2-1)/2=1.5; n=3<br> boucle 3: curAvg=1.5+(3-1.5)/3=2; n=4
- Votre solution est là:
new average = old average + (next data - old average) / next count
- Vous avez oublié d'incrémenter la valeur de n. Il devrait être de 3 au lieu de 2.Ainsi, l'expression serait
curAvg = 1.5+(3-1.5)/3=1.5+0.5 = 2
, ce qui est correct. - Il convient de noter que l'OP de l'algorithme n'est pas un standard de la moyenne mobile, mais d'une façon exponentielle-moyenne mobile pondérée. Alors que l'EMA pourrait être juste le billet pour de nombreuses applications, les deux se comportent tout à fait différemment dans certaines circonstances (grand pas de réponse), les maîtres d'œuvre doivent être conscients de la différence. Voir stackoverflow.com/questions/12636613/...
Vous devez vous connecter pour publier un commentaire.
Votre solution est essentiellement le "standard" en ligne optimale, la solution pour garder une piste de course de moyenne sans stocker de grosses sommes d'argent et également lors de l'exécution "en ligne", c'est à dire que vous pouvez traiter simplement un numéro à la fois, sans revenir pour les autres numéros et vous ne l'utilisez une quantité constante de la mémoire supplémentaire. Si vous voulez un peu solution optimisée en termes de précision numérique, au prix d'être "en ligne", puis en supposant que vos numéros sont toutes non-négatif, ensuite trier vos numéros d'abord à partir de la plus petite à la plus grande, puis de les traiter dans l'ordre, de la même manière que vous le faites maintenant. De cette façon, si vous obtenez un tas de chiffres qui sont vraiment petites, à propos de l'égalité et puis, vous obtenez un grand nombre, vous serez en mesure de calculer la moyenne avec précision et sans dépassement de capacité, par opposition à si vous avez traité un grand nombre premier.
La formule ci-dessus est un non-sens. Mathématiques simples et de précision voudrait:
n
est l'itération contre,AV
est en cours d'exécution moyenne,newVal
est la nouvelle valeurinitialisation
n=0
,AV=0
Il n'y a pas de raccourci, vous devez avoir tous les chiffres et de les diviser par le nombre d'itérations, cependant, vous pouvez reconstruire l'un des numéros de connaître itération il est, il est un tossup de garder une exécution totale ou re-calcul. Le temps de re-calculer est à un coût élevé, le coût de stockage d'un nombre probablement un faible coût en termes de mémoire et le code de re-calculer serait certainement plus que de l'emplacement de mémoire à tenir le total et l'itération.