[Python-es] ¿Cómo generar una distribución aleatoria?

Daπid davidmenhur en gmail.com
Mie Jul 3 14:58:54 EDT 2019


Distribución plana es sólo uno de los requisitos de randint. Otro es que
los valores sucesivos sean independientes.

La solución de Mario tiene este problema:

import numpy as np
import pylab as plt

results = []
k, seed = randint_1_7()
for n in range(100000):
    k, seed = randint_1_7(seed)
    results.append(k)

results = np.array(results)
plt.hist2d(results[::2], results[1::2], bins=(np.arange(1, 8)-0.5,
np.arange(1,8)-0.5))
plt.colorbar()
plt.scatter(results[::2], results[1::2], color='w')
plt.tight_layout()
[image: hist_randint.png]

Como puedes ver, nunca tienes dos números iguales seguidos, y nunca tienes
un número seguido del anterior.

El mismo proceso en tres dimensiones revela más agujeros.

La solución de Lasizoillo parece no tener este problema.


Detalle importante: este es un test muy básico de independencia, que lo
pase no quiere decir que sea independiente...

/David.

On Wed, 3 Jul 2019 at 18:07, Mario R. Osorio <nimbiotics en gmail.com> wrote:

> Muy interesante la solución de Javi (Que demuestra tener una distribución
> plana), sin embargo me permito presentar la mía para su consideración:
>
> """
>  Solucion para:
>     generar una distribución plana de enteros aleatorios, del 1 al 7,
> usando únicamente random.randint(1,5)
>     como funcion generadora de enteros aleatorios
> """
>
> from random import randint
>
> def randint_1_7(seed=None):
>     l = (1, 2, 3, 4, 5, 6, 7)
>
>     if seed is None:
>         seed = randint(1,5) + randint(1,5)
>     else:
>         seed += randint(1,5)
>
>     seed = seed % 7
>
>     return (l[seed - 1], seed)
>
>
> if __name__ == "__main__":
>     """
>     se demuestra que la distribucion es plana,
>     pero la PRUEBA matematica se la dejo a otro...
>
>     """
>
>     d = {}
>     k, seed = randint_1_7()
>
>     for n in range(100000):
>         k, seed = randint_1_7(seed)
>         if k in d:
>             d[k] += 1
>         else:
>             d[k] = 1
>
>     print(d)
>
>
>
>
> On Tue, Jul 2, 2019 at 10:10 PM lasizoillo <lasizoillo en gmail.com> wrote:
>
>> Buenas,
>>
>> Lo primero sería acotar cual es realmente el problema. En una entrevista
>> de trabajo alguien tiene que desentrañar si eres apto o no para un puesto y
>> esa aptitud puede tener varias facetas:
>> - Eres capaz de poner en duda los requisitos y plantear alternativas
>> mejores para la empresa
>> - Eres capaz de resolver problemas lógicos
>> - Ante un problema que muy posiblemente no sabes por dónde cogerlo...
>> ¿cómo vas a reaccionar? te enfadarás, tratarás de colar una solución
>> erronea, asumirás que no sabes hacer eso pero plantearás estrategias para
>> atacar el problema, ...
>>
>> Así que lo primero negociaría si realmente no se puede simplificar el
>> enunciado porque lo que realmente se quiere evaluar el conocimiento técnico
>> o recursos para atacar este problema. Si les vale ser capaz de poner en
>> duda requisitos peregrinos eso que me ahorraría. Si quiere una solución
>> técnica pasaría a atacar el problema, reconociendo que no sé la solución a
>> priori, y pensaría en voz alta algunas cosas evidentes:
>> - Una sola llamada a la función randint(1,5) no tiene información
>> suficiente para hacer el equivalente a randint(1,7)
>> - No puedo sumar 7 "tiradas" de randint(1,5) y dividir entre 5 porque la
>> distribución no sería plana.
>> - Al no ser una potencia de dos no puedo convertir a binario la función
>> randint(1,5) y codificar los bits del número. Ejemplo 1 y 3 es un 0, 2 y 4
>> es un 1 y 5 vuelvo a calcular. 2^3=8, por lo que tres bits de tiradas
>> binarias me darían números del 0 al 7, no del 1 al 7.
>>
>> Ahora diría en alto lo que me parece una solución válida que me ha venido
>> a la cabeza: lo mismo que con la función randint(1,5) desechaba cuando
>> salía 5 para simular tiradas de cara o cruz, puedo eliminar cuando el
>> resultado de calcular 3 bits me da un número que equivale a 0. Pensaría si
>> cumple con las restricciones del enunciado (creo que si) y pasaría a una
>> implementación rápida.
>>
>> def rand_0_1() -> int:
>>      while True:
>>           num = randint(1, 5)
>>           if num==5:
>>               continue
>>           return num % 2
>>
>> def randint_1_7() -> int:
>>      while True:
>>           num = rand_0_1() * 4 + rand_0_1() * 2 + rand_0_1()
>>           if num:
>>              return num
>>
>> Le comentaría que lo suyo sería hacer una función de test para quedarme
>> tranquilo con que el resultado es correcto y poder refactorizar en el
>> futuro si se me ocurre una solución mejor. Escucharía si quiere dejarlo
>> aquí o si quiere ver la función que haga el test (que no es trivial, pero
>> tampoco demasiado complicada). Pero la función de test ya se escapa a tu
>> propuesta ;-)
>>
>> Un saludo,
>>
>> Javi
>>
>>
>> El mié., 3 jul. 2019 a las 1:50, Jose Caballero (<
>> jcaballero.hep en gmail.com>) escribió:
>>
>>> Hola,
>>>
>>> a un colega le han preguntado durante una entrevista de trabajo lo
>>> siguiente:
>>> ¿cómo generar una distribución plana de enteros aleatorios, del 1 al 7,
>>> usando únicamente random.randint(1,5)?
>>> O sea, sin usar ninguna otra función que genere números aleatorios.
>>>
>>> Y he pensado en proponer el reto aquí, a ver lo que los miembros de la
>>> lista sugieren.
>>>
>>> Un saludo,
>>> Jose
>>> _______________________________________________
>>> Python-es mailing list
>>> Python-es en python.org
>>> https://mail.python.org/mailman/listinfo/python-es
>>>
>> _______________________________________________
>> Python-es mailing list
>> Python-es en python.org
>> https://mail.python.org/mailman/listinfo/python-es
>>
> _______________________________________________
> Python-es mailing list
> Python-es en python.org
> https://mail.python.org/mailman/listinfo/python-es
>
------------ próxima parte ------------
Se ha borrado un adjunto en formato HTML...
URL: <http://mail.python.org/pipermail/python-es/attachments/20190703/f093c770/attachment.html>
------------ próxima parte ------------
A non-text attachment was scrubbed...
Name: hist_randint.png
Type: image/png
Size: 13680 bytes
Desc: no disponible
URL: <http://mail.python.org/pipermail/python-es/attachments/20190703/f093c770/attachment.png>


Más información sobre la lista de distribución Python-es