상수 시간과 상각 상수 시간은 사실상 동등한 것으로 간주됩니까?


16

Constant Time (O (1))에서 추가 및 무작위 제거를 허용하는 RandomQueue를 작성해야합니다.

내 첫 번째 생각은 배열이 인덱스를 통해 지속적으로 액세스하기 때문에 일종의 Array (ArrayList를 선택)로 백업하는 것이 었습니다.

문서를 살펴보면 ArrayLists의 추가가 Amortized Constant Time으로 간주된다는 것을 알았습니다. 추가에는 기본 배열의 재 할당이 필요하기 때문에 O (n)입니다.

Amortized Constant Time과 Constant Time은 실질적으로 동일합니까, 아니면 추가 할 때마다 완전히 재 할당 할 필요가없는 일부 구조를 살펴 봐야합니까?

배열 기반 구조는 제쳐두고 (항상 Amortized Constant Time 추가가있을 것입니다) 요구 사항을 충족시키는 것은 생각할 수 없기 때문에 이것을 묻습니다.

  • 모든 트리 기반은 최상의 O (log n) 액세스 권한을 갖습니다.
  • 연결된 목록에는 잠재적으로 O (1) 추가 (꼬리에 대한 참조가 유지되는 경우)가있을 ​​수 있지만 무작위 제거는 최대 O (n)이어야합니다.

전체 질문은 다음과 같습니다. 중요한 세부 사항을 살펴본 경우

RandomQueue를 설계하고 구현하십시오. 이것은 remove () 오퍼레이션이 현재 큐에있는 모든 요소 중에서 무작위로 균일하게 선택된 요소를 제거하는 큐 인터페이스의 구현입니다. (RandomQueue를 백으로 간주하여 요소를 추가하거나 임의의 요소에 도달하여 맹목적으로 제거 할 수 있습니다.) RandomQueue의 add (x) 및 remove () 작업은 작업마다 일정한 시간에 실행되어야합니다.


할당은 무작위 제거 수행 방법을 지정합니까? 제거 할 인덱스 또는 큐 요소에 대한 참조가 제공됩니까?

구체적인 내용은 없습니다. 요구 사항은 대기열 인터페이스를 구현하는 구조 일 뿐이며 O (1) 추가 및 제거가 있습니다.
Carcigenicate 2016 년

옆으로 – O (n)이 증가하는 크기 조정 가능한 배열에 반드시 O (1)이 추가 될 필요는 없습니다 . 이는 배열을 성장시키는 방법에 따라 다릅니다 . 일정한 양만큼 증가 하는 것은 여전히 ​​덧셈을 위해 O (n)입니다 (우리는 1/aO (n) 연산 a > 1(1/a)^n기회 가 있습니다). (n) 연산이지만 large의 경우 확률은 0에 가까워 n집니다.
amon

ArrayLists는 후자를 올바르게 사용합니까?
Carcigenicate 2016 년

1
질문 (me)의 저자는 상각 된 일정한 시간 솔루션을 생각하고있었습니다. 나는 다음 판에서 그것을 분명히 할 것이다. (여기서 최악의 상수 시간은 여기서 상각 제거 기술을 사용하여 달성 할 수 있지만 )
Pat Morin

답변:


10

Amortized Constant Time은 거의 항상 Constant Time과 동등한 것으로 간주 될 수 있으며, 응용 프로그램의 세부 사항과이 대기열에 수행하려는 사용 유형을 알지 못하면 대부분 보장 될 수 있습니다.

배열 목록은 용량 개념을 가지며 , 이는 기본적으로 지금까지 필요한 최대 크기 / 길이 / 항목 수와 같습니다. 따라서 처음에는 배열 목록에 항목을 추가 할 때 용량을 늘리기 위해 배열 목록을 계속 할당하지만 어떤 시점에서 단위 시간당 추가 된 평균 항목 수는 필연적으로 평균 항목 수와 일치합니다 단위 시간당 제거 (그렇지 않으면 결국 메모리가 부족합니다).이 시점에서 배열 자체 재 할당이 중지되고 모든 추가는 O (1)의 일정한 시간에 충족됩니다.

그러나 기본적으로 배열 목록에서 임의 제거는 O (1)가 아니라 O (N)입니다. 배열 목록은 제거 된 항목 뒤에있는 모든 항목을 한 위치 아래로 이동하여 제거 된 위치를 대신하기 때문입니다. 안건. O (1)을 달성하려면 제거 된 항목을 배열 목록의 마지막 항목의 복사본으로 바꾸는 기본 동작을 재정의 한 다음 마지막 항목을 제거하여 항목이 이동하지 않도록해야합니다. 그러나 그렇게하면 더 이상 대기열이 없습니다.


1
젠장, 제거에 대한 좋은 지적; 나는 그것을 고려하지 않았다. 그리고 우리는 무작위로 요소를 제거하기 때문에 기술적으로 더 이상 그런 의미에서 대기열이 아니라는 것을 의미하지 않습니까?
Carcigenicate 2016 년

예, 실제로 대기열로 취급하지 않는다는 의미입니다. 그러나 제거 할 항목을 찾는 방법을 모르겠습니다. 그것들을 찾는 메커니즘이 그것들이 그들이 추가 된 순서대로 큐에 존재할 것을 기대한다면, 당신은 운이 좋지 않습니다. 품목의 주문이 깨져도 상관 없다면 괜찮습니다.
Mike Nakis 2016 년

2
인터페이스 RandomQueue를 구현하고 Queue제공된 remove메소드가 헤드를 팝하는 대신 무작위로 제거 할 것으로 기대 하므로 특정 순서에 의존 할 수있는 방법이 없어야합니다. 나는 그 임의의 특성을 감안할 때 사용자가 특정 순서를 유지할 것으로 기 대해서는 안된다고 생각합니다. 설명을 위해 내 질문에 과제를 인용했습니다. 감사합니다.
Carcigenicate 2016 년

2
예, 아이템 제거가 내가 제안한 방식으로 완료되었는지 확인하면 괜찮을 것 같습니다.
Mike Nakis 2016 년

신경 쓰지 않으면 마지막으로 나는 그것을 더 많이 생각했고, "true"O (1) 추가와 "true"O (1) 랜덤 제거를 모두 가질 수있는 것 같지 않습니다. 제거는되지만 additon은 제공하지 않는 단독으로 할당 된 구조 (배열과 같은) 또는 추가를 제공하지만 제거는 제공하지 않는 Linked-List와 같은 청크 할당 구조를 가지고 있습니다. 이것이 사실입니까? 다시 한 번 감사드립니다.
Carcigenicate 2016 년

14

질문은 구체적으로 상각 된 일정 시간이 아닌 일정 시간을 요구하는 것 같습니다 . 따라서 인용 된 질문과 관련하여 아니요, 사실상 동일하지 않습니다 *. 그러나 실제 응용 프로그램에 있습니까?

상각 된 상수의 일반적인 문제는 때때로 누적 부채를 지불해야한다는 것입니다. 따라서 인서트는 일반적으로 일정하지만 때때로 새 블록이 할당 될 때 모든 것을 다시 삽입해야하는 오버 헤드가 발생합니다.

일정한 시간과 상각 된 일정한 시간의 차이가 어플리케이션과 관련이있는 경우,이 매우 느린 속도가 허용 가능한지 여부에 따라 다릅니다. 매우 많은 도메인의 경우 일반적으로 괜찮습니다. 특히 컨테이너가 유효 최대 크기 (캐시, 임시 버퍼, 작업 컨테이너와 같은)를 가지고 있으면 실행 중에 한 번만 비용을 효과적으로 지불 할 수 있습니다.

응답이 중요한 응용 프로그램에서는 이러한 시간이 허용되지 않을 수 있습니다. 짧은 처리 시간 보장을 충족해야하는 경우 때때로이를 초과하는 알고리즘에 의존 할 수 없습니다. 나는 전에 그러한 프로젝트를 해왔지만 매우 드물다.

또한이 비용이 실제로 얼마나 높은가에 달려 있습니다. 재 할당 비용이 상대적으로 낮기 때문에 벡터의 성능이 우수합니다. 그러나 해시 맵으로 이동하면 재 할당이 훨씬 높아질 수 있습니다. 다시 말하지만 대부분의 응용 프로그램의 경우 컨테이너의 항목에 상한이있는 수명이 긴 서버가 특히 좋습니다.

* 여기에 약간의 문제가 있습니다. 범용 컨테이너를 삽입 시간을 일정하게 유지하려면 다음 두 가지 중 하나를 유지해야합니다.

  • 컨테이너는 고정 된 최대 크기 여야합니다. 또는
  • 개별 요소의 메모리 할당이 일정한 시간이라고 가정 할 수 있습니다.

"간 서버"는 여기서 사용하기에 이상한 문구처럼 보입니다. "라이브 서버"를 의미합니까?
Pieter Geerkens 2016 년

6

처리량 또는 대기 시간을 최적화하는지 여부에 따라 다릅니다.

  • 지연 시간에 민감한 시스템에는 일관된 성능이 필요합니다. 이러한 시나리오에서는 시스템의 최악의 동작을 강조해야합니다. 예를 들어 일정한 프레임 속도를 달성하려는 게임이나 특정 시간 내에 응답을 보내야하는 웹 서버와 같은 소프트 실시간 시스템이 있습니다. CPU주기 낭비가 늦는 것보다 낫습니다.
  • 처리량에 최적화 된 시스템은 최대량의 데이터를 장기적으로 처리 할 수있는 한 가끔 중단되는 것을 신경 쓰지 않습니다. 여기서는 주로 상각 된 실적에 관심이 있습니다. 이는 일반적으로 번호 크 런칭 또는 기타 일괄 처리 작업의 경우입니다.

하나의 시스템에는 다르게 분류해야하는 다른 구성 요소가있을 수 있습니다. 예를 들어 최신 텍스트 프로세서에는 대기 시간에 민감한 UI 스레드가 있지만 맞춤법 검사 또는 PDF 내보내기와 같은 다른 작업에 대해 처리량에 최적화 된 스레드가 있습니다.

또한 알고리즘 복잡도는 생각만큼 중요하지 않은 경우가 많습니다. 문제가 특정 수에 국한된 경우 실제 및 측정 된 성능 특성이 "매우 큰 n "에 대한 동작보다 중요합니다 .


불행히도, 나는 배경이 거의 없습니다. 문제는 "RandomQueue의 add (x) 및 remove () 작업이 작업 당 일정한 시간에 실행되어야합니다"로 끝납니다.
Carcigenicate 2016 년

2
@Carcigenicate 시스템이 대기 시간에 민감하다는 사실을 알지 못하면 상각 된 복잡성을 사용하여 데이터 구조를 선택하는 것이 절대적으로 충분해야합니다.
amon

나는 이것이 프로그래밍 연습이나 테스트 일 수 있다는 인상을 받았습니다. 그리고 쉬운 일이 아닙니다. 매우 중요하지 않다는 것은 사실입니다.
gnasher729

1

당신은 "일정한 상각 시간"알고리즘을 요구하는 경우, 알고리즘이 있습니다 때로는 시간이 오래 걸릴. 예를 들어 C ++에서 std :: vector를 사용하는 경우 이러한 벡터는 10 개의 객체에 공간을 할당 할 수 있으며 11 번째 객체를 할당하면 20 개의 객체에 대한 공간이 할당되고 10 개의 객체가 복사되고 11이 추가됩니다. 상당한 시간이 걸립니다. 그러나 백만 개의 개체를 추가하면 평균 시간이 빠른 999,980 개의 빠른 작업과 20 개의 느린 작업이있을 수 있습니다.

"일정한 시간"알고리즘을 요구할 경우 , 모든 단일 작업마다 알고리즘이 항상 빨라야합니다. 각 단일 작업이 항상 빠르다 는 보장이 필요할 수있는 실시간 시스템에 중요합니다 . "일정 시간"은 종종 필요하지 않지만 " 정확한 시간"과 동일 하지는 않습니다 .

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