I 0의 범위의 신호 강도 값이 매 초마다 업데이트되는 정수 속성을 가지고 지난 10, 25, 50 측정 동안 이동 평균.계산하는 이동 - 평균은
가장 효율적인 방법은 무엇입니까?
현재 NSMutableArray를 사용하여 FIFO 대기열 집합을 구현하고 배열에 필요한 수의 항목이있는 경우 끝에 새 값을 추가 할 때마다 선행 값을 팝핑 할 생각입니다. 그러나이 작업을 수행하는보다 효율적인 방법이 있는지 확실하지 않습니다.
I 0의 범위의 신호 강도 값이 매 초마다 업데이트되는 정수 속성을 가지고 지난 10, 25, 50 측정 동안 이동 평균.계산하는 이동 - 평균은
가장 효율적인 방법은 무엇입니까?
현재 NSMutableArray를 사용하여 FIFO 대기열 집합을 구현하고 배열에 필요한 수의 항목이있는 경우 끝에 새 값을 추가 할 때마다 선행 값을 팝핑 할 생각입니다. 그러나이 작업을 수행하는보다 효율적인 방법이 있는지 확실하지 않습니다.
대기열이 올바른 방법입니다. 실제 효율은 평균을 다시 계산하는 방법과 함께 제공됩니다.
는 그것은으로 수행해야합니다
avg = avg + newSample/N - [queue dequeue]/N
[queue enqueue:newSample]
즉 새로운 실행 평균이 단순히 이전 평균 뺀 떨어 가장 오래된 가치의 무게, 플러스 당신이 큐에 최신 값의 무게입니다.
나는 당신에게 맞는 솔루션이 있다고 생각합니다.
동적으로 크기가 조정 된 배열에서 물건을 이동하는 대신 정적 크기의 배열을 사용하고 현재 색인을 추적 할 수 있습니다.
e.e. N은 크기 배열이며 %는 나머지 연산자 인 경우 (내가 객관적 C 프로그래머가 아니에요) :
values[current] = get_current_sample()
previous = (current + N - 1) % N
sum = sum + values[current] - values[previous]
current = (current + 1) % N
당신은 개별적으로 워밍업 기간을 치료하기 위해이 평균 = 합계/N. (당신이 전에 N 개의 샘플을 가짐).
NSMutableArray가 메모리 할당을 처리하는 방법에 따라 훨씬 빨라질 수 있습니다.
저는 이것을 처리하기 위해 MovingAverage라는 간단한 클래스를 작성했습니다. 에 넣어 정적 슬롯의 알을 계산 당신은 유지 기간의 수와 방법을 초기화하기 그리고 시료의 계수를 사용하여 나머지를 추적합니다.
초기화와
MovingAverage *avg5periods = [[MovingAverage alloc] initWithSize:5];
추가 항목 :
[avg5periods addSample:1.0];
NSLog(@"1.2f",[avg5periods movingAverage]); //1.0
[avg5periods addSample:2.0];
NSLog(@"1.2f",[avg5periods movingAverage]); //1.5
[avg5periods addSample:3.0];
NSLog(@"1.2f",[avg5periods movingAverage]); //2.0
[avg5periods addSample:4.0];
NSLog(@"1.2f",[avg5periods movingAverage]); //2.5
[avg5periods addSample:5.0];
NSLog(@"1.2f",[avg5periods movingAverage]); //3.0
[avg5periods addSample:6.0];
NSLog(@"1.2f",[avg5periods movingAverage]); //4.0
헤더 파일 :
#import <Foundation/Foundation.h>
@interface MovingAverage : NSObject {
NSMutableArray *samples;
int sampleCount;
int averageSize;
}
-(id)initWithSize:(int)size;
-(void)addSample:(double)sample;
-(double)movingAverage;
@end
과 꼬마 도깨비 파일 :
#import "MovingAverage.h"
@implementation MovingAverage
-(id)initWithSize:(int)size {
if (self = [super init]) {
samples = [[NSMutableArray alloc] initWithCapacity:size];
sampleCount = 0;
averageSize = size;
}
return self;
}
-(void)addSample:(double)sample {
int pos = fmodf(sampleCount++, (float)averageSize);
[samples setObject:[NSNumber numberWithDouble:sample] atIndexedSubscript:pos];
}
-(double)movingAverage {
return [[samples valueForKeyPath:@"@sum.doubleValue"] doubleValue]/(sampleCount > averageSize-1?averageSize:sampleCount);
}
@end
안녕하세요! 방금 당신의 솔루션을 시도했습니다. 이것은 샘플 크기가 5 일 때만 잘 작동합니다. 그보다 큰 값 (예 : 10, 20 정도)을 설정하면 값이 감소합니다. 예 : 매번 const == 10을 추가합니다. 이동 평균은 샘플 크기가 5 일 때만 10을 반환합니다. 10은 5, 20 - 2.5입니다. 그 맞습니까? –
방금 대답을 편집했습니다 : int pos = fmodf (sampleCount ++, 5.0); ~ int pos = fmodf (sampleCount ++, (float) averageSize); 기본적으로 fmodf는 이동 평균의 샘플 수를 기준으로 mod이어야합니다. 세네 스를 만드시겠습니까? – earnshavian
그건 완벽하게 이해가됩니다! 감사. –
'[queue dequeue] 란 무엇을 의미합니까? – progrmr
@progrmr : 내 Objective-C 구문이 녹슬니다. 나는 'dequeue'라는 메시지를 'queue'객체에 보냈습니다. 즉, 어떻게 든 큐를 구현한다고 가정하고 있거나 기존 큐 클래스 중 하나를 사용합니다 (있는 경우). – ArjunShankar