Distancia esperada entre dos puntos de un cuadrado unitario
Definir, por simulación, la función
distanciaEsperada :: Int -> Double
tal que (distanciaEsperada n) es la distancia esperada entre n puntos del cuadrado unitario de vértices opuestos (0,0) y (1,1), elegidos aleatoriamente. Por ejemplo,
distanciaEsperada 10 == 0.4815946544198219 distanciaEsperada 10 == 0.5558438642543654 distanciaEsperada 100 == 0.5699663553203216 distanciaEsperada 100 == 0.5085629461572269 distanciaEsperada 1000 == 0.5376963424746385 distanciaEsperada 1000 == 0.523432374720393
Nota. El valor exacto de la distancia esperada es
(sqrt(2) + 2 + 5*log(1+sqrt(2)))/15 = 0.5214054331647207
Soluciones
import System.Random import System.IO.Unsafe -- (aleatorio a b) es un número aleatorio entre a y b. Por ejemplo, -- λ> aleatorio 0 1000 -- 681 -- λ> aleatorio 0 1000 -- 66 aleatorio :: Random t => t -> t -> t aleatorio a b = unsafePerformIO $ getStdRandom (randomR (a,b)) -- (aleatorios m n) es una lista infinita de números aleatorios entre m y -- n. Por ejemplo, -- λ> take 20 (aleatorios 2 9) -- [6,5,3,9,6,3,6,6,2,7,9,6,8,6,2,4,2,6,9,4] -- λ> take 20 (aleatorios 2 9) -- [3,7,7,5,7,7,5,8,6,4,7,2,8,8,2,8,7,6,5,5] -- λ> take 3 (aleatorios 0 1.0) -- [0.7808059324830976,0.13619706746099292,0.2348891848186122] aleatorios :: Random t => t -> t -> [t] aleatorios m n = aleatorio m n : aleatorios m n type Punto = (Double,Double) -- (puntosDelCuadrado n) es una lista de n puntos del cuadrado -- unitario de vértices opuestos (0,0) y (1,1). Por ejemplo, -- λ> puntosDelCuadrado 3 -- [(0.10932257643522625,0.7099956121231793), -- (0.16098424598126437,0.5581017987539308), -- (0.6774875277724967, 0.8870082327978139)] -- λ> puntosDelCuadrado 3 -- [(0.6344417902106956, 0.24924560438268484), -- (0.1094807024051736, 0.9341963885040684), -- (0.33330496979798485,0.18440873262644397)] puntosDelCuadrado :: Int -> [Punto] puntosDelCuadrado n = take n (zip (aleatorios 0.0 1.0) (aleatorios 0.0 1.0)) -- (distancia p1 p2) es la distancia entre los puntos p1 y p2. Por -- ejemplo, -- distancia (0,0) (3,4) == 5.0 distancia :: Punto -> Punto -> Double distancia (x1,y1) (x2,y2) = sqrt ((x1-x2)^2+(y1-y2)^2) -- (distancias ps) es la lista de las distancias entre los elementos 1º -- y 2º, 3º y 4º, ... de ps. Por ejemplo, -- distancias [(0,0),(3,4),(1,1),(7,9)] == [5.0,10.0] distancias :: [Punto] -> [Double] distancias [] = [] distancias (p1:p2:ps) = distancia p1 p2 : distancias ps -- (distanciaEsperada n) es la distancia esperada entre n puntos -- aleatorios en el cuadrado unitario. Por ejemplo, -- distanciaEsperada 10 == 0.4815946544198219 -- distanciaEsperada 10 == 0.5558438642543654 -- distanciaEsperada 100 == 0.5699663553203216 -- distanciaEsperada 100 == 0.5085629461572269 -- distanciaEsperada 1000 == 0.5376963424746385 -- distanciaEsperada 1000 == 0.523432374720393 distanciaEsperada :: Int -> Double distanciaEsperada n = sum ds / fromIntegral n where ps = puntosDelCuadrado (2*n) ds = distancias ps