Ihre innere für iteriert alle Array so thats, warum Sie immer den gleichen Durchschnitt (die für die gesamte Array), sollten Sie iterieren von 0 auf die aktuelle Zahl der äußeren für statt. Ihr gleitender Durchschnitt wird aktualisiert, basierend auf j Ihrer inneren für das bedeutet, dass es vorherige Werte überschreibt jede neue Schleife, sollte dies innerhalb der äußeren für statt der inneren mit i als Index sein. Sie teilen sum j, um Mittelwerte zu berechnen, jede neue innere Schleife j Sie teilen durch 0 die erste Summe. Ich glaube, Sie wollten j1 verwenden, Index ist nicht das gleiche wie aktuelle Länge Tipps zur Fehlerbehebung: Vermeiden Sie die Verwendung von Variablen zu Loop-Arrays, sollten Sie array. length stattdessen verwenden. Für eine Frage der Reproduktion Ihres Problems könnten Sie uns das isolierte Problem anstelle des aktuellen Codes. Dh: Stellen Sie sich vor, wenn der Fehler in Ihren Eingaben ist, wie könnten wir glauben, dass Sie wirklich verwendet sie beantwortet werden Sie sind Looping über alle Daten jedes Mal. Sie sollten für (int j (igtaverageLengthi-averageLength 2: 0) jlt iaverageLength 2 ampamp jltnumDataPoints j) (oder etwas ähnliches) für Ihren innersten Durchschnitt. Auch MovingAverageisum j sollte modifiziert werden, um den Fall zu behandeln, wenn j 0 ist. Insbesondere sollte es wahrscheinlich MovementAverageisum averageLength sein und es sollte auf den movingAveragei-Slot außerhalb der Mittelungsschleife angewendet werden. Antwortete Oct 4 13 am 20:42 Nächstes Mal, nehmen Sie die Kommentare über die Zuweisung aus der Frage, bevor Sie es. Aber da Sie scheinen ziemlich neu in diesem, darüber nachzudenken, wie würden Sie durch die Daten gehen, und machen es tun. Sie sollten sicherstellen, dass jede Schleife an dem richtigen Punkt stoppt, und denken Sie daran, dass wenn Sie stoppen würden, wenn es keine Zahlen mehr gibt (wie wenn Sie die innere Schleife machen und nur 3 weitere Zahlen anstelle von 4 erhalten können) Muss das Programm auch stoppen. Stellen Sie sicher, dass Ihr Code für diese Überprüfung ist. Antwortete ohne weitere Details, benötigen Sie wahrscheinlich einen ungewichteten gleitenden Durchschnitt. An einem beliebigen Punkt Ai im Eingabefeld A der Länge N (mit 0ltiltN) ist das einfach der Mittelwert der vorherigen K Einträge des Arrays, bis zu und einschließlich Ai. Wenn es arent K solche Werte, dann die durchschnittlichen (i1) Werte von A0 bis Ai. Einschließlich. Ein wenig Gedanke zeigt Ihnen, dass Sie nicht alle K-Werte addieren müssen jedes Mal. Halten Sie einfach die Summe, und beim Bewegen zum nächsten Punkt (dies ist ein gleitender Durchschnitt), subtrahieren Sie den Wert, der ersetzt wird, und fügen Sie den neuen Wert hinzu, der es ersetzt. (Bei den ersten K-1-Punkten fügen Sie einfach den neuen Wert zur Summe hinzu und erhöhen Sie den Zählwert um 1.) Der gleitende Durchschnitt ist an jedem Punkt der aktuelle Summe dividiert durch den aktuellen Zählwert. In einem gleitenden Durchschnitt, müssen Sie eine Art von Fenstergröße haben. Ihre Fenstergröße ist averageLength, so wird es etwa so aussehen: Die for-Schleife startet bei den aktuellen Daten und geht zurück AverageLength Datenpunkte und fügt sie hinzu. Sie haben nur einen gleitenden Durchschnitt, wenn Sie haben, wenn Sie genügend Datenpunkte haben und der Durchschnitt wird die Summe geteilt durch die durchschnittliche Länge haben. Hinweis: Nicht getestet nur Sudo-Code, aber das ist die Idee. Antwort # 2 am: Mai 23, 2010, 07:10:49 pm »Ihre Antwort 2016 Stack Exchange, IncA Einfache Moving Average Implementation in Java Bei mehreren Gelegenheiten Ive wollte einfache Metriken in meinem Java-Anwendungen, zum Beispiel die Anzahl der Treffer pro Stunde oder Fehler während eines Zeitraums zu berechnen . Während der Berechnung einfacher Metriken ist nicht schrecklich schwierig, seine nur extra Arbeit und Id eher verbringen diese Zeit auf der Problem-Domain. Ich war überrascht, keine allgemein akzeptierten Lösungen für Metriken in Java zu finden. Ich fand Metrics, aber es schien ein wenig zu kompliziert und nicht gut dokumentiert - Alles, was ich wollte, war es, einen gleitenden Durchschnitt zu berechnen. Ich dachte über das Problem einiges mehr und entschied es nicht ein schwieriges Problem. Heres meine Lösung Dies funktioniert durch die Schaffung eines Arrays von Fenster-Update-Frequenz Größe, dann ein Thread setzt die Zählung auf den nächsten Index im Array auf die Aktualisierungsfrequenz. Die Zählung für das Intervall ist einfach arrayi - arrayi1, das ist die jüngste Zählung minus der ältesten Zählung. Für ein 10-Minuten-Intervall ist die älteste Zählung (i1) genau 10 Minuten alt. Um einen gleitenden Durchschnitt zu unserem Code hinzuzufügen, benötigen Sie zunächst einen Zähler mit AtomicLong. Dieser Zähler sollte basierend auf den Ereignissen inkrementiert werden, die für das Berechnen interessant sind (z. B. POST-Anforderungen für einen REST-Dienst). Wir müssen die Implementierung mit Zugriff auf den Zähler bereitstellen und das wird durch die GetCount-Schnittstelle erreicht. Hier Ill erstellen einen gleitenden Durchschnitt mit einem 5-Minuten-Fenster, das jede Sekunde aktualisiert. Und um den aktuellen Durchschnitt zu erhalten, rufen wir einfach die getAverage-Methode auf: Ein wichtiges Implementierungs-Detail ist, wie die Array-Größe bestimmt wird: indem Sie das Fenster durch die Aktualisierungshäufigkeit teilen. So kann ein großes Fenster mit einer häufigen Aktualisierungshäufigkeit eine beträchtliche Menge an Speicher verbrauchen. In diesem Beispiel ist die Array-Größe vernünftig 300. Wenn wir jedoch einen 24-Stunden-gleitenden Durchschnitt mit einem Intervall von 1 Sekunde erstellt haben, wäre die Größe 86400 Eine vernünftigere Aktualisierungsfrequenz für einen Zeitraum von 24 Stunden kann alle 5 Minuten betragen (Arraygröße von 288 ). Eine weitere Überlegung der Auswahl der Fenster-und Update-Frequenz ist das Fenster muss durch die Frequenz teilbar. Zum Beispiel ist ein 2-minütiges Fenster mit einer 6-Sekunden-Aktualisierungsfrequenz ok, aber eine 7-Sekunden-Aktualisierungsfrequenz ist nicht vorhanden, da es nicht durch 120 teilbar ist. Eine IllegalArgumentException wird geworfen, wenn die Fenstermodul-Aktualisierungsfrequenz nicht Null ist. Diese Implementierung erfordert einen Thread pro gleitenden Durchschnitt, was nicht sehr effizient ist. Eine bessere Lösung wäre, einen Thread über viele Durchschnitte zu teilen. Aktualisieren. Ich habe den Code aktualisiert, um einen Thread hier zu teilen. Schließlich theres ein Anfangszustandproblem: wir dont haben Daten noch für das gesamte Fenster. Zum Beispiel, wenn Sie ein 5-Minuten-Fenster und nur 15 Sekunden Daten haben. Diese Implementierung gibt null zurück, bis wir 5 Minuten Daten haben. Ein anderer Ansatz ist, den Durchschnitt abzuschätzen. Angenommen, wir haben eine Zählung von 10 in 30 Sekunden, dann können wir den Durchschnitt als 40 in 2 Minuten abschätzen. Es besteht jedoch das Risiko eines signifikanten Fehlers, indem unvollständige Daten extrapoliert werden. Zum Beispiel, wenn wir einen Burst von 20 Hits in 2 Sekunden hatten, schätzte man 1200 pro 2 Minuten, was aller Wahrscheinlichkeit nach weg ist.
No comments:
Post a Comment