development

상각 상각 시간

big-blog 2020. 2. 23. 11:58
반응형

상각 상각 시간


알고리즘의 시간 복잡성에 대해 이야기 할 때 "일정한 상각 시간"이란 무엇입니까?


상각 된 시간은 간단한 용어로 설명됩니다.

작업이 백만 번 말하면 실제로 작업의 최악의 경우 또는 가장 좋은 경우에 신경 쓰지 않습니다. 관심있는 것은 백만 번 작업을 반복 할 때 총 시간이 얼마나 걸리는가입니다. .

따라서 "한 번에 한 번"이 느리게 희석 될 정도로 드물기 만하면 작업이 한 번에 매우 느리게 진행되는지는 중요하지 않습니다. 본질적으로 상각 된 시간은 "작업이 많은 경우 작업 당 평균 평균 시간"을 의미합니다. 상각 시간이 일정 할 필요는 없습니다. 선형 및 대수 상각 시간 또는 기타 다른 것을 가질 수 있습니다.

반복적으로 새 항목을 추가하는 동적 배열의 매트를 예로 들어 보겠습니다. 일반적으로 항목을 추가하는 데 일정한 시간이 걸립니다 (즉, O(1)). 그러나 어레이가 가득 찰 때마다 두 배의 공간을 할당하고 데이터를 새 지역에 복사하고 이전 공간을 비 웁니다. 할당 및 해제가 일정한 시간에 실행된다고 가정하면,이 확대 프로세스는 O(n)n이 어레이의 현재 크기 인 시간 이 걸립니다 .

따라서 확대 할 때마다 마지막 확대보다 약 두 배의 시간이 걸립니다. 그러나 당신은 또한 그것을하기 전에 두 배나 기다렸습니다! 따라서, 각각의 확대 비용은 삽입물 사이에서 "확산"될 수있다. 이것은 장기적으로 m 개의 항목을 배열 에 추가하는 데 걸리는 총 시간 O(m)이므로 상각 된 시간 (즉, 삽입 당 시간)은임을 의미 O(1)합니다.


시간이 지남에 따라 최악의 시나리오는 기본적으로 O (1) 또는 일정 시간으로 설정됩니다. 일반적인 예는 동적 배열입니다. 새 항목에 이미 메모리를 할당 한 경우 추가하면 O (1)이됩니다. 할당하지 않은 경우 현재 금액의 두 배를 할당하여 할당합니다. 이 특정 삽입 할 수 없습니다 O (1), 그러나 다른 사람보다는 뭔가.

중요한 것은 알고리즘이 일련의 작업 후에 고가의 작업이 상각되어 전체 작업 O (1)을 렌더링한다는 것을 보장한다는 것입니다.

더 엄격한 용어로

상수 C는, 거기에 대한 그런 모든 길이 L의 (a 비싼 연산으로 끝나는 하나) 동작의 순서, 시간 C 이하인 * L (감사 라팔 Dowgird )


직관적 인 사고 방식을 개발하려면 동적 배열 (예 std::vector: C ++) 에 요소를 삽입하는 것이 좋습니다. 배열에 N 개의 요소를 삽입하는 데 필요한 연산 수 (Y)의 종속성을 보여주는 그래프를 그려 봅시다.

음모

검은 색 그래프의 세로 부분은 배열을 확장하기 위해 메모리 재 할당에 해당합니다. 여기서 우리는이 의존성이 대략 선으로 표현 될 수 있음을 알 수 있습니다. 그리고이 선 방정식은 Y=C*N + b( 우리의 경우 C상수, b= 0입니다). 따라서 우리는 C*N배열에 N 개의 요소를 추가 하기 위해 평균 연산 을 소비 하거나 C*1하나의 요소를 추가하는 연산 (암스트롱 드 상수 시간) 을 사용해야한다고 말할 수 있습니다 .


3 번 반복해서 읽은 후 Wikipedia 설명이 유용하다는 것을 알았습니다.

출처 : https://en.wikipedia.org/wiki/Amortized_analysis#Dynamic_Array

"동적 배열

동적 어레이에 대한 푸시 작업의 상각 분석

Java의 ArrayList와 같이 더 많은 요소가 추가되면 크기가 커지는 동적 배열을 고려하십시오. 크기가 4 인 동적 배열로 시작한 경우 4 개의 요소를 밀어 넣으려면 일정한 시간이 걸립니다. 그러나 배열에 다섯 번째 요소를 밀어 넣으면 배열이 현재 크기의 두 배인 새 배열을 작성하고 (8) 이전 요소를 새 배열에 복사 한 다음 새 요소를 추가해야하므로 시간이 더 오래 걸립니다. 다음 세 번의 푸시 작업도 마찬가지로 일정한 시간이 걸리며, 이후의 추가 작업에는 어레이 크기의 느린 두 배가 필요합니다.

일반적으로 임의 크기의 푸시 n을 크기 n의 배열로 고려할 경우 크기 배가 연산을 수행하는 데 O (n) 시간이 걸리는 마지막 것을 제외하고는 푸시 작업에 일정한 시간이 걸린다는 것을 알 수 있습니다. 총 n 개의 연산이 있었으므로이 평균을 취하여 동적 배열에 요소를 푸시하는 데 걸리는 시간은 O (n / n) = O (1), 상수 시간입니다. "

간단한 이야기로 이해 :

돈이 많다고 가정하자. 그리고 당신은 그들을 방에 쌓아두기를 원합니다. 그리고 현재 또는 미래에 필요한만큼 손과 다리가 길다. 그리고 한 방에 모두 채워야하므로 잠그기가 쉽습니다.

따라서 방의 끝 / 구석으로 가서 쌓아 올리십시오. 쌓아 올리면 천천히 공간이 부족합니다. 그러나 채울 때 쉽게 쌓을 수있었습니다. 돈을 가지고 돈을 넣어. 쉬운. O (1)입니다. 우리는 이전 돈을 옮길 필요가 없습니다.

공간이 부족 해지면 우리는 더 큰 다른 방이 필요합니다. 여기에는 하나의 방만있을 수 있으므로 하나의 자물쇠 만 가질 수 있으므로 문제가 있습니다. 그 방에있는 기존의 모든 돈을 새로운 더 큰 방으로 옮길 필요가 있습니다. 따라서 모든 돈을 작은 방에서 더 큰 방으로 옮기십시오. 즉, 모두 다시 쌓으십시오. 따라서 우리는 이전의 모든 돈을 옮길 필요가 있습니다. 그래서 O (N)입니다. (N이 이전 돈의 총 돈이라고 가정)

다시 말해 N까지는 쉬웠지만 한 번만 조작 할 수 있었지만 더 큰 방으로 이사해야 할 때는 N 번을했습니다. 즉, 평균을 구하면 시작 부분에 1 개의 삽입물이 있고 다른 방으로 이동하는 동안 1 개의 이동이 더 있습니다. 총 2 개의 작업, 한 번의 삽입, 한 번의 이동.

작은 방에서도 N이 1 백만이라고 가정하면 N (1 백만)에 비해 2 개의 연산은 실제로 비교할 수있는 숫자가 아니므로 상수 또는 O (1)로 간주됩니다.

우리가 더 큰 다른 방에서 위의 모든 일을하고 다시 움직일 필요가 있다고 가정합니다. 여전히 동일합니다. 예를 들어 N2 (예 : 10 억)는 더 큰 방에서 새로운 금액의 돈입니다.

그래서 우리는 N2를 가지고 있습니다 (이것은 모두 작은 방에서 더 큰 방으로 이동하기 때문에 이전의 N을 포함합니다)

우리는 여전히 2 개의 작업 만 필요합니다. 하나는 더 큰 방에 삽입하고 다른 하나는 더 큰 방으로 이동합니다.

따라서 N2 (10 억)의 경우에도 각각 2 개의 작업입니다. 다시는 아무것도 아닙니다. 따라서 상수 또는 O (1)

따라서 N이 N에서 N2로 증가함에 따라 그다지 중요하지 않습니다. 여전히 일정하거나 각 N에 필요한 O (1) 연산입니다.


이제 N이 1로 매우 작고, 돈의 수가 적고, 1의 돈에만 맞는 매우 작은 방이 있다고 가정하십시오.

방에 돈을 채우 자마자 방이 가득 찼습니다.

더 큰 방에 갈 때 총 2 개의 돈을 더 넣을 수 있다고 가정하십시오. 즉, 이전에 돈을 옮겼고 1 개가 더 옮겼습니다. 그리고 다시 채워집니다.

이런 식으로, N은 느리게 성장하고 있으며 우리가 이전 방에서 모든 돈을 옮기고 있기 때문에 더 이상 O (1)는 아니지만 1 개만 더 들어갈 수 있습니다.

100 번이 지나면 새로운 방은 이전의 돈과 100 개의 돈을 수용 할 수 있습니다. 이것은 O (N)입니다. O (N + 1)이 O (N)이기 때문에, 즉 100 또는 101의 정도는 동일합니다. 이전 이야기와는 달리 수백에서 수백억까지 .

따라서 이것은 돈 (변수)을 위해 공간 (또는 메모리 / RAM)을 할당하는 비효율적 인 방법입니다.


따라서 좋은 방법은 2의 거듭 제곱으로 더 많은 공간을 할당하는 것입니다.

첫 번째 방 크기 = 1 개의 돈 계산
2 번째 방 크기 = 4 개의 돈 계산
3 번째 방 크기 = 8 개의 돈 계산
4 번째 방 크기 = 16 개의 돈 계산
5 번째 방 크기 = 32 개의 계산 돈
6 번째 방 크기 = 맞는 64 개의 돈
7 번째 방 크기 = 128 개의 돈
크기 8 번째 방 크기 = 256 개의 돈
크기 9 번째 방 크기 = 512 개의 돈
크기 10 번째 방 크기 = 1024 개의 돈
11 번째 방 크기 = 2,048 개의 돈 맞음
. ..
16 번째 방 크기 = 65,536 개의 돈에 해당
...
32 번째 방 크기 = 4,294,967,296에 해당하는 돈
...
64 번째 방 크기 = 18,446,744,073,709,551,616에 해당

왜 이것이 더 낫습니까? RAM의 메모리 양과 비교할 때 처음에는 느리게 성장하고 나중에는 더 빨리 커지기 때문입니다.

첫 번째 경우는 좋지만 돈당 수행 할 총 작업량이 고정되어 있고 (2) 방 크기 (N)와 비교할 수 없기 때문에 초기 단계에서 수행 한 방이 너무 많을 수 있기 때문에 도움이됩니다. 우리가 처음에 전혀 저축 할 돈이 많을 지에 따라 우리가 완전히 사용하지 않을 수도있는 큰 (백만).

그러나 마지막 경우 2의 거듭 제곱은 RAM의 한계에서 커집니다. 따라서 2의 거듭 제곱이 증가함에 따라 Armotized 분석은 일정하게 유지되며 오늘날의 제한된 RAM에 적합합니다.


위의 설명은 여러 작업에 대해 "평균"을 취한다는 아이디어 인 집계 분석에 적용됩니다. 은행가 방법 또는 물리학 자 상각 방법에 어떻게 적용되는지 잘 모르겠습니다.

지금. 정답이 확실하지 않습니다. 그러나 그것은 물리학 자 + 뱅커의 두 가지 방법의 원칙적 조건과 관련이 있습니다.

(상각비 상각액의 합계)> = (실제 비용 상한 액).

내가 직면하는 가장 큰 어려움은 할부 상환 작업 비용이 일반 점근 비용과 다르다는 점을 감안할 때 상각 비용의 중요성을 어떻게 평가할 수 있는지 잘 모르겠습니다.

누군가 누군가가 상각 비용을 줄 때, 나는 정상적인 상각 비용과 동일하지 않다는 것을 알고 있습니다. 그렇다면 상각 비용에서 어떤 결론을 도출해야합니까?

일부 작업이 과충전되고 다른 작업이 과소 청구되는 경우가 있기 때문에 개별 작업의 상각 비용을 인용하면 의미가 없다는 가설이있을 수 있습니다.

예를 들어, 피보나치 힙의 경우, Decreasing-Key의 할부 상환 비용을 O (1)로 인용하는 것은 "힙의 잠재력을 높이는 초기 작업에 의해 수행되는 작업"에 의해 비용이 감소되기 때문에 의미가 없습니다.

또는

우리는 다음과 같이 할부 상환 비용에 대한 이유에 대한 또 다른 가설을 가질 수 있습니다.

  1. 비싼 작업이 MULTIPLE LOW-COST 작업보다 우선한다는 것을 알고 있습니다.

  2. 분석을 위해 저비용 운영을 과충전 할 것인데, 그 비용은 변하지 않습니다.

  3. 이러한 저비용 운영으로 비용이 많이 드는 운영 비용을 입증 할 수 있습니다.

  4. 따라서 나는 운영 비용의 ASYMPTOTIC-BOUND를 개선 / 감소시켰다.

따라서 상각 비용 분석 + 상각 비용 범위는 이제 고가의 작업에만 적용 할 수 있습니다. 값싼 작업은 일반 점근 비용과 동일한 점근 비용이 있습니다.


"전체 함수 호출 수"를 "모든 해당 호출에 걸린 총 시간"으로 나눔으로써 모든 기능의 성능을 평균화 할 수 있습니다. 각 호출마다 더 오래 걸리는 기능조차도 이러한 방식으로 평균화 할 수 있습니다.

따라서 수행하는 기능의 본질은 Constant Amortized Time이 "평균 시간"이 통화 수가 계속 증가함에 따라 초과되지 않는 한도에 도달한다는 것입니다. 특정 통화는 성능이 다를 수 있지만 장기적으로이 평균 시간이 계속 커지는 것은 아닙니다.

이것은에서 수행하는 무언가의 필수 장점입니다 Constant Amortized Time.

참고 URL : https://stackoverflow.com/questions/200384/constant-amortized-time



반응형