내 기능의 시간은 무엇입니까? [복제]
이 질문에 이미 답변이 있습니다.
- 알고리즘의 시간 알고리즘을 찾는 방법 9 답변
- Big O, 어떻게 계산 / 근사화 사용량? 23 답변
- 고조파 시리즈 2 답변 의 Big O 찾기
설치하고있는 곳에서 공부하기 시작합니다.
void what(int n) {
int i;
for (i = 1; i <= n; i++) {
int x = n;
while (x > 0)
x -= i;
}
}
음, 첫 번째 for 루프는 분명히 O(n)
. 첫 번째 반복은 O(n)
두 번째이며, O(n/2)
.. 그리고 같은 log(n)
시간 것 같아요? 즉 . 이게 맞았나요?O(n) * O(log(n)) = O(n * log(n)) complexity
편집 : (중복이 아님) Big O가 무엇인지 압니다. 올바른 경우에 올바른 평가를 요청했습니다.
루프는 외부 n
time-을 실행 합니다.
반복에 대해 각 내부 루프가 여러 n / i
번 실행 됩니다.
총 실행 횟수는 다음과 가변적입니다.
n + n/2 + n/3 + ... + n/n
점근 적으로 (정수 산술 반올림 무시) 다음과 같이 단순화됩니다.
n * (1 + 1/2 + 1/3 + ... + 1/n)
이 시리즈는 n * log(n)
.
예상 대로 O (N.log (N)) 입니다.
내부 루프-th 첫 실행 n
time-
두-th 내부 루프 실행 n/2
time-
세-th 내부 루프 실행 n/3
time-
.. 마지막 루프는 한 번 실행
그래서 n + n/2 + n/3 + ... + 1 = n(1+1/2+1/3+1/4 + ... +1/n)
.
이것은 n에 고조파 시리즈의 합을 곱한 것입니다. 이것은 멋진 닫힌 형태 표현을 가지고 있습니다. 같이 그러나 여기 그것은이다 O(log(n))
. 그래서 전반적으로 알고리즘은O(n log(n))
대안으로, 알고리즘 y = n - x
내부 while
루프의 반복 횟수를 분석하기 위해 변수 대체 다음에 시그마 표기법을 사용하십시오 .
위의 내용은 각 내부 루프에 잠시 1
대해 n-1
의 배수가 아닌 경우 i
, 즉 경우 의 반복 횟수를 과대 평가 (n-1) % i != 0
합니다. 계속 진행 (n-1)/i
하면서 모든 값에 대해 정수 라고 가정 i
에서는 내부 while
루프 의 총 반복 횟수를 과대 평가하고 이후에 아래 (i)
에 작거나 등호를 포함합니다 . 시그마 표기법 분석을 진행합니다.
여기서 우리 는 관련 적분에 의해 : th 고조파 수 를 (ii)
근사화했습니다 . 알고리즘은에서 따라서 점근 적으로 실행됩니다 .n
O(n·ln(n))
점근 적 동작을 떠나 알고리즘의 실제 성장을 연구하면 @chux (그의 답변 참조)에 의해 정확한 (n,cnt)
( cnt
내부 반복 수) 쌍 의 멋진 샘플 데이터를 사용하고 위에서 추정 된 반복 횟수와 비교할 수 있습니다. 즉, n(1+ln(n))-ln(n)
. 추정치가 실제 개수와 깔끔하게 조화를 이루는 것이 분명합니다 . 실제 숫자 는 아래 플롯 이나이 스 니펫을 참조하세요 .
마지막으로 위 n->∞
의 합계를 입력 1/i
하면 결과 시리즈는 무한 고조파 시리즈 가되는데, 이는 흥미롭게도 충분히 발산합니다. 후자의 증거는 0이 아닌 항의 무한한 합에서 자연적으로 그 자체가 무한하다는 사실을 사용합니다. 그러나, 실제로는 A에 대한 충분히 크지 만 무한하지 N , ln(n)
합계 적절한 근사치이며,이 차이는 다음은 점근 적 분석에 대한 중요한 아니다.
테스트 및 그래픽으로 시도합니다. log2 대 log2 플롯은 상당히 선형 적으로 보입니다. 선형 O (n)보다 크고 O (n * log (n))보다 작은 것. 자신의 결론을 "그리십시오".
[편집하다]
수학적 파생 공식을 사용하여 계산 된 O ()는 O (n * log (n))의 상한입니다. 이것은 1이 아닌 분수 번호를 증가시키는 "루프 반복의 분수"를 사용합니다. 예를 들어 n
6 일 때 , 일련의 발표는 실제 6 + 3 + 2 +가 아닌 6 + 3 + 2 + 1.5 + 1.2 + 1 = 14.7 루프입니다. 2 + 2 + 1 = 16.이 차이는 n
증가할수록 최후의 덜 중요 O (n * log (n)) 증가보다 약간 적습니다. 따라서 코드를 무시하지 않고 정수를 사용하면 훨씬 더 어려운 질문이 생깁니다.
unsigned long long what(int n) {
unsigned long long cnt = 0;
int i;
for (i = 1; i <= n; i++) {
int x = n;
while (x > 0) {
x -= i;
cnt++;
}
}
return cnt;
}
void wtest(int n) {
unsigned long long cnt = what(n);
printf("%d %llu\n", n, cnt);
fflush(stdout);
}
void wtests(void) {
int i = INT_MAX/2 + 1;
while (i > 0) {
wtest(i);
i /= 2;
}
}
int main(void) {
wtests();
return 0;
}
많이
1073741824 23567395117
536870912 11411566988
268435456 5519718329
134217728 2666826555
67108864 1286897093
33554432 620190504
16777216 298466265
8388608 143418602
4194304 68802063
2097152 32947406
1048576 15746897
524288 7510048
262144 3573331
131072 1695816
65536 802493
32768 378537
16384 177921
8192 83286
4096 38803
2048 17973
1024 8275
512 3782
256 1713
128 765
64 337
32 145
16 61
8 24
4 9
2 3
1 1
참고 URL : https://stackoverflow.com/questions/35326140/what-is-the-time-complexity-of-my-function
'IT' 카테고리의 다른 글
Android 4.2 API 설치 문제 (0) | 2020.09.06 |
---|---|
"Arrange-Assert-Act-Assert"내에 삽입? (0) | 2020.09.05 |
Java에 버퍼 오버 플로우가 있습니까? (0) | 2020.09.05 |
ACE vs Boost vs POCO (0) | 2020.09.05 |
iPhone Simulator에서 생성 된 충돌 로그? (0) | 2020.09.05 |