[algorithm] “Big O”표기법에 대한 일반적인 영어 설명은 무엇입니까?

가능한 한 공식적인 정의와 간단한 수학을 선호하지 않습니다.



답변

참고로, 이것은 Big O 표기법 (상한)과 Theta 표기법 “Θ”(양쪽 바운드)와 혼동 될 수 있습니다. 내 경험상, 이것은 실제로 비 학술적 환경에서의 토론에서 일반적입니다. 혼란에 대한 사과.


이 그래프를 통해 큰 O 복잡성을 시각화 할 수 있습니다.

큰 O 분석

Big-O 표기법에 대한 가장 간단한 정의는 다음과 같습니다.

Big-O 표기법은 알고리즘의 복잡성을 나타내는 상대적인 표현입니다.

그 문장에는 중요하고 일부러 선택된 단어가 있습니다.

  • 상대 : 사과와 사과 만 비교할 수 있습니다. 산술 곱셈을 수행하는 알고리즘을 정수 목록을 정렬하는 알고리즘과 비교할 수 없습니다. 그러나 산술 연산을 수행하는 두 알고리즘 (하나의 곱셈, 하나의 덧셈)을 비교하면 의미있는 것을 알 수 있습니다.
  • 표현 : Big-O (가장 간단한 형식)는 알고리즘 간의 단일 변수 비교를 줄입니다. 해당 변수는 관찰 또는 가정에 따라 선택됩니다. 예를 들어, 정렬 알고리즘은 일반적으로 비교 작업을 기반으로 비교됩니다 (상대 순서를 결정하기 위해 두 노드를 비교). 이것은 비교가 비싸다고 가정합니다. 그러나 비교가 저렴하지만 교환이 비싸면 어떨까요? 비교를 변경합니다. 과
  • 복잡성 : 10,000 개의 요소를 정렬하는 데 1 초가 걸리면 백만을 정렬하는 데 얼마나 걸립니까? 이 경우의 복잡성은 다른 것에 대한 상대적인 척도입니다.

나머지를 읽었을 때 되돌아 와서 위의 내용을 다시 읽으십시오.

내가 생각할 수있는 Big-O의 가장 좋은 예는 산술입니다. 두 개의 숫자 (123456 및 789012)를 사용하십시오. 우리가 학교에서 배운 기본 산술 연산은 다음과 같습니다.

  • 부가;
  • 빼기;
  • 곱셈; 과
  • 분할.

이들 각각은 작업 또는 문제입니다. 이를 해결하는 방법을 알고리즘 이라고합니다 .

추가가 가장 간단합니다. 숫자를 오른쪽으로 정렬하고 결과에 해당 추가의 마지막 숫자를 기록하는 열에 숫자를 추가합니다. 해당 숫자의 ‘수십’부분이 다음 열로 넘어갑니다.

이 숫자를 더하는 것이이 알고리즘에서 가장 비싼 연산이라고 가정 해 봅시다. 이 두 숫자를 더하기 위해서는 6 자리 숫자를 더해야합니다 (그리고 7 번째 숫자도 가능). 두 100 자리 숫자를 더하면 100을 더해야합니다. 10,000 자리 숫자를 개 더하면 10,000을 더해야합니다.

패턴을 보시겠습니까? 복잡성 (동작 횟수 인)는 자릿수에 정비례 N 보다 큰 수이다. 이것을 O (n) 또는 선형 복잡성이라고 합니다.

빼기는 비슷합니다 (캐리지 대신 빌려야 할 수도 있습니다).

곱셈이 다릅니다. 숫자를 정렬하고 맨 아래 숫자의 첫 번째 숫자를 가져 와서 맨 위 숫자의 각 숫자와 차례로 각 숫자를 곱합니다. 6 자리 숫자 두 개를 곱하려면 36 곱셈을해야합니다. 최종 결과를 얻으려면 10 또는 11 열을 추가해야 할 수도 있습니다.

100 자리 숫자가 두 개인 경우 10,000 곱하기와 200을 더해야합니다. 2 백만 자리 숫자의 경우 1 조 (10 12 ) 곱셈과 2 백만 더하기 를 수행해야 합니다.

알고리즘이 n 제곱으로 확장됨에 따라 이것은 O (n 2 ) 또는 2 차 복잡성 입니다. 또 다른 중요한 개념을 소개하기에 좋은시기입니다.

우리는 복잡성의 가장 중요한 부분에 대해서만 신경을 씁니다.

현명한 사람은 우리가 n 2 + 2n 의 연산 수를 표현할 수 있음을 깨달았을 것 입니다. 그러나 두 개의 숫자 (백만 자릿수)를 가진 예제에서 보았 듯이 두 번째 항 (2n)은 중요하지 않습니다 (해당 단계의 총 작업 중 0.0002 %를 차지함).

우리는 여기서 최악의 시나리오를 가정 한 것을 알 수 있습니다. 6 자리 숫자를 곱하는 동안 그 중 하나에 4 자리 숫자가 있고 다른 하나에 6 자리 숫자가 있으면 24 개의 곱셈 만 있습니다. 여전히, 우리는 그 ‘n’에 대한 최악의 시나리오, 즉 두 숫자가 모두 6 자리 숫자 인 경우를 계산합니다. 따라서 Big-O 표기법은 알고리즘의 최악의 시나리오에 관한 것입니다.

전화 번호부

내가 생각할 수있는 다음으로 가장 좋은 예는 전화 번호부 (일반적으로 화이트 페이지 또는 이와 유사 함)이지만 국가마다 다릅니다. 그러나 나는 성을 기준으로 사람들을 나열 한 다음 이니셜이나 이름, 주소 및 전화 번호에 대해 이야기하고 있습니다.

이제 1,000,000 개의 이름이 포함 된 전화 번호부에서 “John Smith”의 전화 번호를 찾도록 컴퓨터에 지시 한 경우 어떻게 하시겠습니까? S가 얼마나 멀리 시작했는지 추측 할 수 없다는 사실을 무시하면 (할 수 없다고 가정) 어떻게해야합니까?

일반적인 구현은 중간 정도까지 열고 500,000 번째 를 “Smith”와 비교하는 것입니다. 그것이 “Smith, John”이라면, 우리는 정말 운이 좋았습니다. “John Smith”가 그 이름 앞이나 뒤에있을 가능성이 훨씬 더 높습니다. 그런 다음 전화 번호부의 마지막 절반을 반으로 나누고 반복하십시오. 이전의 경우 전화 번호부의 전반부를 반으로 나누고 반복합니다. 등등.

이를 이진 검색 이라고하며 이를 인식하는지 여부에 관계없이 매일 프로그래밍에 사용됩니다.

따라서 백만 개의 전화 번호부에서 이름을 찾으려면 실제로 최대 20 회 수행하여 이름을 찾을 수 있습니다. 검색 알고리즘을 비교할 때 우리는이 비교가 ‘n’이라고 결정합니다.

  • 이름이 3 개인 전화 번호부의 경우 최대 2 개의 비교가 필요합니다.
  • 7의 경우 최대 3이 걸립니다.
  • 15의 경우 4가 걸립니다.
  • 1,000,000의 경우 20이 걸립니다.

정말 대단하지 않습니까?

Big-O 용어에서 이것은 O (log n) 또는 로그 복잡도 입니다. 이제 해당 로그는 ln (base e), log 10 , log 2 또는 다른 염기가 될 수 있습니다. O (2n 2 )와 O (100n 2 )가 여전히 O (n 2 ) 와 마찬가지로 여전히 O (log n)인지는 중요하지 않습니다 .

이 시점에서 Big O를 사용하여 알고리즘으로 세 가지 경우를 결정할 수 있다고 설명하는 것이 좋습니다.

  • 최상의 경우 : 전화 번호부 검색에서 가장 좋은 경우는 한 번의 비교에서 이름을 찾는 것입니다. 이것은 O (1) 또는 일정한 복잡성입니다 .
  • 예상 사례 : 위에서 논의한 바와 같이 이것은 O (log n)입니다. 과
  • 최악의 경우 : 이것은 또한 O (log n)입니다.

일반적으로 우리는 최선의 경우에 관심이 없습니다. 우리는 예상과 최악의 경우에 관심이 있습니다. 때로는 이들 중 하나가 더 중요 할 것입니다.

전화 번호부로 돌아갑니다.

전화 번호가 있고 이름을 찾으려면 어떻게합니까? 경찰은 전화 번호부를 역으로 가지고 있지만 일반인에게는 이러한 조회가 거부됩니다. 아니면 그들입니까? 기술적으로 일반 전화 번호부에서 번호 조회를 반대로 할 수 있습니다. 어떻게?

이름에서 시작하여 숫자를 비교하십시오. 일치하는 게임이라면 그렇지 않으면 다음 게임으로 넘어갑니다. 전화 번호부가 순서 가 맞지 않기 때문에 (전화 번호로) 이 방법을 사용해야 합니다.

전화 번호가 주어진 이름을 찾으려면 (역방향 조회) :

  • 가장 좋은 경우 : O (1);
  • 예상 사례 : O (n) (50 만); 과
  • 최악의 경우 : O (n) (100,000).

여행 세일즈맨

이것은 컴퓨터 과학에서 매우 유명한 문제이며 언급 할 가치가 있습니다. 이 문제에는 N 개의 도시가 있습니다. 각 도시는 일정 거리의 도로로 1 개 이상의 다른 도시와 연결되어 있습니다. Traveling Salesman 문제는 모든 도시를 방문하는 가장 짧은 여행을 찾는 것입니다.

간단하게 들리나요? 다시 생각 해봐.

모든 쌍 사이에 도로가있는 3 개의 도시 A, B 및 C가있는 경우 다음을 수행 할 수 있습니다.

  • A → B → C
  • A → C → B
  • B → C → A
  • B → A → C
  • C → A → B
  • C → B → A

글쎄, 실제로는 그 중 일부가 동일하기 때문에 그보다 적습니다 (예 : A → B → C 및 C → B → A는 예를 들어 동일한 도로를 반대로 사용하기 때문에 동일합니다).

실제로 3 가지 가능성이 있습니다.

  • 이것을 4 개의 도시로 가져 가면 12 개의 가능성이 있습니다.
  • 5는 60입니다.
  • 6은 360이됩니다.

이것은 factorial 이라는 수학적 연산의 함수입니다 . 원래:

  • 5! = 5 × 4 × 3 × 2 × 1 = 120
  • 6! = 6 × 5 × 4 × 3 × 2 × 1 = 720
  • 7! = 7 × 6 × 5 × 4 × 3 × 2 × 1 = 5040
  • 25! = 25 × 24 ×… × 2 × 1 = 15,511,210,043,330,985,984,000,000
  • 50! = 50 × 49 ×… × 2 × 1 = 3.04140932 × 10 64

따라서 Traveling Salesman 문제의 Big-O는 O (n!) 또는 계승 또는 조합 복잡성 입니다.

200 개 도시에 도착할 때까지는 기존 컴퓨터의 문제를 해결할 충분한 시간이 우주에 남아 있지 않습니다.

생각할 것.

다항식 시간

내가 간단히 언급하고 싶은 또 다른 요점은 O (n a ) 의 복잡성을 갖는 알고리즘 은 다항식 복잡도 를 갖 거나 다항식 시간으로 해결할 수 있다는 것입니다 .

O (n), O (n 2 ) 등은 모두 다항식 시간입니다. 다항식 시간에서는 일부 문제를 해결할 수 없습니다. 이 때문에 세상에는 어떤 것들이 사용됩니다. 공개 키 암호화 가 대표적인 예입니다. 매우 큰 두 가지 주요 요소를 찾는 것은 계산 상 어렵습니다. 그렇지 않은 경우 사용하는 공개 키 시스템을 사용할 수 없었습니다.

어쨌든, 그것은 Big O (개정)에 대한 나의 (희망 평범한 영어) 설명을위한 것입니다.


답변

입력 크기에 따라 알고리즘이 어떻게 확장되는지 보여줍니다.

O (n 2 ) : 2 차 복잡성

  • 1 개 항목 : 1 초
  • 10 개 항목 : 100 초
  • 100 개 항목 : 10000 초

항목 수는 10 배 증가하지만 시간은 10 2 배 증가합니다 . 기본적으로 n = 10이므로 O (n 2 ) 는 10 2 인 스케일링 계수 n 2 를 제공합니다 .

O (n) : 선형 복잡도 로 알려진

  • 1 개 항목 : 1 초
  • 10 개 항목 : 10 초
  • 100 개 항목 : 100 초

이번에는 항목 수가 10 배 증가하여 시간도 늘어납니다. n = 10이므로 O (n)의 스케일링 계수는 10입니다.

O (1) : 상수 복잡성

  • 1 개 항목 : 1 초
  • 10 개 항목 : 1 초
  • 100 개 항목 : 1 초

항목 수는 여전히 10 배 증가하지만 O (1)의 배율은 항상 1입니다.

O (log n) : 대수 복잡성

  • 1 개 항목 : 1 초
  • 10 개 항목 : 2 초
  • 100 개 항목 : 3 초
  • 1000 개 항목 : 4 초
  • 10000 개 항목 : 5 초

계산 횟수는 입력 값의 로그만큼만 증가합니다. 따라서이 경우 각 계산에 1 초가 걸리면 입력 로그가 n필요한 시간 log n입니다.

그것이 요점입니다. 수학을 줄이면 정확히 n 2 이 아니 거나 말한 것이 아닐 수 있지만 스케일링에서 지배적 인 요소가 될 것입니다.


답변

Big-O 표기법 ( “점근선 성장”표기법이라고도 함)은 원점 근처에서 일정한 요인과 물건을 무시할 때 기능어떻게 보이는지 입니다. 우리는 그것을 어떻게 스케일 하는가 에 대해 이야기하기 위해 사용합니다 .


기초

“충분히”큰 입력을 위해 …

  • f(x) ∈ O(upperbound)f“보다 빠르지 않다”는 의미upperbound
  • f(x) ∈ Ɵ(justlikethis)f“정확히 자란다” 라는 의미justlikethis
  • f(x) ∈ Ω(lowerbound)f“보다 느리게 성장하지 않는다”는 의미lowerbound

big-O 표기법은 상수 요소를 신경 쓰지 않습니다. 함수 9x²는 “정확하게 성장합니다”라고 10x²합니다. 둘 다 큰-O하지 않습니다 점근 에 대한 표기주의를 비 점근 함수가 : ( “문제의 크기가 작은 경우 어떻게됩니까” “기원 근처 물건”또는) 물건 10x²“성장 정확히 같은”을 말한다 10x² - x + 2.

왜 방정식의 작은 부분을 무시하고 싶습니까? 더 큰 스케일을 고려할 때 방정식의 큰 부분으로 인해 왜소하게 왜곡되기 때문입니다. 그들의 기여는 왜소하고 무관심해진다. (예제 섹션 참조)

다시 말해, 무한대로 갈 때의 비율 에 관한 것 입니다. 실제 시간을로 나누면 O(...)큰 입력의 한계에 일정한 요소가 생깁니다. 직관적으로 이것은 의미가 있습니다. 함수를 곱하여 다른 함수를 얻을 수 있다면 함수는 서로 “비교”됩니다. 우리가 말할 때입니다 …

actualAlgorithmTime(N) ∈ O(bound(N))
                                       e.g. "time to mergesort N elements
                                             is O(N log(N))"

… 이것은 “충분히 큰”문제 크기 N (원점 근처의 것을 무시하는 경우)에 대해 다음과 같은 상수 (예 : 2.5, 완전히 구성됨)가 있음을 의미합니다.

actualAlgorithmTime(N)                 e.g. "mergesort_duration(N)       "
────────────────────── < constant            ───────────────────── < 2.5
       bound(N)                                    N log(N)

많은 상수 선택이 있습니다. 종종 “최상의”선택은 알고리즘의 “일정한 요인”으로 알려져 있지만 가장 큰 용어를 무시하는 것처럼 종종 무시합니다 (일반적으로 중요하지 않은 이유는 상수 요인 섹션 참조). 또한 “며 바운드로 위의 방정식 생각할 수있는 , 걸리는 시간은 약보다 더 없을 것 최악의 경우 N*log(N)(일정한 요인은 우리가 많이 걱정하지 않는다) 2.5 배 내 ” .

일반적으로 O(...)최악의 행동에 관심을 갖기 때문에 가장 유용합니다. f(x)프로세서 나 메모리 사용량과 같이 “나쁜”것을 나타내는 경우 ” f(x) ∈ O(upperbound)“는 ” upperbound가 프로세서 / 메모리 사용량의 최악의 시나리오 “를 의미 합니다.


응용

순전히 수학적 구성으로서, big-O 표기법은 처리 시간과 메모리에 관해 이야기하는 것으로 제한되지 않습니다. 이를 사용하여 다음과 같이 스케일링이 의미가있는 모든 경우의 증상에 대해 논의 할 수 있습니다.

  • N파티에서 사람들 사이에 가능한 핸드 셰이크 수 ( Ɵ(N²)특히 N(N-1)/2, “스케일”과 같은 것이 중요합니다 )
  • 바이러스 성 마케팅을 시간의 함수로 본 확률 론적 예상 인원
  • 웹 사이트 대기 시간이 CPU 또는 GPU 또는 컴퓨터 클러스터의 처리 장치 수에 따라 확장되는 방법
  • 트랜지스터 카운트, 전압 등의 함수로 CPU에서 열 출력 스케일링이 어떻게 감소하는지
  • 입력 크기의 함수로 알고리즘을 실행해야하는 시간
  • 입력 크기의 함수로 알고리즘을 실행해야하는 공간

위의 핸드 셰이크 예에서는 방의 모든 사람이 다른 사람의 손을 흔 듭니다. 이 예에서는 #handshakes ∈ Ɵ(N²). 왜?

약간 백업하십시오 : 악수의 수는 정확히 n-choose-2 또는 N*(N-1)/2(각 N 명의 사람들이 다른 사람들의 N-1 악수를하지만이 두 번의 악수는 2로 나눕니다) :

모두가 다른 사람을 악수합니다.  Wikipedia / Wikimedia commons "완전한 그래프"기사당 이미지 크레딧 및 라이센스. 인접 행렬

그러나 매우 많은 수의 사람들의 경우 선형 항 N은 왜소 해져서 비율에 0을 효과적으로 기여합니다. 따라서 스케일링 동작은 order N²또는 “N²처럼 커지는 핸드 셰이크 수”입니다.

#handshakes(N)
────────────── ≈ 1/2
     N²

마치 차트의 대각선에있는 빈 상자 (N * (N-1) / 2 확인 표시)가없는 것처럼 보입니다 (N 2 확인 표시가 그대로 표시됨).

( “일반 영어”의 일시적인 위반 🙂 이것을 스스로 증명하고 싶다면, 여러 대수로 나누기 위해 비율에 대한 간단한 대수를 수행 할 수 있습니다 ( lim“한도에서 고려 됨”을 의미 함). 그것을 보지 못했다면, 그것은 단지 “N은 정말로 크다”라는 표기입니다.

    N²/2 - N/2         (N²)/2   N/2         1/2
lim ────────── = lim ( ────── - ─── ) = lim ─── = 1/2
N→∞     N²       N→∞     N²     N²      N→∞  1
                               ┕━━━┙
             this is 0 in the limit of N→∞:
             graph it, or plug in a really large number for N

tl; dr : 큰 값의 경우 핸드 셰이크 수 ‘x²’가 너무 커서 # handshakes / x² 비율을 기록하면 정확히 x² 핸드 셰이크가 필요하지 않다는 사실 조차 나타나지 않습니다. 임의로 큰 동안 10 진수로.

예 : x = 1 백만, 비율 # handshakes / x² : 0.499999 …


직관

이를 통해 다음과 같은 진술을 할 수 있습니다.

입력 크기를 충분히 크게하려면 상수 크기 가 무엇이든 입력 크기를 두 배로 늘리면 …

  • … 나는 O (N) ( “선형 시간”) 알고리즘에 걸리는 시간을 두 배로 늘 렸습니다. ”

    N → (2N) = 2 ( N )

  • … 나는 O (N²) ( “이차 시간”) 알고리즘이 걸리는 시간을 2 제곱 (사 분위수)합니다. ” (예를 들어 100x 큰 문제는 100² = 10000x 오래 걸리지 만 아마도 지속 할 수없는 문제)

    → (2N) ² = 4 ( )

  • … 나는 O (N³) ( “cubic time”) 알고리즘이 걸리는 시간을 두 배로 (옥수) 나눠 넣었습니다. ” (예를 들어 100x 큰 문제는 100³ = 1000000x 긴 시간 … 매우 지속 불가능한 문제)

    cN³ → c (2N) ³ = 8 ( cN³ )

  • … 나는 O (log (N)) ( “logarithmic time”) 알고리즘이 걸리는 시간에 고정 된 금액을 추가합니다. ” (싼!)

    c log (N) → c log (2N) = (c log (2)) + ( c log (N) ) = (고정 금액) + ( c log (N) )

  • … 나는 O (1) ( “일정 시간”) 알고리즘이 걸리는 시간을 바꾸지 않습니다. ” (가장 저렴합니다!)

    c * 1c * 1

  • … 나는 시간이 오 (N 로그 (N)) 알고리즘이 걸립니다 “(기본적으로) 두 배”. ” (매우 일반적인)

    O (N 1.000001 ) 보다 작습니다. 기본적으로 선형 호출 할 수 있습니다.

  • … 나는 엄청나게 시간에게 O (2 증가 N 알고리즘이 소요) ( “지수 시간”). ” (당신은 단지 하나의 단위로 문제를 증가) 등의 시간을 두 배 (또는 삼중 것)

    2 N → 2 2N = (4 N ) ………… 다른 방법으로 ………… 2 N → 2 N + 1 = 2 N 2 1 = 2 2 N

[수학적으로 기울어 진 경우 작은 스포일러 위로 마우스를 움직일 수 있습니다]

( https://stackoverflow.com/a/487292/711085에 크레딧으로 )

(기술적으로 상수 요소는 좀 더 난해한 예에서 중요 할 수 있지만 위의 내용을 말하지 않았습니다 (예 : log (N)) 그렇지 않습니다)

이들은 프로그래머와 응용 컴퓨터 과학자들이 참조 점으로 사용하는 빵과 버터의 성장 순서입니다. 그들은 항상 이것을 본다. (기술적으로 “입력을 두 배로하면 O (√N) 알고리즘이 1.414 배 느려진다”고 생각할 수 있지만 “로그보다 나쁘지만 선형보다는 낫다”고 생각하는 것이 좋습니다.


일정한 요인

일반적으로 특정 상수 요소가 무엇인지는 중요하지 않습니다. 함수가 성장하는 방식에 영향을 미치지 않기 때문입니다. 예를 들어, 두 알고리즘 모두 O(N)완료 하는 데 시간이 걸리지 만 하나는 다른 것보다 두 배 느릴 수 있습니다. 최적화가 까다로운 사업이기 때문에 요소가 너무 크지 않으면 우리는 일반적으로 너무 신경 쓰지 않습니다 (최적화는 언제입니까? ); 또한 더 나은 big-O로 알고리즘을 선택하는 단순한 행동은 종종 성능을 몇 배나 향상시킵니다.

무조건적으로 우수한 일부 알고리즘 (예 : 비 비교 O(N log(log(N)))정렬)은 상수 요소 (예 :)가 너무 크 100000*N log(log(N))거나 O(N log(log(N)))숨겨진 것과 같이 상대적으로 큰 오버 헤드를 가질 수 있으므로 + 100*N“빅 데이터”에서도 사용할 가치가 거의 없습니다.


O (N)이 때로는 최선 인 이유, 즉 데이터 구조가 필요한 이유

O(N)알고리즘은 모든 데이터를 읽어야하는 경우 “최상의”알고리즘입니다. 읽는 행위 자체 데이터의 무리가 있습니다 O(N)작업. 메모리에로드하는 것은 일반적으로 O(N)(또는 하드웨어를 지원하는 경우 더 빠르거나, 이미 데이터를 읽은 경우 전혀 시간이 없음) 그러나 모든 데이터 조각 (또는 다른 모든 데이터 조각) 을 만지거나 살펴보면 알고리즘 O(N)이이 모양을 수행하는 데 시간 이 걸립니다 . 실제 알고리즘이 얼마나 오래 걸리더라도 적어도 O(N)모든 데이터를 보는 데 시간 이 걸리기 때문에 시간이 많이 걸립니다.

바로 글쓰기 행위에 대해서도 마찬가지 입니다. N 개를 출력하는 모든 알고리즘은 출력 시간이 적어도 길기 때문에 N 시간이 걸립니다 (예 : N 개의 재생 카드 세트는 모든 순열을 인쇄 (재배 열하는 방법)하는 것이 중요합니다 🙂 O(N!).

이것은 데이터 구조 의 사용에 동기를 부여합니다 . 데이터 구조는 한 번만 (일반적으로 O(N)시간) 데이터를 읽고, 작게 유지하려는 임의의 양의 전처리 (예 : O(N)또는 O(N log(N))또는 O(N²))를 요구합니다. 그런 다음 데이터 구조 (삽입 / 삭제 등)를 수정하고 데이터에 대한 쿼리를 작성하는 데 시간이 거의 걸리지 않습니다 (예 : O(1)또는) O(log(N)). 그런 다음 많은 수의 쿼리를 진행합니다! 일반적으로 미리 할 일이 많을수록 나중에해야 할 일이 줄어 듭니다.

예를 들어, 수백만 개의 도로 세그먼트의 위도 및 경도 좌표가 있고 모든 거리 교차로를 찾고 싶다고 가정하십시오.

  • 순진한 방법 : 거리 교차로의 좌표가 있고 근처의 거리를 조사하려면 매번 수백만 개의 세그먼트를 거쳐 각 인접성을 확인해야합니다.
  • 이 작업을 한 번만 수행해야한다면 순진한 O(N)작업 방법을 한 번만 수행해야하는 것은 문제가되지 않지만 여러 번 (이 경우에는 N각 세그먼트에 대해 한 번씩) 수행해야합니다. O(N²)작업 또는 1000000² = 1000000000000 작업 을 수행해야 합니다. 좋지 않습니다 (현대 컴퓨터는 초당 약 10 억 번의 작업을 수행 할 수 있습니다).
  • 해시 테이블 (해시 맵 또는 사전이라고도하는 인스턴트 속도 조회 테이블)이라는 간단한 구조를 사용하는 경우 모든 것을 미리 처리하여 적은 비용을 지불합니다 O(N). 그 후, 키로 무언가를 찾는 데 평균적으로 일정한 시간이 걸립니다 (이 경우 키는 위도 및 경도 좌표이며 그리드로 반올림됩니다. 우리는 9 개만있는 인접한 그리드 공간을 검색합니다. 일정한).
  • 우리의 작업은 실행 불가능한 것에서 O(N²)관리 가능한 것 까지 진행되었으며, O(N)우리가해야 할 일은 해시 테이블을 만들기 위해 약간의 비용을 지불하는 것입니다.
  • 유추 :이 특별한 경우의 유추는 직소 퍼즐입니다. 데이터의 일부 속성을 활용하는 데이터 구조를 만들었습니다. 도로 구간이 퍼즐 조각과 같으면 색상과 패턴을 일치시켜 그룹화합니다. 그런 다음 나중에 추가 작업을 피하기 위해 (이것은 다른 모든 단일 퍼즐 조각이 아니라 서로 같은 퍼즐 조각을 비교) 피합니다.

이야기의 교훈 : 데이터 구조를 통해 작업 속도를 높일 수 있습니다. 더욱이, 고급 데이터 구조를 사용하면 믿을 수 없을 정도로 영리한 방식으로 작업을 결합, 지연 또는 무시할 수 있습니다. 다른 문제는 다른 유추가있을 수 있지만, 우리가 관심을 갖는 일부 구조를 이용하거나 부기 관리를 위해 인위적으로 부과 한 방식으로 데이터를 구성해야합니다. 사전 계획 (기본 계획 및 구성)을 수행하므로 반복 작업이 훨씬 쉬워집니다.


실제 예 : 코딩하는 동안 성장 순서 시각화

점근 적 표기법의 핵심은 프로그래밍과는 별개입니다. 점근 표기법은 다양한 분야에서 사물이 어떻게 확장되고 사용될 수 있는지에 대한 수학적 틀입니다. 그것은 말했다 … 이것은 코딩에 점근 표기법을 적용 하는 방법 입니다.

기본 사항 : 크기 A의 컬렉션 (예 : 배열, 집합, 맵의 모든 키 등)의 모든 요소와 상호 작용하거나 루프의 반복을 수행 할 때마다 크기 A의 곱셈 요소 루프와 함수 (거의 정의에 따라)에 곱하기 실행 시간이 있기 때문에 반복 횟수, 루프에서 수행 한 작업 시간 (또는 함수 : 호출 횟수) 기능, 시간은 기능에서 수행됩니다). (루프 건너 뛰기 또는 루프를 조기에 종료하거나 인수를 기반으로 함수의 제어 흐름을 변경하는 것과 같이 멋진 작업을 수행하지 않는 경우 유지됩니다. 의사 코드와 함께 시각화 기술의 몇 가지 예가 있습니다.

(여기서 xs는 상수 시간 작업 단위, 프로세서 명령어, 인터프리터 opcode 등을 나타냅니다)

for(i=0; i<A; i++)        // A * ...
    some O(1) operation     // 1

--> A*1 --> O(A) time

visualization:

|<------ A ------->|
1 2 3 4 5 x x ... x

other languages, multiplying orders of growth:
  javascript, O(A) time and space
    someListOfSizeA.map((x,i) => [x,i])
  python, O(rows*cols) time and space
    [[r*c for c in range(cols)] for r in range(rows)]

예 2 :

for every x in listOfSizeA:   // A * (...
    some O(1) operation         // 1
    some O(B) operation         // B
    for every y in listOfSizeC: // C * (...
        some O(1) operation       // 1))

--> O(A*(1 + B + C))
    O(A*(B+C))        (1 is dwarfed)

visualization:

|<------ A ------->|
1 x x x x x x ... x

2 x x x x x x ... x ^
3 x x x x x x ... x |
4 x x x x x x ... x |
5 x x x x x x ... x B  <-- A*B
x x x x x x x ... x |
................... |
x x x x x x x ... x v

x x x x x x x ... x ^
x x x x x x x ... x |
x x x x x x x ... x |
x x x x x x x ... x C  <-- A*C
x x x x x x x ... x |
................... |
x x x x x x x ... x v

예 3 :

function nSquaredFunction(n) {
    total = 0
    for i in 1..n:        // N *
        for j in 1..n:      // N *
            total += i*k      // 1
    return total
}
// O(n^2)

function nCubedFunction(a) {
    for i in 1..n:                // A *
        print(nSquaredFunction(a))  // A^2
}
// O(a^3)

약간 복잡한 작업을 수행해도 현재 상황을 시각적으로 상상할 수 있습니다.

for x in range(A):
    for y in range(1..x):
        simpleOperation(x*y)

x x x x x x x x x x |
x x x x x x x x x   |
x x x x x x x x     |
x x x x x x x       |
x x x x x x         |
x x x x x           |
x x x x             |
x x x               |
x x                 |
x___________________|

여기서 가장 작은 인식 가능한 윤곽선이 중요합니다. 삼각형은 2 차원 모양 (A ^ 2)과 마찬가지로 2 차원 모양 (0.5A ^ 2)입니다. 여기서 두 가지의 일정한 요소는 두 요소 사이의 점근 비율로 유지되지만 모든 요소와 마찬가지로 무시합니다 … (이 기술에 대한 불행한 뉘앙스가 있지만 여기에 들어 가지 않을 수 있습니다.)

물론 이것이 루프와 함수가 나쁘다는 것을 의미하지는 않습니다. 반대로, 그들은 현대 프로그래밍 언어의 빌딩 블록이며, 우리는 그것들을 좋아합니다. 그러나 데이터와 함께 루프와 함수 및 조건을 짜는 방식 (제어 흐름 등)이 프로그램의 시간과 공간 사용을 모방한다는 것을 알 수 있습니다! 시간과 공간 사용이 문제가된다면, 그것은 우리가 영리함에 의지하고 우리가 고려하지 않은 쉬운 알고리즘이나 데이터 구조를 찾아서 어떻게 든 성장 순서를 줄이는 것입니다. 그럼에도 불구하고, 이러한 시각화 기술 (항상 작동하지는 않지만)은 최악의 실행 시간에서 순진한 추측을 제공 할 수 있습니다.

시각적으로 인식 할 수있는 또 다른 사항은 다음과 같습니다.

<----------------------------- N ----------------------------->
x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x
x x x x x x x x x x x x x x x x
x x x x x x x x
x x x x
x x
x

우리는 이것을 재정렬하고 O (N)을 볼 수 있습니다 :

<----------------------------- N ----------------------------->
x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x
x x x x x x x x x x x x x x x x|x x x x x x x x|x x x x|x x|x

또는 O (N * log (N)) 총 시간 동안 데이터의 log (N) 패스를 수행 할 수 있습니다.

   <----------------------------- N ----------------------------->
 ^  x x x x x x x x x x x x x x x x|x x x x x x x x x x x x x x x x
 |  x x x x x x x x|x x x x x x x x|x x x x x x x x|x x x x x x x x
lgN x x x x|x x x x|x x x x|x x x x|x x x x|x x x x|x x x x|x x x x
 |  x x|x x|x x|x x|x x|x x|x x|x x|x x|x x|x x|x x|x x|x x|x x|x x
 v  x|x|x|x|x|x|x|x|x|x|x|x|x|x|x|x|x|x|x|x|x|x|x|x|x|x|x|x|x|x|x|x

관련이 없지만 다시 언급 할 가치가 있습니다. 해시 (예 : 사전 / 해시 테이블 조회)를 수행하는 경우 이는 O (1)의 요소입니다. 꽤 빠릅니다.

[myDictionary.has(x) for x in listOfSizeA]
 \----- O(1) ------/

--> A*1 --> O(A)

재귀 함수 또는 분할 및 정복 알고리즘과 같이 매우 복잡한 작업을 수행 하는 경우 Master Theorem (보통 작동)을 사용하거나 어리석은 경우 Akra-Bazzi Theorem (거의 항상 작동) 을 사용할 수 있습니다. Wikipedia에서 알고리즘 실행 시간.

그러나 프로그래머는 알고리즘 직관이 제 2의 본성이되기 때문에 이와 같이 생각하지 않습니다. 당신은 무언가 비효율적 인 것을 코딩하기 시작하고 즉시 ” 엄청나게 비효율적 인 일을하고 있습니까? ” 라고 생각할 것 입니다. 대답이 “예”이고 실제로 중요하다고 생각하면 한 걸음 물러나서 여러 가지 속임수를 사용하여 더 빠르게 실행할 수 있습니다 (대답은 항상 “해시 테이블 사용”, “트리 사용”은 거의 없음), 아주 조금 더 복잡한 것).


상각 및 평균 대소 문자 복잡성

“약탈 된”및 / 또는 “평균 사례”라는 개념도 있습니다 (이것은 다릅니다).

평균 사례 : 이것은 함수 자체가 아니라 함수의 예상 값에 big-O 표기법을 사용하는 것입니다. 모든 입력이 동일하게 고려되는 일반적인 경우 평균 사례는 실행 시간의 평균입니다. 예를 들어 quicksort를 사용하면 최악의 경우는 O(N^2)실제로 입력이 좋지 않은 경우에도 일반적인 경우가 일반적입니다 O(N log(N))(실제로 나쁜 입력의 수는 매우 적기 때문에 평균적으로 눈에 띄지 않습니다).

Amortized Worst-Case : 일부 데이터 구조는 최악의 경우 복잡도를 가질 수 있지만 이러한 작업을 많이 수행하면 평균적인 작업량이 최악의 경우보다 낫습니다. 예를 들어 일반적으로 일정한 O(1)시간 이 걸리는 데이터 구조가있을 수 있습니다 . 그러나 때로는 O(N)부기 또는 가비지 수집 또는 무언가를 수행해야하기 때문에 ‘딸꾹질’하고 하나의 임의 작업에 시간이 걸립니다 …하지만 딸꾹질을하면 다시 딸꾹질하지 않을 것이라고 약속합니다. 더 많은 작업. 최악의 비용은 여전히 O(N)작업 당이지만 많은 실행 에서 상각 된 비용 은 O(N)/N=O(1)작업 당. 큰 작업은 충분히 드물기 때문에 가끔씩 많은 작업이 작업의 나머지 부분과 일정한 요소로 혼합되는 것으로 간주 될 수 있습니다. 우리는 그 작업이 무의식적으로 사라지는 충분히 많은 수의 호출을 통해 “완전히 암시되어있다”고 말합니다.

상각 분석에 대한 유추 :

당신은 차를 운전합니다. 때때로, 주유소로가는 데 10 분을 소비 한 다음 탱크에 가스를 채우는 데 1 분을 소비해야합니다. 당신이 당신의 차를 가지고 어디든지 갈 때마다 (주유소까지 운전 10 분을 보내고, 몇 초를 갤런의 일부를 채우는 데)한다면, 이것은 매우 비효율적입니다. 그러나 며칠에 한 번씩 탱크를 채우면 주유소로 운전하는 데 소요 된 11 분이 충분히 많은 횟수의 여행으로 “완성”되어 무시할 수 있고 모든 여행이 5 % 더 길다고 가정 할 수 있습니다.

평균 사례와 상각 된 최악 사례의 비교 :

  • 평균 사례 : 입력에 대해 몇 가지 가정을합니다. 즉, 입력에 다른 확률이있는 경우 출력 / 런타임에 다른 확률 (평균을 취함)을 갖게됩니다. 일반적으로 입력이 모두 동일 할 가능성이 있다고 가정하지만 (실제 입력) 실제 입력이 “평균 입력”가정에 맞지 않으면 평균 출력 / 런타임 계산이 의미가 없을 수 있습니다. 균일하게 임의의 입력을 예상한다면, 이것은 생각하는 데 유용합니다!
  • 상각 최악의 데이터 구조 : 상각 최악의 데이터 구조를 사용하는 경우, 상각 최악의 데이터 범위 내에서 성능이 보장됩니다. 결국 모든 것을 알고 악의적 인 악마가 입력을 선택하더라도 당신을 망치십시오). 일반적으로 예기치 않은 큰 딸꾹질로 성능이 매우 ‘고르지 않은’알고리즘을 분석하는 데 사용되지만 시간이 지남에 따라 다른 알고리즘과 마찬가지로 성능이 향상됩니다. 그러나 데이터 구조에 미루고 자하는 뛰어난 작업에 대한 상한이없는 한 악의적 인 공격자는 한 번에 최대의 미루는 작업을 따라 잡을 수 있습니다.

공격자에 대해 합리적으로 걱정 한다면 할부 상환 및 평균 사례 외에도 걱정할 다른 알고리즘 공격 벡터가 많이 있습니다.)

평균 사례와 할부 상환은 모두 스케일링을 염두에두고 생각하고 디자인하는 데 매우 유용한 도구입니다.

이 하위 주제에 관심이있는 경우 평균 사례와 상각 분석의 차이를 참조하십시오 .


다차원 빅오

대부분의 사람들은 직장에 하나 이상의 변수가 있다는 것을 인식하지 못합니다. 예를 들어, 문자열 검색 알고리즘에서 알고리즘은 시간이 걸릴 수 있습니다 O([length of text] + [length of query]). 즉,와 같은 두 변수에서 선형입니다 O(N+M). 다른보다 순진한 알고리즘은 O([length of text]*[length of query])또는 일 수 있습니다 O(N*M). 여러 변수를 무시하는 것은 알고리즘 분석에서 볼 수있는 가장 일반적인 감독 중 하나이며 알고리즘을 설계 할 때 장애를 일으킬 수 있습니다.


전체 이야기

big-O는 전체 이야기가 아니라는 점을 명심하십시오. 캐시 대신 캐시를 사용하거나 디스크 대신 RAM을 사용하거나 병렬화를 사용하거나 미리 작업을 수행하여 병목 현상을 피함으로써 일부 알고리즘의 속도를 크게 높일 수 있습니다. 이러한 기술은 종종 성장 순서와 무관 합니다 “big-O”표기법이지만 병렬 알고리즘의 big-O 표기법에서 코어 수를 자주 볼 수 있습니다.

또한 프로그램의 숨겨진 제약으로 인해 실제로 점근 적 행동에 신경 쓰지 않을 수도 있습니다. 다음과 같이 제한된 수의 값으로 작업 할 수 있습니다.

  • 5 개의 요소와 같은 것을 정렬하는 경우 빠른 O(N log(N))퀵 정렬 을 사용하고 싶지 않습니다 . 작은 입력에서 잘 수행되는 삽입 정렬을 사용하려고합니다. 이러한 상황은 종종 재귀 정렬, 빠른 푸리에 변환 또는 행렬 곱셈과 같은 문제를 더 작은 하위 문제로 나누는 분할 및 정복 알고리즘에서 발생합니다.
  • 숨겨진 사실로 인해 일부 값이 효과적으로 제한되는 경우 (예 : 평균 사람 이름은 약 40 자로 부드럽게 묶이고, 나이는 약 150으로 부드럽게 묶입니다). 용어를 효과적으로 일정하게 만들기 위해 입력에 경계를 지정할 수도 있습니다.

실제로, 동일하거나 유사한 점근 적 성능을 갖는 알고리즘 중에서도, 상대적인 장점은 다음과 같은 다른 요인에 의해 실제로 유도 될 수 있습니다 O(N log(N)). 구현의 용이성과 같은 비 성능 고려 사항; 도서관의 이용 가능 여부 및 도서관의 평판 및 유지 관리 수준

프로그램은 또한 500MHz 컴퓨터와 2GHz 컴퓨터에서 느리게 실행됩니다. 우리는 이것을 실제 자원의 한 부분으로 간주하지 않습니다. 왜냐하면 실제 초 당이 아니라 기계 자원 (예 : 클럭 사이클)에 따른 스케일링을 생각하기 때문입니다. 그러나 에뮬레이션에서 실행 중인지 또는 컴파일러가 코드를 최적화했는지의 여부와 같이 성능에 ‘비밀’로 영향을 줄 수있는 유사한 것들이 있습니다. 이로 인해 일부 기본 작업이 더 길어 지거나 (상대적으로) 일부 작업의 속도가 빨라지거나 속도가 느려질 수 있습니다 (서로에 비해). 효과는 다른 구현 및 / 또는 환경 사이에서 작거나 클 수 있습니다. 약간의 추가 작업을 피하기 위해 언어 나 기계를 전환합니까? 백 가지 이유 (필요성, 기술, 동료, 프로그래머 생산성,

프로그래밍 언어가 사용되는 선택의 효과와 같은 위의 문제는 상수 요소의 일부로 간주되지 않습니다. 그러나 때로는 (드물기는하지만) 영향을 줄 수 있기 때문에이를 알고 있어야합니다 . 예를 들어, cpython에서 기본 우선 순위 큐 구현은 선택적 으로 삽입 또는 find-min을 선택하는 O(log(N))것이 아니라 점증 적으로 비 최적입니다 O(1). 다른 구현을 사용하십니까? 아마도 C 구현이 더 빠르고 다른 곳에서도 비슷한 문제가있을 수 있기 때문에 아마도 아닙니다. 트레이드 오프가 있습니다. 때때로 그들은 중요하고 때로는 중요하지 않습니다.


( 편집 : “일반 영어”설명은 여기서 끝납니다.)

수학 부록

완전성을 기하기 위해 big-O 표기법의 정확한 정의는 다음과 같습니다. f(x) ∈ O(g(x))“f는 const * g에 의해 점진적으로 상한입니다”: x의 유한 한 값 아래의 모든 것을 무시하면 다음과 같은 상수가 있습니다 |f(x)| ≤ const * |g(x)|. (다른 기호는 다음과 같습니다. O≤, Ω≥를 의미합니다. 소문자 변형이 있습니다 : o<를 ω의미하고>를 f(x) ∈ Ɵ(g(x))의미합니다 .) f(x) ∈ O(g(x))f(x) ∈ Ω(g(x))(g로 상한 및 하한을 의미 ) : f와 같은 상수가 있습니다. const1*g(x)와 사이의 “대역”에 항상 있습니다 const2*g(x). 그것은 당신이 만들 수있는 가장 강력한 점근 적 진술이며==. (죄송하지만, 명확성을 기하기 위해 지금까지 절대 값 기호에 대한 언급을 연기하기로 결정했습니다. 특히 컴퓨터 과학 상황에서 음수 값이 나타나는 것을 본 적이 없기 때문입니다.)

사람들은 종종 = O(...)더 정확한 ‘comp-sci’표기법을 사용하며 완전히 사용하기에 합법적 인을 사용합니다. “f = O (…)”는 “f is order … / f는 …에 의해 xxx-bounded입니다.”로 읽히고 “f는 무증상이 … 인 표현입니다”라고 생각됩니다. 나는 더 엄격한 것을 사용하도록 배웠다 ∈ O(...). “의 요소”를 의미합니다 (여전과 같이 읽음). 이 특정한 경우에, O(N²){같은 요소를 포함 2 N², 3 N², 1/2 N², 2 N² + log(N), - N² + N^1.9, …} 무한히 크지 만 여전히 세트입니다.

O와 Ω는 대칭이 아니고 (n = O (n²)이지만 n²는 O (n)이 아님) Ɵ는 대칭이므로 (이 관계가 모두 전이적이고 반사적이므로) Ɵ, 대칭과 전이 및 반사 따라서 모든 함수 집합을 동등성 클래스 로 분할합니다 . 동등성 클래스는 우리가 동일하다고 생각하는 것들의 집합입니다. 즉, (일반적으로 한계를 고려하여 … 내가 클래스의 정식 / 독특한 ‘점근 대표’를 찾을 수 있습니다, 당신이 생각할 수있는 모든 기능을 제공, 말을하는 것입니다 생각 ); 모든 정수를 승산 또는 짝수로 그룹화 할 수있는 것처럼 기본적으로 작은 용어를 무시하여 Ɵ가있는 모든 함수를 x-ish, log (x) ^ 2-ish 등으로 그룹화 할 수 있습니다 (그러나 때로는 붙어있을 수 있습니다) 별도의 클래스 인 더 복잡한 함수).

=표기법이 더 일반적 일 수 있으며 세계적으로 유명한 컴퓨터 과학자들이 논문에 사용하기도합니다. 또한, 캐주얼 한 환경에서 사람들은 O(...)그들이 언제 의미하는지 말할 것입니다 Ɵ(...). 일련의 항목 Ɵ(exactlyThis)O(noGreaterThanThis)… 의 하위 집합이므로 입력하기가 쉽기 때문에 이것은 기술적으로 사실 입니다. 😉


답변

편집 : 빠른 참고, 이것은 Big O 표기법 (상한)과 Theta 표기법 (상한 및 하한 모두)과 거의 혼동 됩니다. 내 경험상 이것은 실제로 비 학술적 환경에서의 토론에서 일반적입니다. 혼란에 대한 사과.

한 마디로 : 직업의 규모가 커질수록 완료하는 데 시간이 얼마나 더 걸립니까?

분명히 이것은 “size”를 입력으로 사용하고 “take time”을 출력으로 사용하는 것입니다. 메모리 사용 등에 대해 이야기하려는 경우에도 동일한 아이디어가 적용됩니다.

다음은 건조시키고 싶은 N- 셔츠가있는 예입니다. 우리는 것이다 가정 (즉, 인간의 상호 작용을 무시할)는 건조 위치를 얻기 위해 믿을 수 없을 정도로 빠르다. 물론 현실에서는 그렇지 않습니다.

  • 외부 세척 라인 사용 : 무한히 큰 뒤뜰이 있다고 가정하면 세척은 O (1) 시간에 건조됩니다. 당신이 그것을 많이 가지고 있지만, 그것은 동일한 태양과 신선한 공기를 얻을 것이므로 크기는 건조 시간에 영향을 미치지 않습니다.

  • 회전식 건조기 사용 : 각 적재에 10 개의 셔츠를 넣은 다음 1 시간 후에 완료됩니다. (실제 숫자는 무시하십시오. 관련이 없습니다.) 따라서 50 개의 셔츠 를 건조하는 것은 10 개의 셔츠를 건조하는 데 5 배가 걸립니다 .

  • 방송 찬장에 모든 것을 담기 : 모든 것을 하나의 큰 더미에 넣고 일반적인 따뜻함을 유지하면 중간 셔츠가 마르기까지 오랜 시간이 걸립니다. 세부 사항을 추측하고 싶지는 않지만 적어도 O (N ^ 2)라고 생각합니다. 세척 부하를 늘리면 건조 시간이 더 빨라집니다.

“big O”표기법의 중요한 측면 중 하나 는 주어진 크기에 대해 어떤 알고리즘이 더 빠를 말하지 않는다는 것입니다. 해시 테이블 (문자열 키, 정수 값)과 쌍의 배열 (문자열, 정수)을 가져옵니다. 문자열을 기반으로 해시 테이블 또는 배열의 요소에서 키를 찾는 것이 더 빠릅니까? (즉, 배열의 경우, “문자열 부분이 주어진 키와 일치하는 첫 번째 요소를 찾으십시오.”) 해시 테이블은 일반적으로 상각됩니다 (~ = “평균”) O (1) — 일단 설정되면 약 1,000,000 개의 엔트리 테이블에서와 같이 100 개의 엔트리 테이블에서 엔트리를 찾는 동시에. 배열에서 요소를 찾는 것은 (인덱스가 아닌 내용을 기반으로) 선형 적입니다. 즉, O (N) — 평균적으로 항목의 절반을 봐야합니다.

조회 배열보다 해시 테이블이 더 빠릅니까? 반드시 그런 것은 아닙니다. 매우 작은 항목 모음이있는 경우 배열이 더 빠를 수 있습니다.보고있는 문자열의 해시 코드를 계산하는 데 걸리는 시간에 모든 문자열을 확인할 수 있습니다. 그러나 데이터 세트가 커지면 해시 테이블은 결국 배열을 이길 것입니다.


답변

Big O는 입력이 커질 때 함수의 증가 동작 (예 : 프로그램 런타임)의 상한을 설명합니다.

예 :

  • O (n) : 입력 크기를 두 배로 늘리면 런타임이 두 배가됩니다.

  • O (n 2 ) : 입력 크기가 런타임 4 배를 두 배로 늘리는 경우

  • O (log n) : 입력 크기가 두 배가되면 런타임이 1 씩 증가합니다

  • O (2 n ) : 입력 크기가 1 씩 증가하면 런타임이 두 배가됩니다

입력 크기는 일반적으로 입력을 나타내는 데 필요한 비트 단위의 공간입니다.


답변

Big O 표기법은 입력 집합의 크기에 따라 계산 (알고리즘)을 완료하는 데 걸리는 대략적인 측정 값으로 프로그래머가 가장 일반적으로 사용합니다.

Big O는 입력 수가 증가함에 따라 두 알고리즘이 얼마나 잘 확장되는지 비교하는 데 유용합니다.

보다 정확하게 Big O 표기법 은 함수의 점근 적 행동을 표현하는 데 사용됩니다. 이는 함수가 무한대에 접근함에 따라 어떻게 동작 하는지를 의미합니다.

많은 경우 알고리즘의 “O”는 다음 경우 중 하나에 해당합니다.

  • O (1) -완료 시간은 입력 세트의 크기에 관계없이 동일합니다. 예를 들어 인덱스로 배열 요소에 액세스합니다.
  • O (Log N) -완료 시간이 log2 (n)에 따라 대략 증가합니다. 예를 들어 Log2 (1024) = 10 및 Log2 (32) = 5이므로 1024 개의 항목은 32 개의 항목보다 약 두 배가 걸립니다. 예를 들어 BST ( Binary Search Tree) 에서 항목을 찾는 것 입니다.
  • O (N) -입력 세트의 크기에 따라 선형으로 확장되는 완료 시간입니다. 즉, 입력 세트의 항목 수를 두 배로 늘리면 알고리즘의 길이가 약 두 배가 걸립니다. 예를 들어 링크 된 목록의 항목 수를 계산합니다.
  • O (N Log N) -완료 시간이 Log2 (N) 결과의 항목 수에 따라 증가합니다. 이에 대한 예는 힙 정렬빠른 정렬 입니다.
  • O (N ^ 2) -완료 시간은 항목 수의 제곱과 거의 같습니다. 이에 대한 예는 bubble sort 입니다.
  • O (N!) -완료 시간은 입력 세트의 계승입니다. 이것의 예는 여행하는 세일즈맨 문제 무차별 대입 솔루션 입니다.

Big O는 입력 크기가 무한대로 증가함에 따라 함수의 성장 곡선에 의미있는 방식으로 기여하지 않는 요소를 무시합니다. 즉, 함수에 더하거나 곱한 상수는 단순히 무시됩니다.


답변

Big O는 일반적인 방법으로 “내 코드를 실행하는 데 시간 / 공간이 얼마나 걸립니까?”

당신은 종종 O (n), O (n 2 ), O (nlogn) 등을 볼 수 있습니다. 알고리즘은 어떻게 변경됩니까?

O (n)은 Big O가 n임을 의미하며 이제 “N이란 무엇입니까?” “n”은 원소의 양입니다. 이미징 배열에서 항목을 검색하려고합니다. 각 요소와 “정확한 요소 / 항목입니까?”로 살펴 봐야합니다. 최악의 경우, 항목은 마지막 색인에 있습니다. 즉, 목록에 항목이있는 것보다 많은 시간이 걸렸음을 의미합니다. 따라서 일반적으로 “오, n은 공정한 값입니다!” .

따라서 “n 2 “가 무엇을 의미 하는지 이해할 수 있지만 더 구체적으로 말하면 가장 간단하고 간단한 정렬 알고리즘을 가지고 있다는 생각을 가지고 놀 수 있습니다. bubblesort. 이 알고리즘은 각 항목에 대해 전체 목록을 살펴 봐야합니다.

나의 목록

  1. 1
  2. 6

흐름은 다음과 같습니다.

  • 1과 6을 비교해보십시오. Ok 6은 올바른 위치에 있으며 앞으로 나아갑니다!
  • 6과 3을 비교하면 3이 적습니다! 목록을 변경 했으니 시작부터 시작해야합니다.

이것은 목록에 “n”개의 항목이있는 모든 항목을 봐야하기 때문에 O n 2 입니다. 각 항목에 대해 모든 항목을 한 번 더보고 비교를 위해이 항목도 “n”이므로 모든 항목에 대해 n * n = n 2를 의미하는 “n”번을 찾습니다.

나는 이것이 당신이 원하는만큼 간단하기를 바랍니다.

그러나 Big O는 시간과 공간의 방식으로 자신을 표현하는 방법 일뿐입니다.