¿Cuál es la probabilidad de formar un triángulo luego de romper un palillo en 3 partes? Python y R

Índice

Introducción

La semana pasada fui al restaurante a cenar por el aniversario de mis padres. Luego de comer, cogí los famosos palillos de dientes para intentar limpiar los restos de comida que quedaban entre mis dientes:

Mondadientes: una herencia peligrosa - Clínica Dental

Luego de usar este famoso invento, tengo la costumbre de partirlo, ya sea en dos, tres, cuatro, … partes:

Palillo De Dientes Roto Foto de stock y más banco de imágenes de Mondadientes - iStock

Pero esta vez, recordé una pregunta que vi en un libro de probabilidades. La pregunta es la siguiente:

Supongamos que rompemos un palillo en 3 partes ¿Cuál es la  probabilidad de formar un triángulo?

Buscando en internet, logré encontrar la respuesta. Muchos resultados usando analítica y fórmulas matemáticas muy interesantes.

En esta publicación intentaré calcularlo pero de dos maneras: de forma analítica y mediante simulación en Python y R.

Solución analítica

Partimos, por simplificar, con un palillo de longitud = 1. En este ejemplo, mi palillo no tiene puntas xD.

Luego ubicaremos dos puntos x e y de manera aleatoria, formando 3 partes: a, b, c

En esta gráfica estamos asumiendo que y\geq x. Esto lo tendremos en cuenta más adelante.

Además, podemos ver que a=x, b=y-x y c=1-y

Veamos estos casos:

  • Partimos el palillo en 3 partes, pero no forman un triangulo:

  • Partimos el palillo en 3 partes, formamos un triángulo:

Para calcular la probabilidad de formar un triángulo necesitamos calcular el siguiente cociente:

\frac{\text{casos favorables}}{\text{casos totales}}

Casos totales

Necesitamos calcular todos los posibles valores que pueden tomar x e y. Como nuestro palillo mide 1 unidad y los cortes generan longitudes aleatorias, pero positivas, los posibles valores que pueden tomar x e y están entre 0 y 1. Graficando los posibles valores:

Vemos, del gráfico que x e y pueden ser cualquier punto dentro del cuadrado. Los casos totales serán el área del cuadrado, es decir.

\text{casos totales}=1

Casos favorables

Para calcular los casos favorables, vamos a poner la condición que

y\geq x

Al final tendremos esto en cuenta esta condición.

Para que 3 lados, a, b, c formen un triángulo, deben de cumplir la condición de que cada lado debe ser menor a la suma de los otros lados. Es decir, debe cumplir estas 3 condiciones:

a<b+c

b<a+c

c<a+b

Como a=x, b=y-x y c=1-y, tenemos lo siguiente:

x<(y-x)+(1-y)

y-x<x+(1-y)

(1-y)<x+(y-x)

Reduciendo las 3 condiciones (para y\geq x):

x<\frac{1}{2}

y<\frac{1}{2}+x

\frac{1}{2}<y

Graficando los casos válidos:

La región oscura indica los casos favorables. El área de esta región es la octava parte de todo el recuadro.

Aún no hemos terminado. Si recuerdan pusimos la condición de que y\geq x, ahora queda probar en el caso que y< x.

Esto implica que a=y, b=x-y y c=1-x. Este cambio genera la siguiente región:

y<\frac{1}{2}

x<\frac{1}{2}+y

\frac{1}{2}<x

Cuya área es también la octava parte del cuadrado.

Sumando las dos regiones:

\text{casos favorables}=\frac{1}{8}(x>y) + \frac{1}{8}(y>x)=\frac{1}{4}

Por lo que la probabilidad de formar un triángulo luego de partir un palillo en 3 partes es igual a:

\frac{\text{casos favorables}}{\text{casos totales}}=\frac{1/4}{1}=\frac{1}{4}

Este valor es independiente de la longitud del palillo, si no me crees, prueba con calcularlo usando otra longitud ;).

Ahora intentaremos resolver el mismo problema mediante simulaciones usando Python y R.

Simulación en Python y R

Ahora intentaremos resolver el problema mediante simulación. Usaré los dos lenguajes de programación más usados para la ciencia de Datos:

Python

Archivo:Python-logo-notext.svg - Wikipedia, la enciclopedia libre

R

R: R Logo

Para el caso de Python necesitamos importar las siguientes librerías:

import tqdm
import random
import matplotlib.pyplot as plt
from typing import Tuple

Rompiendo el palillo

La siguiente función forma 3 lados, a, b, c a partir de un palillo de longitud configurable (esto para que puedas probar con distintos valores y comprobar que la probabilidad es la misma).

Python

def romper_palillo(longitud: float) -> Tuple[float, float, float]:
    '''
    divide un palillo en 3 partes
    '''
    x = random.uniform(a=0, b=longitud)
    y = random.uniform(a=0, b=longitud)
    
    a = min(x, y)
    b = abs(x - y)
    c = longitud - (a + b)
    
    return a, b, c

R

romper_palillo = function(longitud){
  # Divide un palillo en 3 partes
  x = runif(n = 1, min = 0, max = longitud)
  y = runif(n = 1, min = 0, max = longitud)

  a = min(x, y)
  b = abs(x - y)
  c = longitud - (a + b)

  return(list(a = a, b = b, c = c))
}

¿Es un tríangulo?

Ahora necesitamos crear una función que, a partir de 3 números: a, b, c, podemos construir un triángulo. Es decir, la función debe comprobar la siguiente condición:

a<b+c

b<a+c

c<a+b

Python

def es_triangulo(a: float, b: float, c: float) -> bool:
    '''
    Determina si los lados de un triángulo son válidos.
    '''
    return a + b > c and a + c > b and b + c > a

R

es_triangulo = function(a, b, c){
  # Determina si los lados de un triángulo son válidos.
  return(a + b > c & a + c > b & b + c > a)
}

Calculando probabilidades

Listo, ya tenemos las dos funciones importantes: partir el palillo y validar que el resultado forme un triángulo.

La siguiente función estima la probabilidad de formar un triángulo:

  • Para numero de iteraciones.
  • Partimos el palillo en 3 partes.
  • Verificamos que el resultado forme un triangulo.
    • Si forma el triángulo, es un éxito
  • Por último, estimamos la probabilidad como: el número de éxitos / número de iteraciones.

Python

def simula_probabilidad(longitud: float = 1.0, num_iter: int = 1000) -> float:
    '''
    Simula la probabilidad de que un palillo se rompa en 3 partes.
    '''
    num_triangulos_formados = 0
    for _ in range(num_iter):
        a, b, c = romper_palillo(longitud)
        if es_triangulo(a, b, c):
            num_triangulos_formados += 1
    return num_triangulos_formados / num_iter

R

simula_probabilidad = function(longitud = 1.0, num_iter = 1000){
  # Simula la probabilidad de que un palillo se rompa en 3 partes
  num_triangulos_formados = 0
  for (i in seq(1, num_iter)){
    lados = romper_palillo(longitud)
    a = lados$a
    b = lados$b
    c = lados$c

    if (es_triangulo(a, b, c)){
      num_triangulos_formados = num_triangulos_formados + 1
    }
  }
  return(num_triangulos_formados / num_iter)
}

Veamos a continuación cómo converge nuestras probabilidades a medida que aumentamos el número de iteraciones.

El script es el siguiente (Python):

iteraciones = range(1, 10000)
probabilidades = [simula_probabilidad(num_iter=i) for i in tqdm.tqdm(iteraciones)]

plt.plot(iteraciones, probabilidades)
plt.axhline(y=0.25, color='r', linestyle='-')

El eje x indica el número de iteraciones, y el eje y la probabilidad estimada con ese número de iteraciones:

Del gráfico podemos ver que, a medida que aumentamos el número de iteraciones, la probabilidad se acerca a 0.25, que es justo la probabilidad que calculamos de manera analítica.

Conclusión

En esta publicación hemos resuelto el problema de calcular la probabilidad de formar un triángulo a partir de partir un palillo en 3 partes.

Lo hemos resuelto de manera analítica y simulando en Python y R

Los códigos que he usado lo pueden encontrar el en siguiente enlace:

https://github.com/Jazielinho/probabilidad_triangulo

Cualquier comentario es bienvenido 🙂

close

¡No te pierdas mis últimas publicaciones!

¡No te enviaré spam!

Una respuesta a «¿Cuál es la probabilidad de formar un triángulo luego de romper un palillo en 3 partes? Python y R»

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *