C언어로 몬티 홀 문제 확률 구현하기

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