I'm practicing my R coding today and am working on the problem where you have a stick with length=1 and break it into 3 pieces. We need to figure out what the probability is that those 3 broken pieces will form a triangle. I've found some proper code online for this problem, but they are slightly beyond my understanding.
Why won't this code work? Could you tell me how to fix it? TIA!
set.seed(12345)
breaks <- sort(runif(n=2))
stick_lengths <- c(breaks[1], breaks[2]-breaks[1], 1-breaks[2])
stick_lengths
repetitions <- 10000
tri <- c(1:10000)
trialstotri <- 0
for(i in 1:repetitions){
break1 <- 0
trials <- 0
while(breaks[1] (breaks[2]-breaks[1])> 1-breaks[2] TRUE){
breaks <- sample(tri, size=1, replace=TRUE)
trialstotri <- trialstotri 1 }
print(proportions(TRUE))
}
CodePudding user response:
Here's a structure that I think will work, and I'll leave some details for you to fill in.
repetitions <- 10000
trials <- logical(length = repetitions)
set.seed(12345)
for(i in 1:repetitions) {
# break a stick randomly
breaks <- sort(runif(n=2))
stick_lengths <- c(breaks[1], breaks[2]-breaks[1], 1-breaks[2])
# see if it works as a triangle
if(
(stick_lengths[1] stick_lengths[2] > stick_lengths[3])
&
() & () ## fill in additional conditions! One is not enough!
) {
trials[i] <- TRUE
} else {
trials[i] <- FALSE
}
}
mean(trials)
CodePudding user response:
Gregor Thomas has a nice didactic answer which should help you follow the logic. It is possible to do the whole thing in a single line though:
mean(replicate(10000, !any(diff(c(0, sort(runif(2)), 1)) > 0.5)))
#> 0.252
Explanation
The way this works is by creating a length-4 vector consisting of: 0 (representing the start of the stick), then two ordered random numbers (representing the breaks), then 1 (representing the end of the stick).
c(0, sort(runif(2)), 1)
The diff
of this vector gives us three "pieces" whose lengths add up to 1. So our stick lengths can be created with:
diff(c(0, sort(runif(2)), 1))
Logically, the only way one cannot make a triangle is if the combined length of two of the pieces is less than the length of the other piece. This can only happen when one of the pieces is longer than 0.5.
We can find out if any of our pieces is longer than 0.5 by doing
any(diff(c(0, sort(runif(2)), 1)) > 0.5)
However, this returns TRUE
if we cannot make a triangle and FALSE
if we can, so we want to negate it with the !
operator.
!any(diff(c(0, sort(runif(2)), 1)) > 0.5)
This gives us a single run of the experiment. To get it to run 10,000 times to return a vector of TRUE and FALSE we can use replicate
:
replicate(10000, !any(diff(c(0, sort(runif(2)), 1)) > 0.5))
The quickest way to get the proportion of TRUE
in this vector is to take its mean. This works by implicitly converting the TRUE values to 1 and FALSE values to 0.
Therefore, we get our final result of 10,000 runs of the experiment with the single line:
mean(replicate(10000, !any(diff(c(0, sort(runif(2)), 1)) > 0.5)))