Monday, 30 October 2017

Java Moving Average Køen


Mye mer enklere versjon: offentlig klasse MovingAverageInSlidingWIndow int vinduer Queue queue int sum offentlig MovingAverageInSlidingWIndow (int vinduer) this. windowsize windowsize this. queue new LinkedList () this. sum 0 finner flytende gjennomsnitt etter å ha satt inn element n til datastrøm private double findMovingAverage (int n) hvis (kø. size () gt windowsize - 1) sum sum - queue. poll () queue. offer (n) sum sum n return (double) sum queue. size () offentlig statisk tomrom main (string args) int windowsize 3 MovingAverageInSlidingWIndow m ny MovingAverageInSlidingWIndow (windowsize) for (int i 1 i lt 20 i) System. out. println (quotAfter Legge til kvote jeg sier til køen: Gjennomsnitt er: quot m. findMovingAverage (i)) Vi kan bare fortsette nåværende sum av elementer i kø i global variabel. Dermed reduseres beregningen i neste () metode. offentlig klasse MovingAverage LinkedList kø int størrelse int sum 0 holder summen køen Initialiser datastrukturen din her. offentlig MovingAverage (int størrelse) this. queue ny LinkedList () this. size størrelse offentlig dobbel neste (int val) queue. offer (val) sum val if (queue. size () gtthis. size) sum - queue. poll () Implementere en FIFO-kø med fast lengde i Java Når du arbeider med tidsseriedata, må du ofte beregne summer av sammenhengende tall for en forhåndsbestemt tidsramme. Tenk deg for eksempel å beregne et glidende gjennomsnitt med en fast størrelse. La oss se på en veldig enkelt tidsserie. Forutsatt at et glidende gjennomsnitt av lengde 4 resulterer i følgende rekkefølge: Formelen for et glidende gjennomsnitt på lengde 4 er således: MA t (Sum av alle elementer fra t-3 til t) 4 Hvordan ville vi effektivt implementere dette i Java-kode The Problemet er at vi må beregne summen i formelen for hvert glidende gjennomsnitt. Selvfølgelig er det mulig å alltid gjenta over alle tallene i gjeldende tidsramme for å gjøre det, men dette er unødvendig sakte. I stedet kan vi bare trekke det siste elementet i tidsrammen og legge til den nyeste til Sum. På denne måten kan vi lagre et betydelig antall unødvendige beregninger. Likevel må vi holde rede på hva som egentlig er de gamle og de nye elementene. Vi må lagre disse tallene et sted. En passende datastruktur vil være en første-i-første-ut (FIFO) kø av tall. Men hvordan kan en FIFO-kø faktisk implementeres i et (ikke-funksjonelt) programmeringsspråk som Java Den første ideen er vanligvis å bruke en arraybasert implementering og å skifte posisjonen til elementene i arrayet ved å gjenta litt skiftede kopier av matrisen. I eksempelet ovenfor må vi opprette en ny serie fem ganger, en gang for hver ny Sum beregnes. Dette er selvsagt svært ineffektivt, fordi opprettelsen av en matrise i minnet er relativt langsom. Implementeringer basert på klasser som java. util. ArrayList eller java. util. Vector er allerede mye bedre, fordi de er avhengige av lengre arrays og indekser internt. Likevel er dette ikke den beste løsningen, fordi når de interne indeksene beveger seg utenfor de indre grenseområdene, må en ny kopi av den interne gruppen opprettes. Et typisk alternativ for å implementere FIFO-køer bruker således en koblet liste: Fordelen er åpenbar, ikke mer kopiering eller gjenoppretting av arrays i minnet. Alt vi trenger å gjøre er å manipulere noen få poeng. Selvfølgelig mister vi fordelene ved direkte å vurdere et element i køen etter indeks, men for vårt formål - å beregne glidende gjennomsnitt - dette er noe vi ikke vil gjøre uansett. I går skjedde det plutselig til meg at det faktisk er et enda bedre alternativ hvis lengden på køen er løst (som i vårt eksempel). Vi kan effektivt bruke en ring. Å legge til et nytt nummer i køen og slippe den eldste er det samme som å bare erstatte det eldste elementet i denne ringen med en ny. Internt kan vi igjen bruke en rekke med en fast lengde i kombinasjon med en roterende indeks. Slik ser koden ut i Java. La oss først lage vårt eget køgrensesnitt: Dette grensesnittet avviker noe fra det som er oppgitt i Java-bibliotekene, men dette er ubetydelig for nå. Neste, implementeringen av køen vår: Køen kvitterer gjennom ringen. Hvis du legger til et nytt element i køen, fjerner du automatisk det eldste elementet i køen - ingen kopiering av arrayer eller tilbakestilling av objektreferanser som kreves. I motsetning til sammenkoblede lister kan vi faktisk få tilgang til hvert element i ringen direkte med get-metoden. Til slutt kan vi lage en underklasse av køforslaget som nådig vil rulle over når nye verdier legges til i køen. Vi kan nå bruke klassen nå. Lengden på det bevegelige gjennomsnittet settes innledningsvis gjennom lengden på gruppen som er gitt til sin konstruktør. Jeg trenger å holde oversikt over de siste 7 dagene arbeidstid i en flat filleseløkke. Dens blir brukt til å måle utmattingen av arbeidsroster. Akkurat nå har jeg noe som fungerer, men det virker ganske ordentlig og jeg er ikke sikker på om det er et mønster som er mer kortfattet. Foreløpig har jeg en Java-klasse med et statisk array for å holde de siste x-dagene dataene, da jeg leser gjennom filen, hugger jeg av det første elementet og flytter de andre 6 (for en ukes rullende sum) tilbake av en. Behandlingen av denne statiske matrisen er gjort i sin egen metode, dvs. Mitt spørsmål: er dette en rimelig design-tilnærming, eller er det noe blindingly åpenbart og enkelt å gjøre denne oppgaven Takk gutta spurte Aug 30 11 kl 14:33 Takk mange menn: Jeg har meldingen: bruk et høyere objekt og utnyt relevante metoder eller en sirkulær buffer. Flotte svar, alle av dem. Når du tenker på det, trenger du alltid tilgang til hele oppsettet slik at du kan kvitte deg med den første oppføringen - som jeg ikke var sikker på selv. I39m lettet over at jeg ikke hadde savnet noen liner og var i utgangspunktet på en rimelig, om ikke effektiv og tett spor. Dette er hva jeg elsker om dette nettstedet: høykvalitets, relevante svar fra folk som kjenner deres sht. ndash Pete855217 Aug 30 11 på 15:05 Hvorfor initierer du runningTotal til null Hva er dens type Hvor det er erklært Det ville fungere bra hvis du legger noen kodeprøver som ligner på faktisk Java-kode. Fortsett, min kritikk ville være følgende: Funksjonen din gjør for mye. En funksjon, eller metode, skal være sammenhengende. Mer hensiktsmessig, de burde bare gjøre en ting og en ting. Verre fortsatt, hva skjer i din forløp når x 5 Du kopierer runningTotal6 til runningTotal5. men da har du to eksemplarer av samme verdi i posisjon 5 og 6. I designet ditt, flyttes funksjonen din til movesshuffles elementene i din matrise beregner totalt antall utskrifter til standard feil, returnerer summen. Det gjør for mye. Mitt første forslag er ikke å flytte ting rundt i matrisen. I stedet implementere en sirkulær buffer og bruk den i stedet for arrayet. Det vil forenkle ditt design. Mitt andre forslag er å bryte ned tingene i sammenhengende funksjoner: ha en datastruktur (en sirkulær buffer) som lar deg legge til det (og det faller den eldste oppføringen når den når sin kapasitet.) Har datastrukturen implementere en interator har en funksjon som beregner total på iteratoren (du bryr deg ikke om du beregner summen ut av en matrise, liste eller sirkulær bufer.) Ikke ring det totalt. Kaller det summen, som er hva du beregner. Det er det jeg gjør :) Det er flott info luis, men husk at denne funksjonen er en liten del av klassens funksjonalitet, og det ville være overkill å legge til for mye kode for å gjøre det perfekt. Du er teknisk riktig, og jeg forstår at koden min gjør 39 til mye39, men samtidig er det bedre å feile på siden av mindre klarere kode enn å gå for perfekt. Gitt min Java-ferdigheter, selv om du gjør pseudokoden du beskriver kompilere, ville jeg få meg til å blåse budsjettet mitt på dette (), men takk for den klare beskrivelsen. ndash Pete855217 Aug 31 11 på 2:23 Hmmm, det handler ikke om perfeksjon, men om etablerte industripraksis som vi har kjent de siste 3 tiårene. Ren kode er alltid en som er partisjonert. Vi har flere tiår med bevis som tyder på at dette er veien å gå i det generelle tilfellet (når det gjelder kostnadseffektivitet, feilreduksjon, forståelse osv.). med mindre det er kaste bort kode for en engang slags ting. Det er aldri dyrt å gjøre dette når man starter en problemanalyse på denne måten. Koding 101, bryte ned problemet og koden følger, verken overkill eller vanskelig) ndash luis. espinal Aug 31 11 på 15:55 Din oppgave er for enkel og det du har vedtatt, er sikkert bra for jobben. Men hvis du vil bruke en bedre design, må du kvitte deg med all den nummerbevegelsen du bedre bruker en FIFO-kø, og bruk god push - og pop-metoder slik at koden ikke reflekterer databevegelser, bare de to logiske handlingene av nye data og fjern data eldre enn 7 dager. svarte aug 30 11 kl 14:49

No comments:

Post a Comment