Saturday 16 September 2017

Java Moving Average Queue


Ich habe ein wissenschaftliches datalogging Programm, das ich für eine Anzahl von Jahren jetzt entwickelt habe. Wir müssen nun etwas Funktionalität hinzufügen, so dass es einen gleitenden Durchschnitt der gesammelten Daten erzeugt. Ich kann eine Warteschlange von myDataClass erstellen, um den Fifo-Puffer zu tun, aber ich frage mich, was der beste Weg, der die Mittelung tut, sein könnte. Wie Sie aus dem folgenden Codebeispiel sehen können, enthält myDataClass verschiedene Datenstrukturen, von denen einige gemittelt werden können, und einige, die nicht (z. B. die Zeichenfolge) sein können. Die Hauptfrage ist, ob es eine einfache Möglichkeit, dies zu erreichen oder muss ich Code zu durchschnittlich jedes Element in myDataClass schreiben oder sollte ich redesign myDataClass Danke. Ich würde eine Klasse quotDataQueue (of MyDataClass) erstellen, die sich selbst dequeue, wenn die Anzahl in der Warteschlange 10 Elemente überschreitet. Auf diese Weise müssen Sie niemals um die Anzahl der Artikel in der Warteschlange aus Ihrem Code zu kümmern, wird dies kümmern werden aus der Warteschlange-Klasse Als Antwort markiert von Mike Feng Moderator Mittwoch, 20. Juli 2011 1:56 Tuesday, July 12, 2011 9:40 AM Nach ein wenig mehr Forschung, ich glaube, ich fand die Lösung für Sie. Sie können die CopyTo-Methode verwenden, um die linken Elemente in der Warteschlange in einem Array zu kopieren. Seien Sie sich bewusst, ich habe nicht den Durchschnitt zu berechnen, zeigte ich nur, wie Sie die Basis Ihrer Berechnungen erhalten können, aber das ist nur das Hinzufügen Ihrer eigenen Berechnungen basierend auf Ihrer Geschäftsregel für die. Als Antwort markiert von Mike Feng Moderator Basiert auf meinem Verständnis, Ihre Anforderung ist so etwas wie dies: Dies sind die Daten in der Warteschlange: myDataClass1. Datadbl 2.1 datastr quotsomeString1quot dataarraydbl ein doppeltes Array myDataClass2. Datadr 3.5 datastr quotsomeString2quot dataarraydbl ein doppeltes Array myDataClass10. Datadbl 9.1 datastr quotsomeString10quot dataarraydbl ein doppeltes Array Nun wollen Sie die durchschnittliche Anzahl der datadbl Feild in jedem myDataClass-Objekt zu berechnen, und erhalten Sie die durchschnittliche Anzahl der dataarraydbl Feild. Wenn ja, schlage ich Ihnen vor, die gleiche Sache wie Crazypenie vorgeschlagen: eine neue Klasse namens DataQueue: Ich hoffe, dies wird hilfreich sein, wenn ich etwas falsch verstanden haben, wenden Sie sich bitte lassen Sie mich wissen. Mike Feng MSFT MSDN Community Support Feedback an uns Get oder Request Code Beispiel von Microsoft Bitte denken Sie daran, die Antworten als Antworten markieren, wenn sie helfen, und sie zu markieren, wenn sie keine Hilfe bieten. Als Antwort markiert von Mike Feng Moderator Mittwoch, 20. Juli 2011 15:33 Danke Cor, ich könnte es so machen, aber myDataClass ist eigentlich ziemlich groß und das Protokollierungssystem kann laufen Eine lange Zeit, so ist es effizienter für mich zu Junk-Kopien der Klasse I dont tatsächlich für die Berechnung der Durchschnitt. Warteschlange schien der einfachste Weg, dies zu erreichen. Meine Hauptfrage ist aber, wie durchschnittlich eine Klasse wie diese Ich bekomme das Gefühl, dass ich muss Code schreiben, die es speziell für jeden Datentyp in myDataClass. Öffentliche Klasse myDataClass Nach meinem Verständnis, Ihre Anforderung ist so etwas wie dies: Dies sind die Daten in der Warteschlange: myDataClass1. Datadbl 2.1 datastr quotsomeString1quot dataarraydbl ein doppeltes Array myDataClass2. Datadr 3.5 datastr quotsomeString2quot dataarraydbl ein doppeltes Array myDataClass10. Datadbl 9.1 datastr quotsomeString10quot dataarraydbl ein doppeltes Array Nun wollen Sie die durchschnittliche Anzahl der datadbl Feild in jedem myDataClass-Objekt zu berechnen, und erhalten Sie die durchschnittliche Anzahl der dataarraydbl Feild. Wenn ja, schlage ich Ihnen vor, die gleiche Sache wie Crazypenie vorgeschlagen: eine neue Klasse namens DataQueue: Ich hoffe, dies wird hilfreich sein, wenn ich etwas falsch verstanden haben, wenden Sie sich bitte lassen Sie mich wissen. Mike Feng MSFT MSDN Community Support Feedback an uns Get oder Request Code Beispiel von Microsoft Bitte denken Sie daran, die Antworten als Antworten markieren, wenn sie helfen, und sie zu markieren, wenn sie keine Hilfe bieten. Marked als Antwort von Mike Feng Moderator Montag, 20. Juli 2011 01:55 AMA Simple Moving Durchschnittliche Implementierung in Java Bei mehreren Gelegenheiten Ive wollte einfache Metriken in meiner Java-Anwendungen zu berechnen, zum Beispiel die Anzahl der Treffer pro Stunde oder Fehler während eines Zeitraums. 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 über 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 Schlüsselimplementierungsdetail ist, wie die Arraygröße bestimmt wird: indem das Fenster durch die Aktualisierungshäufigkeit dividiert wird. 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, wed würde schätzen 1200 pro 2 Minuten, die aller Wahrscheinlichkeit nach weit weg ist. Java Gleitender Durchschnitt Methode Wenn Sie für eine EMA, die für Streaming-Daten optimiert ist, sourced suchen Aus einer Datei oder Quoting-Dienst, die folgende Beispiel-Klasse wird Ihnen gut, im Gegensatz zu mit Brute-Force-Berechnungen. Dieser Ansatz ist besonders nützlich, wenn Sie Daten in Echtzeit verarbeiten. EMAs, ein Sonderfall gewichteter gleitender Durchschnitte, haben den Vorteil, dass die relative Gewichtung für jede aufeinanderfolgende Periode um einen konstanten Faktor f 2 / (N1) abnimmt, wobei N die Anzahl der Perioden ist, über die die EMA angewendet werden soll. Die folgende Beispielklasse implementiert diesen iterativen Charakter von EMA und minimiert die rechnerischen Anforderungen gegenüber Brute-Eman-Eman-1, Kraft-Methoden oder Nachbearbeitungsverfahren. Privates int numPeriods 0 privates int totalPeriods 0 privates double runningEMA 0.0 privates doppeltes Faktor 0.0 public EMA (int numPeriods) this. numPeriods numPeriods Faktor 2.0 / (numPeriods 1.0) / Reset Berechnungen zu generieren EMA für den angegebenen Zeitraum. / Public void reset (int numPeriods) / Gibt EMA für den Zeitraum zurück, der während des Konstruktors definiert wird. Wenn verarbeitete Perioden kleiner als der EMA-Bereich sind, wird Null zurückgegeben. / Public double berechnen (doppelter Preis) runningEMA factorprice (1-Faktor) runningEMA if (totalPeriods lt numPeriods) Von wo aus Sie die Preisdaten ausgeben und was Sie mit den EMA-Ergebnissen tun, liegt bei Ihnen. Wenn Sie beispielsweise die Preisdaten in einem Array haben und eine EMA in ein anderes Array berechnen möchten, funktioniert das folgende Snippet: doppelte Preise. (50) // 50 Periode EMA für (int idx0 iltprices. length idx) emaidx ema (pricesidx) Viel Glück und beste Wünsche für Ihr Projekt .

No comments:

Post a Comment