2023. 5. 31. 10:12ㆍ정윤탐
안녕하세요. 강가의 정보 강승입니다. 저번 게시물은 이공계 체험학습으로 7박 9일동안 다녀온 미국 이야기를 써봤는데요. 오늘은 4월 과제로 낸 테일러 급수를 이어 다른 급수의 수렴에 대해 쓸 계획이었는데 미국도 갔다 오고 매번 급수만 하면 지루하니까 재미있는 확률 문제로 정.윤.탐 주제를 정하게 되었습니다. 오늘 할 재미있는 확률 문제는 몬티 홀 문제입니다.
몬티홀 문제
몬티 홀 문제는 몬티 홀이라는 캐나다-미국 TV 프로그램 사회자가 진행하던 미국 오락 프로그램 《Let's Make a Deal》에서 유래한 확률 문제입니다. 몬티 홀 문제의 핵심적인 규칙만 말하자면 다음과 같습니다.
-닫혀 있는 문 3개가 있다.
-한 문 뒤에는 상품이 있고, 나머지 두 문은 꽝이다
-참가자는 이 3가지 문 중 하나를 골라야 상품을 얻을 수 있다.
-함가자가 문 하나를 고르면 사회자는 남은 2가지 문 중에 하나를 열고 그게 '꽝'이라는 사실을 밝힌다.
-여기서 참가자에게 다른 문으로 바꿀 수 있는 기회가 주어진다.
이 문제를 수학적으로 엄밀하게 풀려면 다음과 같은 전제가 가정됩니다.
-사회자는 자동차가 어느 문 뒤에 있는지 알고 있다.
-사회자는 염소가 들어 있는 문을 임의로 선택한다.
그렇다면 참가자에게 다른 문으로 바꿀 수 있는 기회가 주어졌을 때 참가자가 다른 문으로 바꾸었을 때 상품을 얻을 수 있는 확률이 높을까 아니면 바꾸지 않았을 때 상품을 얻을 수 있는 확률이 높을까요? 정담은 바로 선택을 바꾸는 것이 훨씬 이득이라는 것입니다. 바꾸지 않았을 때 상품을 얻을 확률은 1/3이지만 바꾸었을 때 상품을 얻을 수 있는 확률은 2/3입니다. 여기서 의문을 가질 수도 있습니다. 사회자가 남은 2가지 문 중 꽝인 문 하나를 열어서 보여주면 상품을 얻을 수 있는 확률이 바꾸지 않았을 때와 바꾸었을 때 둘 다 1/2이 아닌가라는 생각이 들기도 하고 바꾸지 않았을 때 상품을 얻을 확률은 1/3아자먼 바꾸었을 때 상품을 얻을 수 있는 확률은 1/2이 아닌가라는 생각이 들기도 하고 정말 별의별 생각과 의견들이 나옵니다. 그렇다면 왜 1/3,2/3이 나오는 걸까요?
각각의 경우를 나눠서 한 번 계산해보도록 하겠습니다.
1. 참가자는 문을 무조건 바꾼다.
1)처음에 꽝인 문을 선택할 확률= 2/3
-사회자는 무조건 꽝인 문을 선택해서 연다= 1/1
-문을 바꿨을 경우 자동차가 있을 확률= 1/1
-2/3 * 1/1 * 1/1=2/3
2)처음에 상품이 있는 문을 선택할 확률=1/3
(1)사회자가 꽝 인 문 중 첫번째 것을 선택할 확률=1/2
-문을 바꿨을 때 상품이 있을 확률=0/1
-1/3 * 1/2 * 0/1=0/6
(2)사회자가 꽝인 문 중 두번째 것을 선택할 확률=1/2
-문을 바꿨을 경우 상품이 있을 확률=0/1
-1/3 * 1/2 * 0/1=0/6
따라서 참가자가 문을 무조건 바꾸는 경우에는 상품에 당첨될 확률이 2/3+0/6=2/3입니다.
2. 참가자는 문을 무조건 바꾸지 않는다.
1)처음에 꽝인 문을 선택할 확률= 2/3
-사회자는 무조건 꽝인 문을 선택해서 연다= 1/1
-문을 바꿨을 경우 자동차가 있을 확률= 0/1
-2/3 * 1/1 * 0/1=0/3
2)처음에 상품이 있는 문을 선택할 확률=1/3
(1)사회자가 꽝 인 문 중 첫번째 것을 선택할 확률=1/2
-문을 바꿨을 때 상품이 있을 확률=1/1
-1/3 * 1/2 * 1/1=1/6
(2)사회자가 꽝인 문 중 두번째 것을 선택할 확률=1/2
-문을 바꿨을 경우 상품이 있을 확률=1/1
-1/3 * 1/3 * 1/1=1/6
-1/6 + 1/6 = 1/3
따하서 참가자가 문을 무조건 바꾸지 않는 경우에 상품에 당첨될 확률은 0/3+1/3=1/3임니다.
이렇게 풀어서 쓰니까 이해가 조금 되시나요?
이제 이 문제를 C언어를 이용해 확률을 구해보도록 하겠습니다.
C언어로 구현
우선 먼저 알고리즘을 짜보도록 하죠. 알고리즘을 짜보면 다음과 같습니다.

이 알고리즘을 기반으로 코드를 짜보면
#include <stdio.h>
#include <stdlib.h>
int main()
{
int n;
int a=0;//A가 선택한 문의 번호에 대한 변수
int a_total;//A가 상품에 당첨될 횟수
int b=0;//B가 선택한 운의 번호에 대한 변수
int b_total;//B가 상품에 당첨될 횟수
printf("반복하고 싶은 횟수를 입력하세요: ");
scanf("%d",&n);//반복할 횟수 입력
for(int i=0; i<n; i++)
{
a=(rand()%3)+1;//1,2,3번 문 중에 무작위로 하나 선택
if(a==1)
a_total++;//a=1 일때 횟수 증가
else if(a==2)
a_total+=0;//a=2 일때 횟수 변경X
else if(a==3)
a_total+=0;//a=3 일때 횟수 변경X
}
for(int i=0; i<n; i++)
{
b=(rand()%3)+1;//1,2,3번 문 중에 무작위로 하나 선택
if(a==1)
a_total+=0;//a=1 일때 횟수 변경X
else if(b==2)
b_total++;//a=2 일때 횟수 증가
else if(b==3)
b_total++;//a=3 일때 횟수 증가
}
float a_result;
float b_result;
a_result=(float)a_total/(float)n;//A가 맞을 확률 계산
b_result=(float)b_total/(float)n;//B가 맞을 확률 계산
printf("a가 맞은 횟수는 %d번 이므로 a가 맞은 확률은 %.6f이다.\n",a_total,a_result);//소수점 6자리까지 확률을 출력
printf("b가 맞은 횟수는 %d번 이므로 b가 맞은 확률은 %.6f이다.\n",b_total,b_result);//소수점 6자리까지 확률을 출력
}
다음과 같은 코드를 실행시켜보면

다음과 같이 A는 1/3인 0.33333...에 근사하는 것을 알 수 있고 B는 2/3인 0.66666....에 근사하는 것을 알 수 있다.
마치는 말
오늘은 재미있는 확률 문제 중 하나인 몬티 홀 문제에 대해 C언어로 구현해 보았습니다. 다음번엔 다른 주제로 찾아오도록 하겠습니다.

'정윤탐' 카테고리의 다른 글
| 진로와 정보 (0) | 2023.07.04 |
|---|---|
| python으로 바젤문제 시각화하기 (0) | 2023.07.04 |
| C언어로 매클로린 급수 표현해보기 (0) | 2023.05.18 |
| C언어로 원주율 나타내기 (0) | 2023.05.17 |
| C언어를 이용한 소수 판별 (0) | 2023.03.30 |