징검다리 문제 III.

강화유리와 유리를 구분할 수 있는 유리 장인이 있다.

이 유리장인은 80퍼센트의 확률로 강화유리를 고른다.

총 10명의 참가자가 있고 이 참가자들은 (유리,강화유리)의 조합으로 이루어진 징검다리를 5번연속으로 건너야 한다.

아래의 경우에 참가자들은 평균적으로 몇명이 살아남겠는가?

(1) 일반인1 - 일반인2 - .... - 일반인9 - 유리장인 || (강화유리, 유리)

(2) 유리장인 - 일반인1 - 일반인2 - ... - 일반인9 || (강화유리, 유리)

1000번 시뮬레이션을 하여 결과를 추정하라.

(단, 일반인은 50%의 확률로 강화유리를 고를수 있다고 하자)


[예시] (1)의 시뮬레이션 결과가 아래와 같다고 하자.

  • 첫번째 징검다리: 유리장인이 강화유리 선택
  • 두번째 징검다리: 유리장인이 강화유리 선택
  • 세번째 징검다리: 유리장인이 일반유리 선택 $\to$ 유리장인 탈락 & 일반인9는 당연히 강화유리를 선택
  • 네번째 징검다리: 일반인9가 일반유리 선택 $\to$ 일반인9 탈락 & 일반인8은 당연히 강화유리 선택
  • 다섯번째 징검다리: 일반인8이 강화유리 선택

이 경우는 일반인8,일반인7, $\dots$, 일반인1이 살아남으므로 8명이 살아남는다.

[예시] (2)의 시뮬레이션 결과가 아래와 같다고 하자.

  • 첫번째 징검다리: 일반인9 일반유리 선택 $\to$ 일반인9 탈락 & 일반인8은 강화유리 선택
  • 두번째 징검다리: 일반인8 일반유리 선택 $\to$ 일반인8 탈락 & 일반인7은 강화유리 선택
  • 세번째 징검다리: 일반인7 일반유리 선택 $\to$ 일반인7 탈락 & 일반인6은 강화유리 선택
  • 네번째 징검다리: 일반인6 일반유리 선택 $\to$ 일반인6 탈락 & 일반인5는 강화유리 선택
  • 다섯번째 징검다리: 일반인5 일반유리 선택 $\to$ 일반인5 탈락 & 일반인4는 강화유리 선택

이 경우는 일반인4,일반인3,일반인2,일반인1,유리장인 이 살아남는다. (따라서 5명)

- 즉 살아남을수 있는 최대인원수는 10명이며 최소인원수는 5명이다.

- 유리장인이 100%의 확률로 강화유리를 구분한다면 (1)의 경우 항상 10명이 살아남는다. (즉 평균도 10명)

풀이2

(1) 일반인1 - 일반인2 - .... - 일반인9 - 유리장인 || (강화유리, 유리)

총 살아남은 사람의 수 = 5 + 5번의 기회 중에서 일반인의 성공횟수

library(tidyverse)
Warning message:
“package ‘tidyverse’ was built under R version 4.0.3”
── Attaching packages ─────────────────────────────────────── tidyverse 1.3.1 ──

 ggplot2 3.3.5      purrr   0.3.4
 tibble  3.1.6      dplyr   1.0.7
 tidyr   1.1.4      stringr 1.4.0
 readr   2.1.1      forcats 0.5.1

Warning message:
“package ‘ggplot2’ was built under R version 4.0.5”
Warning message:
“package ‘tibble’ was built under R version 4.0.5”
Warning message:
“package ‘tidyr’ was built under R version 4.0.5”
Warning message:
“package ‘readr’ was built under R version 4.0.5”
Warning message:
“package ‘purrr’ was built under R version 4.0.3”
Warning message:
“package ‘dplyr’ was built under R version 4.0.5”
Warning message:
“package ‘stringr’ was built under R version 4.0.5”
Warning message:
“package ‘forcats’ was built under R version 4.0.3”
── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
 dplyr::filter() masks stats::filter()
 dplyr::lag()    masks stats::lag()

y = rbinom(1, size=5, 0.5)
y
[1] 4

- 살아남은 사람수는 ?

print(5+y)
[1] 6

- 정리하면

rslt <- c()
for (i in 1:10000) {
    y = rbinom(1, size = 5, 0.5)
    rslt[i]=5+y
}
rslt1 = mean(rslt)
rslt1
[1] 7.4965

(2) 유리장인 - 일반인1 - 일반인2 - ... - 일반인9 || (강화유리, 유리)

총 살아남은 사람의 수 = 5 + 장인의 성공횟수 + (5-장인의성공횟수-1)의 기회중에서 일반인의 성공횟수

  • 단 (5-장인의성공횟수-1)=<0 이면 마지막항은 0으로 계산한다.
rslt <- c()
for (i in 1:10000){
    x=sum(cumprod(rbinom(5,size=1,0.8)))
    xx_=5-x-1 
    if (xx_>0) y = rbinom(1, size=xx_, 0.5) else y=0 
    rslt[i]=5+x+y
}
rslt2 = mean(rslt) 
rslt2
[1] 8.5053
print(c(rslt1, rslt2))
[1] 7.4965 8.5053

풀이3

(1) 일반인1 - 일반인2 - .... - 일반인9 - 유리장인 || (강화유리, 유리)

rm(list=ls())
SIMULATE1 = function(){
### 변수들의 모음
ARR = c('A','N1','N2','N3','N4','N5','N6','N7','N8','N9')
SURV = 10 
PLAYER = ARR[SURV]
STAGE = 0 
TOSSRSLT = NA

### Subfunction들의 모음 
toss = function(p) rbinom(n=1,size=1,prob=p) %>% as.logical
reset = function(){
    TOSSRSLT <<- NA
    SURV <<- 10
    STAGE <<- 0 
    PLAYER <<- ARR[SURV]
}
record = function(){
    list(PRE_TOSSRSLT=TOSSRSLT, SURV=SURV, STAGE=STAGE, PLAYER=PLAYER) 
}
go = function(){
    PROB <<- 0.5+ (PLAYER=='A')*0.3
    TOSSRSLT <<- toss(PROB) 
    if (TOSSRSLT==FALSE) SURV <<- SURV - 1 
    STAGE <<- STAGE + 1 
    PLAYER <<- ARR[SURV]    
}
gogo = function() for(i in 1:5) go()

gogo_history = function(){
    rslt_ = as_tibble(record()) ## go를 시작하기전의 결과가 티블로 만들어짐 
    for(i in 1:5){
        go()
        rslt_ = rbind(rslt_, as_tibble(record())) 
    }
    print(rslt_)
}

simulate_once = function(){
    reset()
    gogo()
    return(record()$SURV )
}

### BODY
simrslt = c() 
for (i in 1:100000) simrslt[i] = simulate_once() 
mean(simrslt)
}
rslt1 = SIMULATE1()
rslt1
[1] 7.50565

(2) 유리장인 - 일반인1 - 일반인2 - ... - 일반인9 || (강화유리, 유리)

SIMULATE2 = function(){
### 변수들의 모음
ARR = c('N1','N2','N3','N4','N5','N6','N7','N8','N9','A')
SURV = 10 
PLAYER = ARR[SURV]
STAGE = 0 
TOSSRSLT = NA

### Subfunction들의 모음 
toss = function(p) rbinom(n=1,size=1,prob=p) %>% as.logical
reset = function(){
    TOSSRSLT <<- NA
    SURV <<- 10
    STAGE <<- 0 
    PLAYER <<- ARR[SURV]
}
record = function(){
    list(PRE_TOSSRSLT=TOSSRSLT, SURV=SURV, STAGE=STAGE, PLAYER=PLAYER) 
}
go = function(){
    PROB <<- 0.5+ (PLAYER=='A')*0.3
    TOSSRSLT <<- toss(PROB) 
    if (TOSSRSLT==FALSE) SURV <<- SURV - 1 
    STAGE <<- STAGE + 1 
    PLAYER <<- ARR[SURV]    
}
gogo = function() for(i in 1:5) go()

gogo_history = function(){
    rslt_ = as_tibble(record()) ## go를 시작하기전의 결과가 티블로 만들어짐 
    for(i in 1:5){
        go()
        rslt_ = rbind(rslt_, as_tibble(record())) 
    }
    print(rslt_)
}

simulate_once = function(){
    reset()
    gogo()
    return(record()$SURV )
}

### BODY
simrslt = c() 
for (i in 1:100000) simrslt[i] = simulate_once() 
mean(simrslt)
}
rslt2 = SIMULATE2()
rslt2
[1] 8.50364
print(c(rslt1, rslt2))
[1] 7.50565 8.50364