주요 내용
컴퓨터과학
추측 게임
같은 문제에 적용한 서로 다른 알고리즘에서 효율성이 얼마나 다르게 나타나는지 알아보기 위해 간단한 게임을 해보기로 합시다. 컴퓨터는 1에서 16까지의 정수 중 무작위로 하나를 선택합니다. 컴퓨터가 고른 수를 알아낼 때까지 계속 그 수를 추측하는데, 각 추측마다 수가 높았는지 낮았는지를 알려 줍니다:
숫자를 맞췄다면, 다음 수를 추측하는데 사용했던 방법에 대해 생각해 보세요.
1을 고르고 2, 3, 4 를 고르는 방식으로 맞을 때까지 했을 수도 있을 겁니다. 이렇게 찾는 방법은 숫자들을 줄지어 있는것처럼 차례대로 검색하기 때문에 선형 검색(linear search)이라고 합니다. 꽤 확실한 방법이죠. 하지만 얼마나 많이 추측을 해야 할까요? 컴퓨터가 16을 고르게 되면 16번이나 추측을 해야 합니다. 또한 정말 운 좋게도 컴퓨터가 1을 골랐다면 첫 번째 추측에서 숫자를 맞출 수 있겠죠. 평균적으로는 어떨까요? 컴퓨터가 1에서 16까지의 수를 고를 확률이 같다면 평균은 8번일 것입니다.
그렇지만 단순히 1, 2, 3, 4,...처럼 일일이 추측하는 방법보다 더 효율적인 방법이 있을 겁니다. 그렇죠? 컴퓨터가 추측한 값이 큰지 작은지 얘기해 주니까 8부터 시작할 수 있습니다. 컴퓨터가 고른 숫자가 8보다 작다면 8이 너무 크다는 것을 알기 때문에 8에서 16까지의 수는 고려 대상에서 제외할 수 있습니다. 컴퓨터가 고른 숫자가 8보다 크다면 1에서 7까지의 수를 제외할 수 있습니다. 어느 쪽이든 숫자 범위의 반을 제외할 수 있겠죠. 다음번 추측에도 남아있는 숫자들 중에서 가운데 있는 수를 제거합니다. 이런 식으로 남아있는 숫자의 절반을 계속 제외합니다. 이런 방법을 이진 탐색(binary search)이라고 하는데 이 방법으로는 컴퓨터가 1부터 16중에 무슨 수를 고르던 최대 네 번의 추측 안에 수를 맞출 수 있습니다.
1에서 300까지의 수로도 한 번 해 보세요. 최대 아홉 번의 추측이면 맞출 수 있을 겁니다.
이번에는 수를 맞추는데 몇 번이나 필요했나요? 아홉 번 이상의 추측이 필요하지 않은 이유는 뭘까요? (수학적으로 설명할 수 있나요)?
어떻게 이진 검색으로 JavaScript 배열에서 특정 항목을 효율적으로 검색하는지 알아보겠습니다. 그전에 먼저, 조금 더 어려운 알고리즘을 살펴보겠습니다.
위 자료는 다트머스 대학교 컴퓨터공학과의 토마스 콜먼 교수와 데빈 발컴 교수, 그리고 칸아카데미 컴퓨팅 과정 팀이 공동으로 저술했으며, 본 내용물의 저작권은 CC-BY-NC-SA 라이선스를 적용합니다.
대화에 참여하고 싶으신가요?
- 아홉번이상의 추측이 필요하지 않은 이유를 알고싶습니다(추천 11 번)
- 경우의 수가 반씩 줄어든다. 2^9 = 512이기 때문에 양 변에 로그를 취하면, 512개의 숫자라면 9번 안에 추측가능하다(추천 9 번)
- 이 설명이 옳을까요? 수학적인 표현이나 수식이 잘못된 것이 있으면 말씀해주세요.
주어진 선택 가능한 경우의 수 300이 2^8=256 과 2^9=300의 중간이므로 경우의 수가 절반씩 줄어든다 할 떄 싣할 수 있는 횟수는 300을 2로 나눠 300, 150, 75, 37.5 18.75 9.375 4.1875 2.9375 1.4... 경우의 수가 1보다 작아지면 시도할 수 없다. 즉 기회가 있는 것은 9번 뿐이다.
이것을 로그로 표현하면 log 2 9 = 512(추천 8 번) - 여기서 알고리즘은 뭘 의미하나요? 알고리즘은 어떤 수행의 방법이라고 이해하고 있는데 이번에 한 활동에서 알고리즘은 무엇인가요?
숫자하나를 선택했을 때 컴퓨터의 선택은그보다 큰지 작은지 말해주는 시스템이 알고리즘인건가요?(추천 8 번)- 정확히 검색 알고리즘을 말하는 것 같아요. 이진 검색에 장점을 볼 수 있는거죠.
예를 들면
랜덤값 300 이 나왔을 경우 순차 검색은 300번 전체 숫자를 검색 해야 하지만,
이진 검색 일 경우는 9번 안에 찾을 수 있는 거죠.
1. 150 보다 크네
2. 150 + 75 = 225 보다 크네 (여기서 75는 150을 반으로 나눈 값이죠)
3. 225 + 38 = 263 보다 크네 (38 반올림)
4. 263 + 19 = 282 보다 크네
5. 282 + 10 = 292 보다 크네
6. 292 + 4 = 296 보다 크네
7. 296 + 2 = 298 보다 크네
8. 298 + 1 = 299 보다 크네
9. 299보다 크니 300 이네
이렇게 되는거죠.ㅎ
하지만!
랜덤 값이 1이 나올 경우 순차 검색은 바로 찾게 되죠.
이렇게 검색 알고리즘이 여러가지고 있고
그에 따라 특징이 있다는 걸 알려주는 것 같아요.(추천 7 번)
- 위에있는 추측을 수학적으로 어떻게 표기하나요?
저는 1~300 이라는 수가 있으면 그것에 대 해 반을 150 또 그것에 만을 하는 방식으로 수를 찾았습니다. 이걸 수학적으로 표기하는 방법을 알려주세요!(추천 4 번)- 위에 나오는 추측게임은 추측을 하고서
정답의 숫자가 추측한 숫자보다 큰지 작은지를 알려줍니다.
가령 1부터 5까지의 수가 있다고 하면(정답은 5라는 가정)
맨 처음으로 가운데 숫자인 3을 고르는 것이 좋겠지요
3보다 크다고 알려주면 3과 5사이의 가운데 수인 4를 고르고
4보다 크다고 알려주면 마지막으로 5를 고르면 됩니다.
이런방식으로 하면 3번째 선택째에 답을 찾을 수 있습니다.
전체수의 갯수x보다 2의 n제곱수가 클 때
n번의 추측으로 정답을 맞출 수 있는 것입니다.
예로 n을 4라고 가정하면
2 * 2 * 2 * 2 = 16 이므로
16 > x 이 되는, 그러니까
위와 같은 게임의 나열된 수가 16개보다 작을 때 4번안에 맞출 수 있는 것입니다(추천 3 번)
- 너무 유용한 칸아카데미 체계적으로 혼자공부할수있게 쉬운거부터 응용까지 완벽하게 가르쳐주셔서 좋아요(추천 3 번)
- 9번의 추측 안에 맞출수 있다고 말하셨는데 1 부터 차례대로 탐색을 하면 10번도 넘게 됩니다. 왜그런지 알려주세요.(추천 3 번)
- 1부터 순서대로 탐색을 하면 맨 처음 말한 선형검색 알고리즘을 수행한 것 입니다.
여기서 말한 이진 탐색은 가운데 숫자를 지목했을 시 범위에 맞지 않는 수들을 제거하는 방식입니다.(추천 2 번)
- 만약 홀수(예를 들어서 301)이라면 2로 나눌수 없는데 9번만에 어떻게 가능한 거죠?(추천 2 번)
- 정확히 반으로 나눌 필요는 없습니다. 301 이라면 중간값인 150.5에 가까운 수인 150 혹은 151을 먼저 추측해보고 선택된 수가 그보다 큰지 작은지에 따라서 남아 있는 수들 중에서 중간값에 가까운 수를 계속 추측해 나가는 방식이 이진탐색입니다.(추천 1 번)
- 만약홀수(예를들면153)라면2로나누어지지않는데 왜9번이상의추측이 필요하지않은건가요?(추천 1 번)
- 정확히 반으로 나눌 필요는 없습니다. 153 이라면 중간값인 76.5에 가까운 수인 76 혹은 77을 먼저 추측해보고 선택된 수가 그보다 큰지 작은지에 따라서 남아 있는 수들 중에서 중간값에 가까운 수를 계속 추측해 나가는 방식이 이진탐색입니다.(한번의 추측으로 선택지가 (경우의 수 / 2) 혹은 ((경우의수 + 1) / 2) 씩 줄어들게 됩니다.(추천 1 번)
- JavaScript 말고 C 언어를 사용할 수는 없나요?(추천 1 번)
- 제가 아는 알고리즘은 어떤 일을 처리하는 순서 뭐 그런 걸 짜는 것입니다. 그런데 이건 좀 다르네요. 왜그러죠?(추천 1 번)