(n ^ 2 + n) / 2 성장률을 가진 알고리즘에 대한 Big O 질문


16

큰 O 표기법에 관한 한 가지 측면에 대해 혼란 스럽기 때문에이 질문을하고 있습니다.

Frank Carrano의 Java데이터 구조 및 추상화 책을 사용하고 있습니다. "알고리즘 효율성"장에서 다음 알고리즘을 보여줍니다.

int sum = 0, i = 1, j = 1
for (i = 1 to n) {
    for (j = 1 to i)
        sum = sum + 1
}

그는 처음에이 알고리즘을 (n 2  + n) / 2 의 성장률로 설명합니다 . 어느 것을 보면 직관적 인 것처럼 보입니다.

그러나, n 이 클 때 (n 2  + n) / 2n 2 처럼 행동 한다고 명시되어있다 . 같은 단락에서 그는 (n 2  + n) / 2n 2 / 2 와 매우 유사하게 동작 한다고 말합니다 . 그는 이것을 사용하여 위의 알고리즘을 O (n 2 ) 로 분류합니다 .

백분율 ( n)n 이 거의 차이가 없기 때문에 (n 2  + n) / 2n 2 / 2 와 유사 하다는 것을 알았습니다 . 내가 얻지 못하는 것은 n 이 클 때 (n 2  + n) / 2n 2 가 비슷한 이유 입니다.

예를 들어, n = 1,000,000 인 경우 :

(n^2 + n) / 2 =  500000500000 (5.000005e+11)
(n^2) / 2     =  500000000000 (5e+11)
(n^2)         = 1000000000000 (1e+12)

마지막 것은 전혀 비슷하지 않습니다. 사실, 그것은 분명히 중간 크기 의 두 배 입니다. Frank Carrano는 어떻게 비슷하다고 말할 수 있습니까? 또한 알고리즘은 O (n 2 ) 로 어떻게 분류됩니까 ? 그 내부 루프를 보면 그것이 n 2 + n / 2 라고 말할 것입니다.


당신이 관심이 있다면 실행 트리 다이어그램 검사와 세 개의 중첩 루프에 대한 답변을 제공 중첩 루프와 관련된 퍼즐
Grijesh Chauhan



1
기본적으로 아이디어는 n'n ^ 2'함수와 함수가 모두 커짐에 따라 비슷하게 동작하므로 성장 속도에 지속적인 차이가 있다는 것입니다. 복잡한 표현이 있으면 더 빨리 자라는 기능이 지배적입니다.
AK_

1
@MichaelT : 다른 질문은 단지 잘못 계산하는 문제이기 때문에 이것이 그 질문의 복제본이라고 생각하지 않습니다. 이것은 왜 더 작은 항 (특히, 승수와 낮은 다항식)이 무시되는지에 대한 더 미묘한 질문입니다. 여기서 질문자는 다른 질문에서 제기 된 문제를 이미 이해하고 있으며, 그 질문에 충분한 답변은이 질문에 답변하지 않습니다.
sdenham

답변:


38

알고리즘의 Big-O 복잡도를 계산할 때 표시되는 것은 알고리즘을 실행하는 요소 수가 증가하면 실행 시간 증가에 가장 크게 기여하는 요소입니다.

복잡한 알고리즘을 가지고 있고 (n^2 + n)/2요소 수를 두 배로 2늘리면 상수 가 실행 시간의 증가에 영향을 미치지 않으며,이 용어 n는 실행 시간이 두 배가되고이 용어 는 실행 n^2이 4 배 증가합니다. 시각.
는 AS n^2기간이 가장 큰 공헌을 가지고, 큰-O의 복잡성이다 O(n^2).


2
나는 그것을 좋아합니다. 조금 더 명확 해지고 있습니다.
Andrew S

7
이것은 매우 손이 흔들립니다. 사실 일 수도 있고 틀릴 수도 있습니다. 약간의 수학을 할 수 있다면 아래 답변 중 하나를 참조하십시오.
usr

2
이 추론은 너무 모호하다 : 그것은 우리가 결론을 내릴 수 있다는 것을 의미 할 것이다 O(n * log n) = O(n).
cfh

가장 정확한 답이 아니거나 의미 적으로 정확하지 않을 수도 있지만 여기서 중요한 것은 그것이 핵심 요점을 이해하기 시작했으며 저자의 목표라고 생각합니다. 세부 사항이 종종 핵심 원칙을 혼란스럽게 할 수 있기 때문에 의도적으로 모호합니다. 나무의 나무를 보는 것이 중요합니다.
Andrew S

바트는 실제로 요인이 아닌 용어에 대해 이야기하고있었습니다. 그것을 이해하면 결론을 내릴 수 없습니다 O(n * log n) = O(n). 이것이 정의의 근거에 대한 좋은 설명을 제공한다고 생각합니다.
Mark Foskey

10

정의는

f(n) = O(g(n))

만약 상수 n이 0보다 큰 상수가 존재한다면, n이 어떤 n_0보다 큰 경우에는

|f(n)| <= C * |g(n)|

상수 C가 2가되어야하는 f (n) = n ^ 2 및 g (n) = 1/2 n ^ 2의 경우에는 이것이 사실입니다. 또한 f (n) = n ^의 경우도 마찬가지입니다. 2 및 g (n) = 1/2 (n ^ 2 + n).


4
"일정한 모든 n을 갖는 상수 C> 0가 존재하는 경우" "일정한 C를 종료하면 모든 n> n_0에 해당하는 n_0"
Taemyr

@Taemyr : 함수 g가 0이 아닌 한, 상수 C를 늘려서 유한하게 많은 첫 n_0 값에 대해 명령문을 참으로 만들 수 있으므로 실제로 필요하지 않습니다.
cfh

아니요, 함수를 살펴보면 유한 한 수의 n_0 값이 없습니다.
Taemyr

@Taemyr : n_0은 유한 숫자입니다. C = max {f (i) / g (i) : i = 1, ..., n_0}을 선택하면 쉽게 확인할 수 있으므로 명령문은 항상 첫 번째 n_0 값을 유지합니다.
cfh

CS에서 n은 일반적으로 입력 크기이므로 신중하지 않기 때문에 걱정할 필요가 없습니다. 어떤 경우에는 n_0 = 1이 작동하도록 C를 선택할 수 있습니다. 그러나 공식적인 정의는 일부 임계 값보다 큰 n이므로 정의를 적용 할 때 많은 nitpicking을 제거합니다.
Taemyr

6

복잡성에 대해 이야기 할 때 요소 수 ( n)를 기준으로 한 시간 요소 변경에만 관심이 있습니다.

따라서 2여기에서 와 같이 상수를 제거 할 수 있습니다 .

이것으로 당신을 떠납니다 O(n^2 + n).

이제 합리적으로 큰 n제품의 경우 즉 n * n, 제품 이 단순히보다 크게 커지 n므로 해당 부분을 건너 뛸 수있는 이유가 실제로 최종 복잡성으로 남습니다 O(n^2).

작은 숫자의 경우 큰 차이가있을 수 있지만, 이것이 커질수록 조금 더 n작아집니다.


차이가 한계가 되려면 n이 얼마나 커야합니까? 또한 왜 / 2가 제거되어 존재의 가치가 절반입니까?
Andrew S

6
@AndrewS Big O Notation이 성장에 대해 이야기하기 때문에. 2로 나누는 것은 궁극적으로 성장률을 변경하지 않기 때문에 벤치 마크 및 타임 스탬프와 관련이 없습니다. 그러나 가장 큰 구성 요소는 그렇게하므로 이것이 전부입니다.
Neil

2
@ 닐, 너무나 분명하다. 나는 그 책들이 그렇게 되었으면 좋겠다. 때로는 필자들이 단순한 필사자들이 그들의 기능적 지식을 갖고 있지 않기 때문에 중요한 점을 명확하게 밝히지 않고 대신 공식적인 수학적 설명에 묻거나 암시한다고 믿는 것을 모두 생략한다는 것을 저자가 너무 많이 알고 있다고 생각합니다.
앤드류 S

이 답변을 두 번 이상 공표 할 수 있기를 바랍니다. @ Neil, Big O 책을 쓰고 있어야합니다.
Tersosauros

3

"(n² + n) / 2는 n이 클 때 n²처럼 행동한다"는 것이 아니라, n이 증가함에 따라 (n² + n) / 2 처럼 커진다 .

예를 들어, n이 1,000에서 1,000,000으로 증가함에 따라

(n² + n) / 2  increases from  500500 to  500000500000
(n²) / 2      increases from  500000 to  500000000000
(n²)          increases from 1000000 to 1000000000000

마찬가지로, n이 1,000,000에서 1,000,000,000으로 증가함에 따라

(n² + n) / 2  increases from  500000500000 to  500000000500000000
(n²) / 2      increases from  500000000000 to  500000000000000000
(n²)          increases from 1000000000000 to 1000000000000000000

그것들은 비슷하게 자라서 Big O Notation이 중요합니다.

Wolfram Alpha 에서 (n² + n) / 2 및 n² / 2플로팅 하면 n = 100으로 구분하기가 너무 유사합니다. 당신이 경우 볼프람 알파의 세 가지를 모두 플롯 , 당신은 2의 일정한 비율에 의해 분리 된 두 개의 라인을 참조하십시오.


이것은 좋으며 나에게 매우 분명합니다. 답장을 보내 주셔서 감사합니다.
Andrew S

2

큰 O 표기법을 조금 더 해결 해야하는 것처럼 보입니다 . 이 표기법이 얼마나 편리한 지, 등호를 사용하여 함수의 평등을 나타내는 데 사용되지 않기 때문에 오해의 소지가 있습니다.

아시다시피,이 표기법은 함수의 점근 적 비교를 표현하고, 쓰기 F = O (g) 것을 의미 F (n은) 빨리 대부분에서 성장 g (N) 으로 n은 무한대로 이동합니다. 이것을 번역하는 간단한 방법은 함수 f / g 가 제한 되어 있다고 말하는 것입니다 . 물론, 우리는 g 가 0 인 곳을 돌봐야 하며 거의 모든 곳에서 읽을 수있는보다 강력한 정의로 끝납니다 .

이 표기법은 컴퓨팅에 매우 편리한 것으로 밝혀졌습니다. 이것이 매우 널리 퍼져있는 이유입니다. 그러나 함수 의 동등성을 나타내지 않는 등호는주의해서 다루어야 합니다 . 이것은 2 = 5 mod 32 = 5를 의미하지 않으며 대수학에 관심이 있다면 실제로 큰 O 표기법을 평등 모듈로 무언가로 이해할 수 있습니다.

이제 특정 질문으로 돌아가려면 몇 가지 숫자 값을 계산하고 비교하는 것이 전혀 쓸모가 없습니다. 그러나 백만 개가 크면 점근 적 행동을 설명하지 않습니다. 함수 f (n) = n (n-1) / 2g (n) = n²의 비율을 플로팅하는 것이 더 유용 하지만이 특별한 경우에는 f (n) / g (n) n> 0 인 경우 f = O (g) 인 경우 1/2 보다 작습니다 .

표기법에 대한 이해를 높이려면

  • 유사 항목을 기반으로 퍼지 인상이 아닌 깔끔한 정의로 작업 하십시오. 방금 경험 한 것처럼 퍼지 인상은 제대로 작동하지 않습니다.

  • 시간을내어 세부 사항에 대한 예제를 작성하십시오. 일주일에 5 개 정도의 사례 만 연습하면 자신감을 향상시키기에 충분합니다. 이것은 확실히 가치있는 노력입니다.


대수 측 참고 하면 , A는 모든 함수의 대수이다 Ν → ΝC 경계 기능의 subalgebra 함수 주어진 F 에 속하는 기능의 집합 O (F)를 A는 C에서 의 -submodule 큰에서, 그리고 연산 규칙 O 표기법 은 이러한 서브 모듈에서 A 가 어떻게 작동 하는지 설명합니다 . 따라서, 우리가 보는 평등 은 AC 서브 모듈의 평등이며 , 이것은 또 다른 종류의 계수입니다.


1
그 위키 백과 기사는 첫 번째 작은 조각 후에 따라 가기가 어렵습니다. 이 책은 성취 된 수학자에 의해 쓰여졌으며 백과 사전 기사에서 기대할 수있는 입문용 텍스트가 아닙니다. 모든 것이 좋지만 통찰력을 가져 주셔서 감사합니다.
Andrew S

위키 백과의 텍스트에서 수준을 과대 평가했습니다! :) 확실히 잘 작성되지 않았습니다. Graham, Knuth 및 Patashnik은 CS 학생들을위한 멋진 책“콘크리트 수학”을 썼습니다. 또한“컴퓨터 프로그래밍 기술”이나 50 년대 (Hardy & Wright, Rose)로 쓰여진 숫자 이론 책을 사용해보십시오. 전체 책을 읽을 필요는 없습니다. 하나를 선택하면 점근선에 대한 부분 만! 그러나 당신이 이해해야 할 양을 결정하기 전에. :)
Michael Le Barbier Grünewald

1

나는 당신이 큰 O 표기법의 의미를 오해한다고 생각합니다.

O (N ^ 2)를 보면 기본적으로 문제가 10 배나 커지면 해결 시간은 10 ^ 2 = 100 배가됩니다.

방정식에서 1000과 10000을 펀치합시다 : 1000 : (1000 ^ 2 + 1000) / 2 = 500500 10000 : (10000 ^ 2 + 10000) / 2 = 50005000

50005000/500500 = 99,91

따라서 N은 10 배 커졌지 만 솔루션은 100 배 커졌습니다. 따라서 동작 : O (N ^ 2)


1

n이 1,000,000그때라면

(n^2 + n) / 2  =  500000500000  (5.00001E+11)
(n^2) / 2      =  500000000000  (5E+11)
(n^2)          = 1000000000000  (1E+12)

1000000000000.00 무엇?

복잡성으로 인해 실제 비용 (시간 복잡성 또는 공간 복잡성에 따라 몇 초 또는 바이트)을 예측할 수 있지만 몇 초나 다른 특정 단위는 제공하지 않습니다.

그것은 우리에게 어느 정도의 비례를줍니다.

알고리즘이 n² 번 무언가를 수행해야하는 경우, 각 반복에 걸리는 시간 인 c 값에 대해 n² × c가 소요됩니다.

알고리즘이 n² ÷ 2 배의 작업을 수행해야하는 경우 각 반복에 걸리는 시간의 두 배인 c의 일부 값에 대해 n² × c가 필요합니다.

어느 쪽이든, 걸리는 시간은 여전히 ​​n²에 비례합니다.

이제 이러한 상수 요소는 우리가 무시할 수있는 것이 아닙니다. 실제로 O (n²) 복잡도를 가진 알고리즘이 O (n) 복잡도를 가진 알고리즘보다 더 나은 경우를 가질 수 있습니다. 작은 수의 항목을 작업하는 경우 상수 요소의 영향이 더 크고 다른 문제를 압도 할 수 있기 때문입니다 . (실제로 O (n!)조차도 n 값이 충분히 낮은 경우 O (1)과 동일합니다).

그러나 그들은 복잡성이 우리에게 말하는 것이 아닙니다.

실제로 알고리즘 성능을 향상시킬 수있는 몇 가지 방법이 있습니다.

  1. 각 반복의 효율성을 향상시킵니다. O (n²)는 여전히 n² × c 초 안에 실행되지만 c는 더 작습니다.
  2. 보이는 사례 수를 줄이십시오. O (n²)는 여전히 n² × c 초 안에 실행되지만 n은 더 작습니다.
  3. 알고리즘을 결과는 같지만 복잡성이 낮은 알고리즘으로 대체하십시오. 예를 들어 O (n²)를 O (n log n)로 대체 할 수 있고 n² × c₀ 초에서 (n log n) × c₁ 초로 변경 한 경우 .

또는 다른 방식으로 살펴 보려면 f(n)×c몇 초가 걸리므로 주어진에 대한 수익을 c줄이거 n나 줄이거 나 줄임 으로써 성능을 향상시킬 수 있습니다 .fn

우리는 루프 내부의 마이크로 선택이나 더 나은 하드웨어를 사용하여 가장 먼저 할 수 있습니다. 항상 개선 될 것입니다.

두 번째로, 모든 것이 검사되기 전에 알고리즘을 단락시킬 수있는 경우를 식별하거나 중요하지 않은 일부 데이터를 필터링 할 수 있습니다. 이를 수행하는 비용이 이익을 능가하는 경우에는 개선되지 않지만 일반적으로 첫 번째 경우보다 더 큰 개선이 될 것입니다. 특히 n이 큰 경우.

세 번째는 다른 알고리즘을 완전히 사용하여 수행 할 수 있습니다. 전형적인 예는 버블 정렬을 퀵 정렬로 교체하는 것입니다. 요소 수가 적 으면 상황이 악화 될 수 있지만 (c₁가 c₀보다 큰 경우) 일반적으로 특히 n이 큰 경우 가장 큰 이득을 얻을 수 있습니다.

실제 사용에서 복잡성 측정을 통해 알고리즘 간의 차이점에 대해 정확하게 추론 할 수 있습니다. 알고리즘이 n 또는 c를 줄이는 데 도움이되는 문제를 무시하고 시험에 집중하기 때문입니다. f()


"O (n!)은 n의 값이 충분히 낮은 경우 O (1)과 같습니다"는 잘못되었습니다. " n충분히 낮게 유지되면 Big-O는 중요하지 않다 "고 설명하는 더 좋은 방법이 있어야합니다 .
Ben Voigt

@BenVoigt 나는 이것을 처음 읽을 때와 같은 수사 학적 영향을 미쳤습니다. 그것은 원래 내 것이 아닙니다. 에릭 리퍼 트에서 훔쳤습니다. 물론 그것은 더 오래된 "π의 작은 값 π와 큰 값 3의 3"과 같은 농담을 언급합니다.
Jon Hanna

0

상수 요인

큰 O 표기법의 요점은 O (함수 (n))가 항상 C * 함수 (n)보다 크도록 임의로 큰 상수를 선택할 수 있다는 것입니다. 알고리즘 A가 알고리즘 B보다 10 억 배 느리면 n이 임의로 커질 때 차이가 커지지 않는 한 동일한 O 복잡도를 갖습니다.

개념을 설명하기 위해 1000000의 상수 팩터를 가정 해 봅시다. 필요보다 백만 배나 크지 만, 그것이 관련성이 없다고 여겨지는 점을 보여줍니다.

(n ^ 2 + n) / 2 "내부 적합"O (n ^ 2) n에 관계없이 (n ^ 2 + n) / 2 <1000000 * n ^ 2.

(n ^ 2 + n) / 2 일부 값 (n ^ 2 + n) / 2> 1000000 * n이므로 더 작은 세트 (예 : O (n))에 "적합하지 않습니다".

상수 인자는 임의로 클 수 있습니다. n 년의 실행 시간을 갖는 알고리즘은 n * log (n) 마이크로 초의 실행 시간을 갖는 알고리즘보다 "더 나은"O (n) 복잡도를 갖습니다.


0

Big-O는 알고리즘이 얼마나 "복잡한 지"에 관한 것입니다. 두 알고리즘을 가지고 있고, 하나가 걸리는 경우 n^2*k실행 초, 다른 소요 n^2*j실행 초, 당신은 하나가 더있는에 대해 주장 할 수 있으며, 영향을하려고 몇 가지 흥미로운 최적화를 할 수 있습니다 k또는 j, 그러나 모두 이러한 알고리즘은 n*m실행 되는 알고리즘과 비교하여 속도가 느립니다 . 상수를 작게 만드는 것은 중요하지 않습니다. k또는 j충분히 큰 입력의 경우 n*m알고리즘이 항상 m큰 경우에도 알고리즘이 항상 이깁니다 .

그래서 우리는 처음 두 알고리즘 O(n^2)을 호출하고 두 번째 알고리즘 을 호출합니다 O(n). 세계 를 알고리즘 클래스 로 멋지게 나눕니다 . 이것이 big-O의 모든 것입니다. 그것은 차량을 자동차와 트럭, 버스 등으로 나누는 것과 같습니다. 차량 간에는 많은 차이가 있으며, 프리우스가 시보레 볼트보다 더 좋은지에 대해 논쟁하면서 하루 종일 보낼 수 있습니다. 12 명을 하나로 묶어야한다면 이것은 의미없는 주장입니다. :)

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.