algorithm - programming - https www geeksforgeeks org data structures




더미에서 양말을 효율적으로 짝 지우는 방법? (20)

내가하는 일은 첫 번째 양말을 집어 내려 놓는 것입니다 (예 : 빨래방의 가장자리). 그런 다음 다른 양말을 집어 들고 첫 번째 양말과 같은지 확인합니다. 그렇다면 둘 다 제거합니다. 그렇지 않다면 나는 첫 번째 양말 옆에 그것을 내려 놓았다. 그런 다음 세 번째 양말을 집어 들고 첫 두 양말과 비교합니다 (여전히있는 경우). 기타.

이 접근법은 양말을 "제거"하는 것이 옵션이라는 가정하에 어레이에 구현 될 수 있습니다. 사실, 양말을 "제거"할 필요조차 없습니다. 양말을 정렬 할 필요가 없다면 (아래 참조) 배열에서 쌍으로 배열 된 모든 양말을 가진 배열로 그들을 이동하고 끝낼 수 있습니다.

양말에 대한 유일한 연산은 평등을 비교하는 것이라고 가정하면,이 알고리즘은 기본적으로 여전히 n 2 알고리즘입니다. 그러나 평균 사례 (계산하지 않는 방법)에 대해서는 알지 못합니다.

정렬은 효율성을 향상시킵니다. 특히 다른 두 양말 사이에 양말을 쉽게 "삽입"할 수있는 실생활에서는 특히 효율성이 향상됩니다. 컴퓨팅에서 트리를 사용하여 동일한 결과를 얻을 수 있지만 추가 공간입니다. 그리고 물론 NlogN으로 돌아 왔습니다 (기준을 정렬하여 여러 개의 양말이 있지만 동일한 쌍이 아닌 경우).

그것 이외에, 나는 아무것도 생각할 수 없다. 그러나이 방법은 실생활에서 꽤 효율적이라고 보인다. :)

어제 나는 깨끗한 세탁물에서 양말을 페어링하고 있었고 내가하고 있었던 방식이 매우 효율적이지 않다는 것을 알아 냈습니다. 순진한 검색을하고있었습니다. 한 쌍의 양말을 골라 내고 그 더미를 찾기 위해 더미를 "반복"했습니다. 이를 위해서는 평균 n / 2 * n / 4 = n 2 / 8 양말을 반복해야합니다.

컴퓨터 과학자로서 내가 할 수있는 일을 생각하고 있었습니까? 물론 (크기 / 색상 / ...에 따라) 정렬은 O (NlogN) 솔루션을 달성하기 위해 마음에 왔습니다.

해싱이나 다른 장소가 아닌 솔루션은 옵션이 아닙니다. 양말을 복제 할 수 없기 때문입니다 (가능하다면 좋을 수도 있지만).

질문은 기본적으로 다음과 같습니다.

2n 요소를 포함하는 n 쌍의 양말 더미가 주어지면 (각 양말에 정확히 일치하는 쌍이 하나 있다고 가정 할 때) 최대 로그 대수 공간까지 효율적으로 쌍을 이루는 가장 좋은 방법은 무엇입니까? (필요한 경우 정보량을 기억할 수 있다고 생각합니다.)

다음과 같은 측면에 대한 답을 고맙게 생각합니다.

  • 엄청난 양의 양말에 대한 일반적인 이론적 해결책.
  • 양말의 실제 수는 그렇게 크지 않습니다, 나는 내 배우자를 믿지 않으며 나는 30 쌍 이상 있습니다. (그리고 내 양말과 그녀의 구별하기가 상당히 쉽다.)
  • 그것은 요소 구분 문제 와 동일합니까?

실용적인 해결책으로서 :

  1. 쉽게 구별 할 수있는 양말 더미를 빠르게 만들 수 있습니다. (색상으로 말하기)
  2. 모든 더미를 정리하고 비교를 위해 양말의 길이를 사용하십시오. 인간으로서 당신은 최악의 상황을 피하는 파티션에 사용하는 양말을 상당히 빨리 결정할 수 있습니다. (병렬로 여러 개의 양말을 볼 수 있으므로 이점을 활용하십시오!)
  3. 더미가 즉시 발견 할 수있는 임계점에 도달하면 정렬을 중지합니다.

양말이 8 개 있고 평균 분포가있는 양말이 1000 개있는 경우, c * n 시간에 각 125 양말 4 개를 만들 수 있습니다. 5 양말의 한계치를 사용하여 6 개의 주행마다 모든 파일을 분류 할 수 있습니다. (2 초를 세어 오른쪽 더미에 양말을 던지면 4 시간 이내에 조금 걸릴 것입니다.)

당신은 단지 60 양말, 3 색 및 2 종류의 양말 (당신 / 당신의 아내)을 가지고 있다면 1 회에 10 개의 양말 더미를 분류 할 수 있습니다 (다시 임계 값 = 5). (2 초를 세면 2 분이 걸릴 것입니다.)

c*n*log(k) 작업을 수행하기 c*n*log(k) 되므로 c*n 시간에 n 개의 양말을 k 개의 버킷으로 나누기 때문에 초기 버킷 정렬은 프로세스 속도를 높여줍니다. (임계 값을 고려하지 않음). 그래서 당신은 모두 n*c*(1 + log(k)) 작업을합니다. 여기서 c는 더미 위에 양말을 던지기위한 시간입니다.

이 접근법은 대략 log(k) < x - 1 모든 c*x*n + O(1) 방법에 비해 유리할 것입니다.

컴퓨터 과학에서 이것은 도움이 될 수 있습니다. 우리는 n 가지 모음, 길이 (순서) 및 등가 관계 (추가 정보, 예를 들어 양말의 색)에 대한 모음을 가지고 있습니다. 등가 관계를 통해 원래 컬렉션의 파티션을 만들 수 있으며 모든 등가 클래스에서 우리 주문은 여전히 ​​유지됩니다. 물건 을 동등한 클래스에 매핑하는 것은 O (1)에서 수행 할 수 있으므로 각 항목을 클래스에 할당하는 데 O (n) 만 필요합니다. 이제 우리는 추가 정보를 사용했으며 어떤 방식 으로든 모든 클래스를 정렬 할 수 있습니다. 이점은 데이터 세트가 이미 상당히 작다는 것입니다.

이 방법은 텍스처에있는 모든 더미 파티션보다 색상 쌓기를 여러 개의 동등한 관계로 만들면 길이를 정렬하는 것보다 중첩 될 수 있습니다. 짝수 크기의 요소가 3 개 이상인 파티션을 만드는 등가 관계라면 정렬에 비해 속도가 향상됩니다 (양말을 더미에 직접 할당 할 수있는 경우). 소규모 데이터 세트에서는 정렬이 매우 빠르게 수행 될 수 있습니다.


이것은 잘못된 질문을하고 있습니다. 올바른 질문은 내가 왜 양말을 정렬하는데 시간을 보내는 것인가하는 것입니다. 당신이 선택한 X 화폐 단위의 자유 시간을 소중하게 생각할 때, 매년 얼마나 비쌉니까?

그리고 더 자주는 아니지만, 이것은 여가 시간이 아닌 아침 시간대입니다. 침대에서 보내거나 커피를 마시거나 조금 일찍 떠나 트래픽에 걸리지 않을 수 있습니다.

한발 뒤로 물러나서 문제를 해결할 수있는 방법을 생각해 보는 것이 좋습니다.

그리고 방법이 있습니다!

좋아하는 양말을 찾으십시오. 다양한 조명 조건, 전반적인 품질 및 내구성, 다양한 기후 조건의 편안함 및 냄새 흡수성에서 색상과 관련된 모든 기능을 고려하십시오. 또한 중요한 것은 저장시 탄력성을 잃어서는 안되기 때문에 천연 섬유가 좋으며 플라스틱 포장재로 사용할 수 있어야합니다.

좌우 양말 사이에 차이가 없으면 좋지만 중요하지는 않습니다. 양말이 좌우 대칭이라면 쌍을 찾는 것은 O (1) 연산이며, 양말을 정렬하는 것은 대략 O (M) 연산입니다. 여기서 M은 양말로 깔린 집의 수입니다. 이상적으로는 작은 상수.

왼쪽과 오른쪽 양말이 다른 멋진 쌍을 선택한 경우 왼쪽과 오른쪽 발 양동이에 전체 양동이 정렬을 수행하면 O (N + M)을 취합니다. 여기서 N은 양말의 수이고 M은 위와 같습니다. 다른 사람은 첫 번째 쌍을 찾는 평균 반복에 대한 수식을 제공 할 수 있지만 맹목적 검색을 사용하여 쌍을 찾는 최악의 경우는 N / 2 + 1이며 합리적인 N의 경우 천문학적으로는 불가능합니다. 고급 이미지를 사용하면 속도가 빨라질 수 있습니다. Mk1 Eyeball 으로 정렬되지 않은 양말 더미를 스캐닝 할 때 인식 알고리즘과 경험적 방법을 사용합니다.

따라서, O (1) 양말 쌍이 효율 (대칭 양말 가정)을 달성하기위한 알고리즘은 다음과 같습니다.

  1. 남은 평생 동안 필요한 양말 몇 개를 예상해야합니다. 아니면 은퇴하고 더운 기후로 이동할 때까지 양말을 다시 착용 할 필요가 없습니다. 당신이 젊다면 가정에 양말 정렬 로봇을 갖기까지 걸리는 시간을 예상 할 수 있으며 전체적인 문제는 무의미 해집니다.

  2. 선택한 양말을 일괄 적으로 주문할 수있는 방법과 그 양과 비용을 알아 내야합니다.

  3. 주문 양말!

  4. 옛날 양말을 벗어 버려라.

대안의 3 단계는 몇 년에 걸쳐 한 번에 몇 켤레의 저렴한 양말을 구입하고 양말을 분류하는 비용을 추가하는 비용을 비교하는 것이지만 대량 구매는 저렴합니다. 또한 스토리지의 양말은 주가 인플레이션 율에 따라 가치가 상승합니다. 이는 많은 투자에서 얻을 수있는 것보다 큽니다. 그런 다음 다시 스토리지 비용도 있지만 양말은 실제로 옷장의 맨 선반에 많은 공간을 차지하지 않습니다.

문제 해결됨. 그래서, 그냥 새로운 양말을 가져 가거나 던지거나 낡은 것을 기증하고 평생 동안 돈과 시간을 절약한다는 것을 알면 행복하게 살 수 있습니다.


이론적 인 한계는 O (n)입니다. 왜냐하면 여러분은 각 양말을 만질 필요가 있기 때문입니다 (어떤 것은 이미 어떻게 든 쌍을 이루지 않는 한).

기수 정렬을 사용 하여 O (n)을 얻을 수 있습니다. 버킷에 대한 일부 속성 만 선택하면됩니다.

  1. 먼저 (그녀, 내)를 선택할 수 있습니다 - 그들을 두 더미로 나눠서,
  2. 색상을 사용하십시오 (예 : 색상 이름에 따라 사전 순으로 색상 순서를 지정할 수 있음) - 색상별로 파일을 분할하십시오 (동일한 더미에있는 모든 양말에 대해 1 단계의 초기 순서를 기억하십시오).
  3. 그 다음 양말의 길이,
  4. 다음 질감, ....

제한된 수의 속성을 선택할 수 있지만 각 쌍을 고유하게 식별 할 수있는 속성이 충분하면 O (k * n)로 완료해야합니다. k는 제한적이라고 생각하면 O (n)입니다.


정렬 솔루션이 제안되었지만 정렬이 너무 많습니다 . 우리는 순서가 필요하지 않습니다. 우리는 단지 평등 그룹이 필요합니다 .

따라서 해싱 은 충분히 빠릅니다 (그리고 더 빠름).

  1. 양말의 각 색깔을 위해, 더미를 형성하십시오 . 입력 바구니의 모든 양말을 반복 하여 색상 더미에 분배 하십시오.
  2. 각 더미를 반복 하고 일부 다른 메트릭 (예 : 패턴)으로 두 번째 더미 세트에 분산시킵니다.
  3. 모든 양말을 시각적으로 즉시 처리 할 수있는 아주 작은 더미 에 배포 할 때까지 반복적으로이 계획을 적용 하십시오.

이러한 재귀 적 해시 분할은 실제로 거대한 데이터 집합에 대한 해시 결합 또는 해시 집계가 필요할 때 SQL Server 에서 수행됩니다. 빌드 입력 스트림을 독립적 인 여러 파티션으로 분배합니다. 이 체계는 임의의 양의 데이터와 여러 CPU를 선형으로 확장합니다.

각 버킷이 매우 빠르게 처리 할 수있을만큼 충분히 작은 버킷제공 하는 배포 키 (해시 키)를 찾을 수있는 경우 재귀 분할이 필요하지 않습니다. 불행히도, 나는 양말이 그런 재산을 가지고 있다고 생각하지 않습니다.

각 양말에 "PairID"라는 정수가 있으면 PairID % 10 (마지막 숫자)에 따라 10 개의 양동이에 쉽게 분배 할 수 있습니다.

필자가 생각할 수있는 최상의 실제 분할 은 더미사각형을 만드는 것입니다. 한 차원은 색상이고 다른 하나는 패턴입니다. 왜 사각형인가? 더미에 O (1) 랜덤 액세스가 필요하기 때문입니다. (3D cuboid 도 작동하지만 실용적이지는 않습니다.)

최신 정보:

병렬 처리는 어떨까요? 여러 사람이 양말을 더 빨리 맞출 수 있습니까?

  1. 가장 단순한 병렬화 전략은 여러 작업자가 입력 바구니에서 꺼내 양말을 묶어 놓는 것입니다. 이것은 단지 너무 커야합니다. 10 명 이상의 사람들이 100 명 이상 싸우는 것을 상상해보십시오. 동기화 비용 (손 충돌 및 인간 커뮤니케이션으로 나타남) 은 효율성과 속도를 저하시킵니다 ( Universal Scalability Law 참조). 이것은 교착 상태 가 발생하기 쉬운가 ? 아니요, 각 작업자는 한 번에 하나의 파일에만 액세스해야하기 때문입니다. 하나의 "잠금 장치"만 있으면 교착 상태가 발생할 수 없습니다. 인간이 더미에 대한 접근을 조정하는 방법에 따라 생동감 이 가능할 수도 있습니다. 네트워크 카드와 같이 임의의 백 오프를 사용하는 것만으로 물리적 수준에서 네트워크 카드를 독점적으로 액세스 할 수있는 카드를 결정할 수 있습니다. NICs 에서 작동하는 경우 인간에게도 잘 작동합니다.
  2. 각 근로자가 자체 더미 세트를 가지고 있다면 거의 무한히 확장됩니다. 그런 다음 작업자는 입력 바구니에서 대량의 양말을 가져올 수 있습니다 (드물게 수행하기 때문에 경합이 거의 없음). 양말을 분배 할 때 (스레드 로컬 더미가 있기 때문에) 동기화 할 필요가 없습니다. 결국, 모든 근로자는 그들의 더미 세트를 결합해야합니다. 작업자가 집계 트리를 구성하는 경우 O (로그 (작업자 당 작업자 수 * 더미))로 수행 할 수 있다고 생각합니다.

요소 구분 문제는 어떻습니까? 기사에서 알 수 있듯이 요소 구분 문제는 O(N) 에서 풀 수 있습니다. 이것은 양말 문제 ( O(N) , 단 하나의 배포 단계가 필요한 경우도 마찬가지 O(N) (인간은 계산이 잘못되어 여러 단계를 제안 했으므로 md5(color, length, pattern, ...) , 즉 모든 속성의 완벽한 해시 )).

분명히 O(N) 보다 빨리 갈 수 없으므로 최적의 하한에 도달했습니다.

결과가 정확히 동일하지는 않지만 (한 경우에는 부울, 다른 경우에는 양말) 쌍방의 복잡성은 동일합니다.


"이동"작업이 상당히 비싸고 "비교"작업이 저렴하고 원본 세트보다 검색이 훨씬 빠른 버퍼로 전체 세트를 이동해야하는 경우 ... 의무 사항으로 정렬을 통합하면됩니다. 움직임.

정렬 과정을 건조에 매달려 통합하는 것이 바람을 피우는 것을 발견했습니다. 어쨌든 각 양말을 집어 들고 (움직여) 매달려 야합니다. 문자열의 특정 위치에 매달아 놓지 않아도됩니다. 이제 전체 버퍼 (문자열)를 강제로 검색하지 않고 색 / 음영으로 양말을 배치하도록 선택합니다. 더 어두운 왼쪽, 더 밝고 오른쪽,보다 화려한 전면 등. 이제 각 양말을 매달기 전에, 일치하는 것이 이미 있다면 "오른쪽 부근"을 본다. 이것은 2-3 개의 다른 양말에 "스캔"을 제한한다. 나는 그 옆에 다른 하나를 걸어 놓는다. 그런 다음 나는 건조한 상태에서 끈에서 꺼내면서 쌍으로 구른다.

이제는 이것이 색으로 말뚝을 형성하는 것과는 다른 것 같지 않을 수 있습니다. 그러나 먼저 별개의 말뚝을 선택하지 않고 범위를 지정함으로써 "자주색"이 "빨간색"또는 "파란색"더미로 분류되는지 여부를 분류하는 데 아무런 문제가 없습니다. 그냥 간다. 그런 다음 두 작업 (건조 및 정렬 중단)을 정렬하여 정렬하는 동안 발생하는 오버 헤드는 별도의 정렬 작업의 10 %와 비슷합니다.


사례 1 : 모든 양말이 동일합니다 (이것이 내가 실제 삶에서하는 방식입니다).

두 명 중 하나를 선택하여 한 쌍을 만듭니다. 일정한 시간.

사례 2 : 일정한 수의 조합 (소유권, 색상, 크기, 질감 등)이 있습니다.

기수 정렬을 사용하십시오. 비교가 필요하지 않기 때문에 이것은 단지 선형 시간입니다.

사례 3 : 조합의 수는 사전에 알려지지 않았다 (일반적인 경우).

두 개의 양말이 한 쌍이되어 있는지 확인하기 위해 비교를해야합니다. O(n log n) 비교 기반 정렬 알고리즘 중 하나를 선택하십시오.

그러나 실생활에서 양말의 수가 상대적으로 적을 때 (이론적으로는 최적의 알고리즘은 잘 작동하지 않을 것입니다. 이론적으로는 2 차 시간을 필요로하는 순차 검색보다 훨씬 더 많은 시간이 소요될 수 있습니다.


잘못된 문제를 해결하려고합니다.

해결책 1 : 세탁 바구니에 더러운 양말을 넣을 때마다 작은 매듭으로 묶으십시오. 그런 식으로 세탁 후에는 아무런 정렬 작업을하지 않아도됩니다. Mongo 데이터베이스에 색인을 등록하는 것과 같습니다. 앞으로 약간의 CPU 절약을위한 약간의 작업.

해결책 2 : 겨울이라면, 맞는 양말을 착용 할 필요가 없습니다. 우리는 프로그래머입니다. 아무도 그것이 작동하는 한, 알 필요가 없습니다.

해결책 3 : 작업을 분산하십시오. UI를 차단하지 않고 이러한 복잡한 CPU 프로세스를 비동기 적으로 수행하려고합니다. 양말 더미를 가지고 가방에 담아 라. 필요할 때 쌍을 찾습니다. 그렇게하면 작업량이 눈에 띄지 않습니다.

희망이 도움이!


나는 적은 양의 작업이나 적은 시간의 소비를 약속하지 않는 또 다른 해결책을 제시했지만 거대한 일련의 양말 작업에서 시간 소비량을 줄이는 데 충분한 경험적 방법 일 수 있는지 알아봐야합니다.

전제 조건 : 동일한 양말이 있다는 보장은 없습니다. 그들이 동일한 색깔의 경우에 동일한 크기 또는 본이다는 것을 의미하지 않는다. 양말은 무작위로 섞습니다. 이상한 수의 양말이있을 수 있습니다 (일부는 누락되었습니다. 우리는 얼마나 많은 양을 모릅니다). 변수 "index"를 기억하고 0으로 설정하십시오.

결과 는 하나 또는 두 개의 말뚝을 가질 것입니다 : 1. "일치"및 2. "누락"

발견 적 :

  1. 가장 독특한 양말을 찾으십시오.
  2. 일치하는 것을 찾으십시오.
  3. 일치하는 항목이 없다면 "누락 된"더미에 놓습니다.
  4. 가장 독특한 양말이 없어 질 때까지 1.부터 반복하십시오.
  5. 양말이 6 개 미만인 경우 11로 가십시오.
  6. 그 이웃에게 맹목적으로 모든 양말을 짝지어 라. 포장하지 마라.
  7. 일치하는 모든 쌍을 찾아 그것을 묶어서 묶은 쌍을 "일치 된"더미로 옮깁니다. 새로운 경기가 없으면 "index"를 1 씩 증가시킵니다.
  8. "index"가 2보다 큰 경우 (이것은 양말 값에 따라 달라질 수 있습니다. 양말 수가 많을수록 맹목적으로 쌍을 이룰 확률이 적기 때문입니다) 11
  9. 나머지는 임의로 섞는다.
  10. 1로 이동
  11. "색인"을 잊어 버려라.
  12. 양말 따기
  13. 그 쌍을 찾아라.
  14. 양말에 쌍이 없다면, 그것을 "누락 된"더미로 옮깁니다.
  15. 일치하는 항목이 발견되면 쌍을 묶어서 "일치 된"더미로 옮깁니다.
  16. 그래도 양말이 하나 이상 있다면 12
  17. 왼쪽에 하나만 있다면 14로 가라.
  18. 스마일 만족 :)

또한 손상된 양말을 제거한 것처럼 추가로 손상된 양말을 추가 할 수 있습니다. 그것은 2에서 3 사이, 그리고 13에서 14 사이에 삽입 될 수 있습니다.

나는 어떤 경험이나 교정에 대해서 듣기를 고대하고 있습니다.


나는 지금 당장 양말을 맺어 봤는데, 나는 그것을하는 가장 좋은 방법은 다음과 같다는 것을 알았다 :

  • 양말 중 하나를 선택하고 버리십시오 (해당 쌍의 '버켓'을 작성하십시오)
  • 다음 하나가 이전 페어의 쌍이면 기존 버킷에 넣고 그렇지 않으면 새로운 버킷을 만듭니다.

최악의 경우, 당신은 n / 2 개의 다른 버킷을 가질 것이고, 현재 양말의 쌍을 포함하고있는 버킷에 대해 n-2 개의 결정을 할 것입니다. 분명히,이 알고리즘은 단지 몇 개의 쌍이있는 경우 잘 작동합니다. 나는 12 쌍으로 해냈어.

그것은 그렇게 과학적이지는 않지만 잘 작동합니다 :)


비용 : 양말 이동 -> 높게, 라인에서 양말 찾기 / 검색 -> 작음

우리가 원하는 것은 이동 횟수를 줄이고 검색 횟수를 보충하는 것입니다. 또한 호미 사피엔스의 멀티 스레드 환경을 활용하여 디시 전 캐시에서 더 많은 것을 보관할 수 있습니다.

X = 당신, Y = 배우자

모든 양말의 말뚝에서 :

두 개의 양말을 선택하고, 해당하는 X 양말을 X 줄에 놓고, Y 양말을 Y 줄에 다음 사용 가능한 위치에 놓습니다.

A가 비어있을 때까지하십시오.

각 줄 X와 Y에 대해

  1. 한 줄의 첫 번째 양말을 골라서 해당 양말을 찾을 때까지 줄을 따라 찾으십시오.

  2. 양말의 대응 완성 된 라인에 넣어.

  3. 선택 사항 당신이 찾고있는 라인과 현재 찾고있는 양말이 이전과 동일하다면,이 양말에 대해 2 단계를 수행하십시오.

선택적으로 1 단계로 진행하면 두 줄 대신 두 줄의 양말을 집어들 수 있습니다. 캐싱 메모리가 크기 때문에 양말 중 어느 것이 현재 관측중인 줄의 현재 양과 일치하는지 신속하게 파악할 수 있습니다. 당신이 3 개의 팔을 가지고있을만큼 충분히 운이 좋다면, 당신은 아마도 피사체의 기억이 충분히 크다면 3 개의 양말을 동시에 분석 할 수 있습니다.

X와 Y가 모두 비워 질 때까지 마십시오.

끝난

그러나 이것은 선택 정렬과 같은 복잡성을 가지므로 I / O (양말 이동) 및 검색 (양말을 찾기 위해 라인 검색)으로 인해 소요되는 시간이 훨씬 적습니다.


실제 접근법 :

가급적 빨리, 분류되지 않은 파일에서 양말을 한 번에 하나씩 꺼내어 앞에 놓으십시오. 더미는 모든 양말이 같은 방향을 가리 키면서 다소 공간 효율적으로 배열되어야합니다. 말뚝의 수는 쉽게 도달 할 수있는 거리에 의해 제한됩니다. 양말을 얹어 놓을 더미를 선택하는 것은 양말 같은 더미에 양말을 깔아서 가능한 한 빨리해야합니다. 가끔 타입 I (그것이 속하지 않은 파일에 양말을 두는 것) 또는 타입 II (양말 같은 기존 파일이있을 때 자체 더미에 양말 넣기) 오류가 용인 될 수 있습니다 - 가장 중요한 고려 사항은 속도입니다. 모든 양말이 말뚝에 놓이면 신속하게 쌍을 만들고 여러 줄을 쌓는 더미를 통과합니다 (이 두 개는 서랍을 향하고 있습니다). 더미에 양이 맞지 않는 양말이있는 경우 가능한 가장 빠른 제한 내에서 더미로 다시 쌓습니다. 모든 멀티 양말 파일이 처리되면 유형 II 오류로 인해 페어링되지 않은 나머지 양말 용 양말이 일치합니다. 헉, 끝났어 - 나는 많은 양의 양말이 있고 더러워지기 전까지는 씻지 않는다. 또 다른 실용적인 노트 : 한 쌍의 양말 중 하나의 윗부분을 다른 양말 위에 뒤집어 놓고 탄성 속성을 활용하여 서랍에 운반되는 동안 및 서랍에있는 동안 함께 머물러 있습니다.


크기 'N'의 해시 테이블을 고려하십시오.

정규 분포라고 가정하면, 하나의 버킷에 매핑 된 적어도 하나의 양말을 포함하는 '삽입'의 예상 개수는 NlogN입니다 (즉, 모든 버킷이 가득 찼습니다)

나는 이것을 다른 수수께끼의 일부로 도출했으나 잘못 입증 된 것을 기쁘게 생각합니다. 여기에 내 블로그 기사가있다.

'N'은 가지고있는 양말의 고유 한 색상 수 / 패턴 수에 대한 대략적인 상한에 해당한다고합시다.

충돌이 발생하면 (예 : 일치) 양말을 제거하십시오. NlogN 양말의 다음 배치와 동일한 실험을 반복하십시오. 그 아름다움은 인간 마음이 작동하는 방식 때문에 NlogN 병렬 비교 (충돌 해결)를 할 수 있다는 것입니다. :-)


양말 쌍 을 정렬하는 문제 는 O (n) 입니다. 세탁 바구니 에 던지기 전에 왼쪽 상자를 오른쪽으로 끼 웁니다. 그들을 꺼낼 때 실을 자르고 각 쌍을 서랍에 넣으십시오 - n 쌍에 대한 2 작업, 그래서 O (n).

이제 다음 질문은 당신이 당신의 세탁물을 가지고 있는지 그리고 당신의 아내가 그녀의 것을하는지에 관한 것입니다. 이는 완전히 다른 문제 영역에서 발생할 수있는 문제 입니다. :)


귀하의 질문에서 당신은 세탁에 대한 많은 실제 경험이 없다는 것이 분명합니다. :) 소수가 아닌 양말로는 잘 작동하는 알고리즘이 필요합니다.

지금까지는 인간의 패턴 인식 기능을 제대로 활용하지 못했습니다. 세트 게임은 잘하는 방법을 알려줍니다. 모든 양말을 2 차원 공간에 두어 두 손을 잘 인식하고 쉽게 손에 닿도록 할 수 있습니다. 약 120 * 80 cm 정도의 영역으로 제한됩니다. 여기에서 인식 한 쌍을 선택하여 제거하십시오. 여유 공간에 여분의 양말을 넣고 반복하십시오. 쉽게 알아볼 수있는 양말 (작은 애들이 떠오르는 사람들)을 위해 세탁하는 경우, 먼저 양말을 선택하여 기수 정렬을 할 수 있습니다. 이 알고리즘은 단일 양말 수가 적을 때만 효과적입니다.


나는이 문제에 새로운 무언가를 기여할 수 있기를 바란다. 나는 모든 대답이 당신의 전반적인 세탁 성능을 저하시키지 않고 전처리 를 수행 할 수있는 두 가지 점이 있다는 사실을 간과했다 .

또한 우리는 대가족을 위해 많은 수의 양말을 맡을 필요가 없습니다. 양말을 서랍에서 꺼내 착용하고, 세탁하기 전에 머물러있는 장소 (아마도 휴지통)에 버려집니다. 내가 그 bin을 LIFO-Stack이라고 부르지는 않지만, 나는 그것을 말하는 것이 안전하다고 말할 것이다.

  1. 사람들은 상자에서 같은 양의 양말을 거칠게 던지며,
  2. 저장소는 임의의 지점에서 임의 화되지 않으므로
  3. 이 저장소의 맨 위에서 가져온 모든 하위 집합은 일반적으로 쌍의 양말을 모두 포함합니다.

내가 알고있는 모든 세탁기는 크기가 제한되어 있으므로 (세탁해야하는 양말 수에 관계없이) 세탁기에서 실제로 무작위로 추출됩니다. 양말이 몇 개인 경우에도 거의 아무 것도 포함하지 않는 작은 하위 세트가 있습니다. 싱글 톤.

우리의 두 가지 전처리 단계는 "양말을 빨랫줄에 두는 것"과 "빨랫줄에서 양말을 가져가는 것"입니다. 우리는해야 할 일이 있습니다. 깨끗하고 건조한 양말을 얻기 위해서입니다. 세탁기와 마찬가지로 빨랫줄도 유한하며, 우리는 양말을 신는 줄의 모든 부분을 가지고 있다고 가정합니다.

put_socks_on_line ()에 대한 알고리즘은 다음과 같습니다.

while (socks left in basket) {
 take_sock();
 if (cluster of similar socks is present) { 
   Add sock to cluster (if possible, next to the matching pair)
 } else {
  Hang it somewhere on the line, this is now a new cluster of similar-looking socks.      
  Leave enough space around this sock to add other socks later on 
 }
}

양말을 움직이거나 가장 잘 맞는 것을 찾는 데 시간을 낭비하지 마십시오.이 모든 작업은 O (n)에서 수행해야하며, 정렬되지 않은 행에 넣기 위해 필요합니다. 양말은 아직 페어링되지 않았으므로, 우리는 라인 상에 몇 가지 유사성 클러스터만을 가지고 있습니다. 제한된 양말 세트를 가지고 있으면 도움이됩니다. 이는 "좋은"클러스터를 만드는 데 도움이됩니다. 예를 들어, 양말 세트에 검은 색 양말 만있는 경우 색으로 클러스터링하는 것이 좋지 않습니다.

take_socks_from_line ()에 대한 알고리즘은 다음과 같습니다.

while(socks left on line) {
 take_next_sock();
 if (matching pair visible on line or in basket) {
   Take it as well, pair 'em and put 'em away
 } else {
   put the sock in the basket
 }

나는 나머지 단계의 속도를 향상시키기 위해 무작위로 다음 양말을 선택하는 것이 아니라 각 클러스터에서 양말을 순차적으로 가져 오는 것이 현명하다는 것을 지적해야한다. 두 가지 전처리 단계는 양말을 줄에 넣거나 바구니에 넣는 것보다 시간이 오래 걸리지 않습니다. 우리는 무엇을해야 하느냐에 따라 빨래 성능이 크게 향상됩니다.

그런 다음 해시 분할 알고리즘을 쉽게 수행 할 수 있습니다. 보통, 양말의 약 75 %가 이미 쌍으로되어있어, 양말의 아주 작은 하위 집합을 남겨두고,이 하위 집합은 이미 (다소) 클러스터되어 있습니다 (전처리 단계 후에 내 바구니에 많은 엔트로피를 도입하지 않습니다). 또 다른 한가지는 남아있는 클러스터는 한 번에 처리 할 수있을만큼 작기 때문에 전체 클러스터를 바스켓에서 제거 할 수 있습니다.

sort_remaining_clusters () 알고리즘은 다음과 같습니다.

while(clusters present in basket) {
  Take out the cluster and spread it
  Process it immediately
  Leave remaining socks where they are
}

그 후 몇 가지 양말 만 남아 있습니다. 여기에서 이전에 페어링되지 않은 양말을 시스템에 도입하고 특별한 알고리즘없이 나머지 양말을 처리합니다. 나머지 양말은 거의없고 시각적으로 매우 빠르게 처리 할 수 ​​있습니다.

남아있는 모든 양말에 대해, 나는 상대방이 아직 씻지 않았다고 가정하고 다음 반복을 위해 멀리 둔다. 시간이 지남에 따라 쌍이 아닌 양말의 성장을 등록하면 ( "양말 누출") 빈을 확인해야합니다 - 무작위로 추출 될 수도 있습니다 (고양이가 잠 들어 있습니까?)

나는이 알고리즘들이 LIFO 스택, 제한된 일반 세탁기, 제한된 일반 빨랫줄처럼 작동하는 저장소를 많이 사용한다는 것을 알고 있습니다. 그러나 이것은 매우 많은 수의 양말을 가지고도 여전히 작동합니다.

병렬 처리 정보 : 양말을 같은 용지함에 던지면 모든 단계를 쉽게 병렬 처리 할 수 ​​있습니다.


양말을 분류 할 때, 근사한 기수 정렬 을합니다. 동일한 색상 / 패턴 유형의 다른 양말 근처에 양말을 떨어 뜨립니다. 내가 양말을 떨어 뜨릴 위치 근처에서 정확히 일치하는 것을 볼 수있는 경우를 제외하고 그 시점에서 그 쌍을 추출합니다.

거의 모든 다른 알고리즘 ( usr에 의한 최고 득점 대답 포함 )은 정렬 한 다음 쌍을 제거합니다. 나는 인간으로서, 한 번에 고려되는 양말의 수를 최소화하는 것이 낫다는 것을 알았다.

나는 이것을 다음과 같이 행한다 :

  1. 독특한 양말 (무엇이든간에 내 눈을 먼저 잡는다)을 고른다.
  2. 더미에서 양말을 뽑아서 개념적 위치에서 기수 정렬을 시작합니다.
  3. 새 양말을 현재 더미에 가까이 놓습니다. 거리에 따라 달라집니다. 양말이 동일하기 때문에 양말을 다른 쪽 위에 올려 놓는다면 양측에 쌍을 형성하고 제거하십시오. 이것은 미래의 비교가 정확한 위치를 찾는 데 더 적은 노력을 기울인다는 것을 의미합니다.

이것은 O (1) 시간에서 퍼지 - 매치 (fuzzy-match)에 대한 인간의 능력을 이용하는데, 이는 컴퓨팅 장치에서의 해시 - 맵 (hash-map)의 설정과 다소 동일하다.

독특한 양말을 먼저 당기면 덜 특색이있는 기능을 "확대"할 수있는 공간을 남겨 둡니다.

유색 형광 색소, 줄무늬가있는 양말, 긴 양말 3 쌍을 제거한 후에는 착용하는 방법에 따라 대략 백색의 양말로 정리할 수 있습니다.

어떤 시점에서, 양말 사이의 차이는 다른 사람들이 차이를 느끼지 못할 정도로 작으며, 더 이상 일치하는 노력이 필요하지 않습니다.


양말을 집을 때마다 한 곳에 담으십시오. 다음 양말을 가져오고, 첫 번째 양말과 일치하지 않으면 첫 번째 양말 옆에 놓습니다. 만약 그렇다면 쌍이 있습니다. 이렇게하면 얼마나 많은 조합이 존재하는지 상관 없으며, 양말마다 이미 두 가지 가능성이 있습니다. 양말 배열에 이미 일치하는 것이 있거나 그렇지 않은 경우입니다. 그것을 배열의 장소에 추가하십시오.

이것은 또한 양말이 일치 할 때 제거 될 것이기 때문에 거의 모든 배열을 양말로 가질 수 없다는 것을 의미합니다.


첫 번째 양말을 집어 테이블 위에 놓습니다. 이제 다른 양말을 골라주십시오. 첫 번째 선택 항목과 일치하는 경우 첫 번째 항목 위에 놓습니다. 그렇지 않은 경우 테이블에서 첫 번째와 약간 떨어진 곳에 놓습니다. 세 번째 양말을 골라 라. 이전 두 개 중 하나와 일치하는 경우 위에 놓거나 다른 위치에서 약간 떨어진 곳에 두십시오. 당신이 모든 양말을 집어들 때까지 반복하십시오.


패턴을 해시로 사용하여 일치하지 않는 양말에 사용할 해시 테이블을 만듭니다. 양말을 하나씩 반복하십시오. 양말이 해시 테이블에서 일치하는 패턴을 가지고 있다면, 양말을 테이블에서 꺼내어 한 쌍을 만듭니다. 양말에 일치하는 것이 없으면 테이블에 넣으십시오.







matching