En enkel rörlig genomsnittsimplementering i Java. Vid flera tillfällen vill jag beräkna enkla mätvärden i mina Java-applikationer, till exempel antalet träffar per timme eller fel under en tidsperiod. Det är inte så svårt att beräkna enkla mätvärden extra arbete och jag vill hellre spendera den tiden på problemområdet Jag blev förvånad över att inte hitta några allmänt accepterade lösningar för metrics i Java. Jag hittade Metrics men det verkade lite för komplicerat och inte väl dokumenterat. Allt jag verkligen ville var att beräkna ett glidande medelvärde Jag tänkte på problemet lite mer och bestämde mig för att det inte är ett svårt problem. Här är min lösning. Det här fungerar genom att skapa en rad fönsteruppdateringsfrekvensstorlek, och en tråd anger räkningen till nästa index i matrisen på uppdateringsfrekvensen Räkningen för intervallet är helt enkelt array i - array i 1, vilket är det senaste räkningen minus det äldsta räkningen. För ett 10 minuters intervall är det äldsta räknet i 1 exakt 10 minuter gammalt. För att lägga till en rörelse genomsnittet till vår kod först behöver vi en räknare med AtomicLong. Denna räknare bör ökas baserat på händelserna du är intresserad av att använda, t. ex. POST-förfrågningar om en REST-tjänst. Vi måste tillhandahålla implementeringen med tillgång till räknaren och det är uppnås via GetCount-gränssnittet Här skapar jag ett glidande medelvärde med ett 5 minuters fönster som uppdaterar varje sekund. För att få det aktuella genomsnittet kallar vi bara getAverage-metoden. En viktig implementeringsdetalj är hur arraystorleken bestäms genom att dela fönstret av uppdateringsfrekvensen Så ett stort fönster med en frekvent uppdateringsfrekvens kan förbruka en betydande mängd minne I det här exemplet är arraystorleken rimlig 300. Om vi skapade ett 24-timmars glidande medelvärde med ett intervall på 1 sekund skulle storleken vara 86400 A mer rimlig uppdateringsfrekvens för en 24-timmarsperiod kan vara varje 5 minuters arraystorlek på 288. En annan övervägning att välja fönstret och uppdateringsfrekvensen är att fönstret måste vara di synlig med frekvensen Till exempel är ett 2-minuters fönster med en 6 sekunders uppdateringsfrekvens ok, men en 7 sekunders uppdateringsfrekvens är inte, eftersom den inte är delbar med 120 En olagligArgumentException kastas om fönstermodulens uppdateringsfrekvens inte är noll. Detta genomförandet kräver en tråd per glidande medelvärde som inte är mycket effektiv En bättre lösning skulle vara att dela en tråd över många medeltal Uppdatering Jag har uppdaterat koden för att dela en tråd här. Det är senast ett första tillståndsproblem som vi inte har data ändå för hela fönstret Till exempel om du har ett 5 minuters fönster och bara 15 sekunder data Denna implementering returnerar null tills vi har 5 minuters data Ett annat tillvägagångssätt är att uppskatta genomsnittet. Antag att vi har ett räkning på 10 i 30 sekunder, då vi kan uppskatta genomsnittet som 40 på 2 minuter Men det finns risk för signifikant fel genom att extrapolera ofullständiga data. Om vi hade en brast på 20 träffar på 2 sekunder, beräknar vi 1200 per 2 minuter, whic h är med all sannolikhet långt borta. Din inre för är att iterera hela matrisen så det är därför du alltid får samma medelvärde för hela matrisen, du bör iterera från 0 till nuvarande antal av yttre för istället. Din rörelse Medelvärdet uppdateras baserat på j i ditt inre för att det innebär att det kommer att åsidosätta tidigare värden varje ny slinga, detta borde vara inuti det yttre i stället för det inre som använder jag som index. Du delar summa j för att beräkna medelvärden, varje ny Inre loop j du kommer att dividera med 0 den första summan jag tror du menade att använda j 1 istället är index inte detsamma som nuvarande längd. Tips för felsökning. Om du inte använder variabler till loop-arrays, borde du använda istället. För en fråga om Reproducera din fråga kan du ge oss det isolerade problemet istället för din nuvarande kod, dvs. Imagine om felet är i dina ingångar, hur kan vi tro att du verkligen använde dem. Svarade 4 okt 13 kl 20 54. Du slår över alla data Varje gång du borde ha för int ji genomsnittlig längd i - AverageLength 2 0 ji averageLength 2 j numDataPoänger j eller något liknande för ditt innersta genomsnitt. Även movingAverage jag summa j bör ändras för att hantera fallet när j är 0 Speciellt borde det förmodligen vara movingAverage i summaLängd och det ska tillämpas till movingAverage i-spåret utanför den genomsnittliga slingan. svarade den 4 oktober 13 på 20 42.Nästa gång, ta kommentarerna om uppdraget ur frågan innan du publicerar det. Men eftersom du verkar ganska ny på det här, tänk på hur du skulle gå genom data och gör det så att du ska försäkra dig om att varje slinga stannar vid rätt punkt och kom ihåg att om du skulle sluta när det inte finns fler nummer, som när du gör innerbandet och du kan bara få 3 fler siffror istället för 4 programmet måste sluta också Se till att din kod checkar efter this. answered 4 okt 13 på 20 56.Med eventuella ytterligare detaljer behöver du noga ett obestämt glidande medelvärde. Vid vilken tidpunkt är jag i inmatningen array A o f längd N med 0 i N, det är helt enkelt medelvärdet av tidigare K-poster i matrisen, upp till och inklusive A i Om det finns t K sådana värden, så genomsnittliga i 1-värdena från A 0 till A i inklusive. En liten tanke kommer att visa dig att du inte behöver lägga till alla K-värden varje gång Bara hålla summan och när du flyttar till nästa punkt är det ett glidande medelvärde, subtraherar det värde som ersätts och lägger till det nya värde som kommer att ersätta det Under de första K-1 poängen lägger du helt enkelt det nya värdet till summan och ökar din räknare med 1.An vilken punkt som helst i denna process är det glidande medelvärdet det aktuella summan dividerat med det aktuella räknarvärdet . Ansökad 4 oktober 13 på 21 05. I ett glidande medelvärde måste du ha någon form av fönsterstorlek. Din fönsterstorlek är medellängd, så det kommer att se ut så här. För slingan börjar vid nuvarande data och går tillbaka genomsnittlig Längd datapunkter och lägger till dem Du kommer bara ha ett glidande medelvärde när du har när du har tillräckligt datapunkter och medelvärdet kommer att vara summan dividerad med den genomsnittliga längden. Notera Inte testad bara sudokod, men det här är idén. ansvarig 4 okt 13 kl 21 05. Ditt svar.2017 Stack Exchange, Inc. Jag har i huvudsak en matris Av värden som denna. Ovanstående matris är översimplifierad, jag m samlar 1 värde per millisekund i min riktiga kod och jag behöver bearbeta utmatningen på en algoritm som jag skrev för att hitta den närmaste toppen före en tidpunkt. Min logik misslyckas eftersom i min Exempel ovan är 0 36 den riktiga toppen, men min algoritm skulle se bakåt och se det sista numret 0 25 som toppen eftersom det sänker till 0 24 före det. Målet är att ta dessa värden och tillämpa en algoritm för att dem som släpper ut dem lite så att jag har mer linjära värden, dvs jag tycker att mina resultat är kurva, inte jaggedy. Jag har fått höra att använda ett exponentiellt glidande medelfilter till mina värden. Hur kan jag göra det? Det är verkligen svårt för mig att läsa matematiska ekvationer, jag hanterar mycket bättre med code. How behandlar jag Värden i min array och tillämpar en exponentiell glidande genomsnittlig beräkning för att jämnas ut. Skakad 8 februari 12 kl 20 27. För att beräkna ett exponentiellt glidande medelvärde behöver du behålla en del tillstånd och du behöver en inställningsparameter Detta kräver att en liten klass antar du använder Java 5 eller senare. Instantiera med sönderfallsparametern du vill ha kan du ställa in bör vara mellan 0 och 1 och använd sedan genomsnittet för att filtrera. När du läser en sida om någon matematisk återkommande, behöver du bara veta när du gör det Kod är att matematiker gillar att skriva indexer i arrays och sekvenser med prenumerationer. De har några andra noteringar, som inte hjälper. EMA är dock ganska enkelt eftersom du bara behöver komma ihåg ett gammalt värde, inga komplicerade tillståndsuppsättningar krävs. Feb 8 12 på 20 42. TKKocheran Ganska mycket Är det inte trevligt när saker kan vara enkla Om du börjar med en ny sekvens får du en ny medelvärde Observera att de första villkoren i den genomsnittliga sekvensen kommer att hoppa runt lite på grund av att gränseffekter men du får även de med andra glidande medelvärden. En bra fördel är dock att du kan förflytta den glidande genomsnittliga logiken till medelvärdena och försöka utan att störa resten av ditt program för mycket. Donal Fellows 9 februari 12 på 0 06.I har svårt att förstå dina frågor men jag försöker svara ändå.1 Om din algoritm hittat 0 25 istället för 0 36, då är det fel Det är fel eftersom det förutsätter en monotonisk ökning eller minskning som alltid går upp eller alltid gå ner Om du inte vill ha det maximala värdet mellan två punkter i tid, skar du din matris från tmin till tmax och hitta max av den subarray.2 Nu är konceptet med glidande medelvärden mycket enkelt. Föreställ dig att jag har följande lista 1 4, 1 5, 1 4, 1 5, 1 5 Jag kan släta ut det genom att ta medeltalet av två siffror 1 45, 1 45, 1 45, 1 5 Observera att det första numret är genomsnittet av 1 5 an d 1 4 sekund och första nummer Den andra nya listan är genomsnittet av 1 4 och 1 5 tredje och andra gamla listan den tredje nya listan i genomsnitt 1 5 och 1 4 fjärde och tredje och så vidare kunde jag ha gjort det period Tre eller fyra eller n Observera hur dataen är mycket jämnare Ett bra sätt att se glidande medelvärden på jobbet är att gå till Google Finance, välj ett lager försök Tesla Motors ganska flyktiga TSLA och klicka på technicals längst ner i diagrammet Välj Flytta Medelvärde med en given period och Exponentiell glidande medelvärde för att jämföra deras skillnader. Exponentialt glidande medelvärde är bara en annan utarbetande av detta men viktar de äldre data mindre än de nya data så är det ett sätt att förspänna utjämningen mot baksidan. Läs Wikipedia så det här är mer en kommentar än ett svar, men den lilla kommentarrutan var bara för liten lycka till. Om du har problem med matte kan du gå med ett enkelt rörligt medel istället för exponentiellt skulle vara de sista x-termerna dela Ed av x Untested pseudocode. Notera att du måste hantera start och slut delar av data eftersom klart du inte kan t genomsnitt de senaste 5 termerna när du är på din andra datapunkt Det finns också mer effektiva sätt att beräkna denna rörelse genomsnittlig summa summan - äldsta nyaste, men det här är att få konceptet av vad som händer across. answered 8 februari 12 på 20 41.
No comments:
Post a Comment