본문 바로가기

알고리즘 & 확률

(14)
피셔-예이츠 셔플 (Fisher-Yates Shuffle) 우리는 종종 무언가를 잘 뒤섞을 필요가 있습니다. 예를 들어, 친구들과 여행을 가서 저녁을 맛있게 먹은 다음 설거지 당번을 뽑는 경우를 생각해 봅시다. 다양한 방법이 있겠지만, 가장 고전적인 방법 중 하나는 종이 조각을 사람 수만큼 준비하고 한 곳에 '꽝'을 적은 후 이를 잘 뒤섞고 한 명씩 종이 조각을 뽑는 것입니다. 이때 우리는 이 조각들이 잘 뒤섞여 있기를 바랍니다. 다른 예시로는 포커 게임을 들 수 있겠습니다. 딜러는 게임을 시작하기 전에 카드를 뒤섞습니다. 이때 게임 참가자들은 카드가 잘 뒤섞여 있기를 희망할 터입니다. 그렇다면, 과연 어떻게 하면 잘 뒤섞을 수 있을까요? 사실 이 주제는 처음부터 제가 정리하겠다고 염두에 둔 주제는 아니었습니다. 처음에는 쿠폰 수집가 문제(coupon colle..
「상자에 공 넣기, 상자를 두 개씩 고르면?」 증명 보충 예전에 상자에 공 넣기 문제(balls-into-bins problem)에서 매번 상자 두 개를 균일한 확률로 골라 공의 개수가 적은 쪽에 넣으면 어떻게 되는지 소개해 드린 적이 있습니다. 2020.03.22 - [알고리즘 & 확률/Balls into bins] - 상자에 공 넣기, 상자를 두 개씩 고르면? (Power of Two Choices) 상자에 공 넣기, 상자를 두 개씩 고르면? (Power of Two Choices) 지난 포스트에서는 상자에 공 넣기 문제(balls into bins problem)를 공부했습니다. 2020/03/21 - [수학적 도구/Randomness] - 상자에 공 넣기 (Balls into Bins Problem) 상자에 공 넣기 (Balls into Bins Pro..
도박꾼의 파산 (Gambler's Ruin) 일확천금을 노리는 한 도박꾼이 있다고 하죠. 이 도박꾼이 참여한 게임은 아주 간단합니다. 매 판마다 이기면 십만 원을 얻고 지면 십만 원을 잃습니다. 이 도박꾼이 오백만 원의 자본금으로 시작해서 천만 원을 더 벌고 싶다고 합시다. 과연 이 도박꾼이 목표를 이룰 확률은 어떻게 될까요? 반대로 이 도박꾼이 파산하게 될 확률은 또 어떻게 될까요? 이는 도박꾼의 파산(gambler's ruin)이라는 이름으로 많이 연구된 문제입니다. 위 상황을 좀더 일반화하면 다음과 같습니다. 도박꾼이 참여하는 게임에서 매 판마다 도박꾼은 \(p\)의 확률로 이기며, \(1 - p\)의 확률로 집니다. 단위를 간소화하기 위해 도박꾼이 이기면 1원을 얻고, 지면 1원을 잃는다고 합시다. 도박꾼은 처음에 \(L\)원의 자본금을 갖..
비서 문제 (Secretary Problem) 여러분이 다음 뽑기 게임에 참가했다고 가정해 봅시다. 안을 볼 수 없는 상자가 여러분 앞에 놓여 있습니다. 여러분은 상자 안에 총 \(n\) 개의 공이 들어 있다는 것과, 공에는 서로 다른 숫자가 적혀 있다는 것을 알고 있습니다. 이제 여러분은 상자에서 공을 하나씩 무작위로 뽑고 공의 숫자를 확인할 것입니다. 만약 숫자가 마음에 든다면 여러분은 이 공을 선택할 수 있고, 만약 마음에 들지 않는다면 이를 버리고 새 공을 뽑을 수 있습니다. 다만 한 번 버린 공은 다시 주울 수 없죠. 가장 큰 숫자가 적힌 공을 선택해야 뽑기 게임에서 이긴다고 할 때, 과연 여러분은 어떤 전략을 취해야 할까요? 이 문제는 1950-60년대 여러 수학자들과 통계학자들 사이에서 매우 깊이 연구되었던 비서 문제(secretary ..
랜덤 알고리즘과 알고리즘의 확률적 분석 (Randomized Algorithms & Probabilistic Analysis of Algorithms) 요새 알고리즘에 어떻게 확률론이 사용되는지를 공부하고 있습니다. 그러면서 예전에는 잘 몰랐거나 어렴풋이만 알던 내용들을 정확히 바로 잡고 있는데요. 그중에서도 가장 기본적인 내용을 하나 가볍게 짚고 넘어 가고자 합니다. 바로 랜덤 알고리즘(randomized algorithm)과 알고리즘의 확률적 분석(probabilistic analysis of algorithm)인데요. 결론을 미리 말씀 드리자면 둘은 서로 다릅니다. 랜덤 알고리즘은 확률 시행이 알고리즘의 내부에서 이루어지는 것을 지칭합니다. 대신 주어지는 입력에 대해서는 어떠한 가정도 존재하지 않죠. 확률 시행이 알고리즘의 내부에서 진행되니, 알고리즘은 동일한 입력에 대해서도 다른 결과를 출력할 수 있습니다. 이러한 알고리즘의 성능을 분석할 때는 ..
체르노프 부등식 (Chernoff Bounds) 여러분의 눈 앞에 총 \(n\)개의 서로 다른 상자가 놓여 있다고 합시다. 각 상자 안에는 흰 공과 검은 공으로만 차 있습니다. 여러분은 각 상자의 흰 공과 검은 공의 비율이 얼마나 되는지 모두 알고 있습니다. 즉, \(i\) 번째 상자에는 \( p_i \)의 비율로 흰 공이 있다고 해 보겠습니다. 여러분이 상자에서 각각 공을 하나씩 뽑는다면 과연 흰 공은 몇 개를 뽑게 될까요? 그 기댓값은 구하기 쉽습니다. 바로 기댓값의 선형성(linearity of expectation)에 의해 \( \sum_{i = 1}^n p_i \) 개가 될 것입니다. 그렇다면 실제로 공을 뽑았을 때, 과연 흰 공의 개수가 기댓값 혹은 기댓값 부근의 값이 될 확률은 얼마나 될까요? 이는 신뢰의 문제입니다. 만약 그 값이 들쭉날..
지연 결정의 원리 (Principle of Deferred Decisions) 최근 논문을 읽는 중에 "지연 결정의 원리(principle of deferred decisions)"에 대해 알게 되었습니다. 이해가 잘 되지 않아서 인터넷에서도 열심히 찾아 보았으나 국문은 고사하고 영문으로 된 자료도 찾기 어렵더군요. 그나마 있는 자료들도 대부분 학교 수업 자료여서 제가 원하는 수준으로 상세하게 기술되어 있지 않았습니다. 다행히 교과서를 하나 찾게 되어 이 주제를 좀더 깊이 이해할 수 있었습니다. 이번 시간에는 이 원리에 대해서 한번 정리해 보겠습니다. 참고로 번역은 다음에서 "principle of deferred decisions"를 쳤을 때 나오는 거의 유일한 국문 웹페이지에서의 번역을 그대로 가지고 왔습니다. 원리를 이해하기 위해 다음 예제 게임을 함께 생각해 봅시다. 책상 ..
쿠폰 수집가 문제 (Coupon Collector Problem) 포켓몬 빵을 기억하시나요? 지금도 파는지는 잘 모르겠습니다만, 제가 어릴 적만 하더라도 큰 인기가 있던 빵이었습니다. 특히 그 빵이 인기가 있던 이유는 빵을 사면 그 안에 동봉되어 있던 포켓몬 "띠부띠부 씰" 때문이었다고 생각합니다. 대개는 플라스틱 책받침에 씰을 모았고, 개중에서 모으는 데 진심인 친구들은 클리어 파일에다가 씰을 붙여서 모았죠. 저도 책받침에다가 몇 개 모았던 기억이 있습니다. 씰을 모으던 아이들의 목표는 당연히 모든 씰을 모으는 것이었을 겁니다. 당시 포켓몬은 255마리였던 것으로 기억합니다. 여기서 한 가지 의문점이 생기죠. 과연 아이들은 몇 개의 빵을 사 먹어야 모든 포켓몬 씰을 모을 수 있었을까요? 정말로 운이 좋은 경우라면 사는 족족 다른 포켓몬이 나와서 255개면 충분합니다...
선형 시간에 중간값 구하기 (Quick-Select & Median-of-Medians) 이번 포스트에서 함께 공부할 내용은 중간값(median)을 구하는 방법입니다. 중간값은 어떤 수열을 오름차순으로 정렬했을 때 가운데에 위치한 수를 의미합니다. 예를 들어, 수열이 \[ 4, 8, 3, 1, 6 \]으로 주어졌을 때, 이를 오름차순으로 정렬하면 \[ 1, 3, 4, 6, 8 \]이 되고, 여기서 중간값은 \(4\)가 되겠습니다. 만약 수열의 길이가 짝수라면 중간에 위치한 수는 두 개가 됩니다. 이 글에서는 크기가 다르다면 둘 중 크기가 더 작은 값을 중간값으로 정의하겠습니다. 중간값을 구하는 가장 간단한 방법은 수열을 먼저 정렬한 후에 가운데에 위치한 수를 찾는 것입니다. (비교 기반) 정렬 알고리즘은 수열의 길이 \(n\)에 대해 \( \Theta(n \log n) \)에 수행된다는 사실..
확률 퀵 정렬 분석 (Analysis on Randomized Quick-Sort) 요즘 백준 온라인 저지에서 문제를 하나씩 풀고 있습니다. 재밌더군요. 좀더 어릴 때부터 이를 해왔다면 더 좋지 않았을까 생각합니다. 주위에 문제 해결 분야를 열심히 연습하는 친구들이 많이 있는데, 그 친구들이 생각하는 건 확실히 남다른 것 같더라고요. 저도 그런 실력을 갖췄다면 어땠을까 생각하며 부러워하기도 합니다. 여튼 지금부터라도 한다면 도움이 되지 않을까요? 아무튼 백준 문제를 풀다 보니 정렬 알고리즘을 사용해야할 때가 자주 있었습니다. 그리고 그때마다 저 나름대로 퀵 정렬(quick-sort)을 구현해왔습니다.(의 std::sort()가 그렇게 좋다는 사실은 최근에야 알게 되었습니다. 지금은 직접 안 짭니다. 하하.) 그러다 문득 퀵 정렬의 시간 복잡도 분석이 궁금해졌습니다. 대학생 때 퀵 정렬이..