IT하는 참새

이동평균 알고리즘 본문

프로그래밍/알고리즘

이동평균 알고리즘

pshot 2018. 4. 9. 23:27

이동평균 알고리즘 = Moving Average Algorithm


이 알고리즘은 이동하며 변화하는 평균을 구하는 알고리즘이다


값이 자주 변하여 일정기준에 따라 그 값의 평균을 추적하는 알고리즘이라고 생각하면 쉽다


예를들어)


여자친구의 몸무게, 자신의 감정변화, 알코올 섭취량, 주식 등 

시시각각 자주변하는 곳에 적용하여 미래를 예측해보는데 사용된다


어떠한 경우에서 적용이 가능할까?


N개의 측정치, M의 기준 이 주어지면 이동평균을 구할 수 있다


N = 12일

M = 3(일)마다의 이동평균을 구하려고 한다


아~ 최소 3개의 기록이 있어야 구할 수 있겠구나(3일부터~)


12개의 결과가 있는데 3번째 결과부터 그 동안의 3일의 평균을 구하는것이다


이동평균을 구하는 함수를 작성해보았다 (JAVA)


public static ArrayList<Integer> movingAverage(ArrayList<Integer> during, int m) {

ArrayList<Integer> ret = new ArrayList<Integer>();


int size = during.size();

for(int i=m-1; m<size; i++) {

int partialSum = 0;

if(i==15) break;

for(int j=0; j<m; j++) {

partialSum += during.get(i-j);

}

ret.add(partialSum/m);

}

return ret;

}


during = N개의 데이터들이 들어있다 (12개)

m = M(기준)이다. 3을 넘겼다


(코드 이해는 알아서 하기로한다)


하지만 이 코드는 80점짜리라고 생각한다

for를 두번 중첩하였기 때문에 속도면에서 -20점이다


N=12, M=3이라면 실제 반복횟수는 30번이다.


(M * (N-M+1) 에 의해서)


그럼 어떻게해야할까? for 중첩을 안하고는 할 수 없을까...


가능하다!


가만 생각해보면 이동평균의 규칙을 생각해볼 수 있다


1 2 3일의 이동평균 = 1+2+3 / 3 

2 3 4일의 이동평균 = 2+3+4 / 3

3 4 5일의 이동평균 = 3+4+5 / 3


규칙이 보인다


두개씩은 전 이동평균과 겹친다  이 말은 즉


1. 새로운 이동평균을 위해 전의 겹치는 두 개의 값은 그대로 두고 

2. 첫번째를 빼고

3. 현재 일의 값을 더하면 된다


아래는 이 말을 구현한 코드이다(JAVA)


public static ArrayList<Integer> movingAverage(ArrayList<Integer> during, int m) {

ArrayList<Integer> ret = new ArrayList<Integer>();


int size = during.size();

int partialSum = 0;

for(int i=0; i<m-1; i++) {

partialSum += during.get(i);

}

for(int i=m-1; i<size; i++) {

partialSum += during.get(i);

ret.add(partialSum/m);

partialSum -=  during.get(i-m+1);

}

return ret;

}



매개변수는 같다


이렇게 구현하면 실행시간은 size에 정비례하다

size는 무엇인가? during의 길이 -> N이다. (총 데이터 개수)


이렇게 수행시간이 N에 정비례하므로 

N이 두 배 커지면 실행시간도 두 배 커진

(주어진 값을 최소한 한 번씩 쳐다보기 때문에)


이러한 알고리즘을 선형시간 알고리즘이라고 한다 (linear time)