tipos sorteos que programacion para números numeros numero método metodos generar generadores generador generación biblioteca app algoritmo aleatorios aleatorio algorithm random psychology

algorithm - sorteos - ¿Hay algoritmos para generar números psicológicamente aleatorios?



que es un numero aleatorio en programacion (5)

El código RNG a continuación (escrito en c #) genera algunos números muy aleatorios:

public class Randomizer { /// <summary> /// An array of unsigned integers containing 100 pre-rolled randomly generated numbers. /// </summary> private uint[] randBuf = new uint[100]; /// <summary> /// The index of the last read number out of the <see cref="Atlana.Random.Randomizer.randBuf">randBuf</see> array. /// </summary> private uint index = 0; /// <summary> /// Original value of the seed used to initialize the number array. /// </summary> private uint origSeed; /// <summary> /// Initializes a new instance of the Randomizer class. Uses <paramref name="seed">seed</paramref> to initialize the number array. /// </summary> /// <param name="seed">Integer value used to seed the number array.</param> public Randomizer(int seed) { this.origSeed = (uint)seed; this.Initialize((uint)seed); } /// <summary> /// Invokes the randomizer to refresh the list of random values. /// </summary> public void ReRoll() { this.Roll(); } /// <summary> /// Generates a random unsigned integer number value between the specified range of <paramref name="min">min</paramref> and <paramref name="max">max</paramref>. /// </summary> /// <param name="min">An unsigned integer representing the minimum value of the return value.</param> /// <param name="max">An unsigned integer representing the maximum value of the return value.</param> /// <returns>An unsigned integer containing a number between <paramref name="min">min</paramref> and <paramref name="max">max</paramref>.</returns> public uint Range(uint min, uint max) { uint y = this.Random(); if (y < min) { y = y * min; } if (y > max) { y = y % (max + 1); } return y; } /// <summary> /// Generates a random integer number value between the specified range of <paramref name="min">min</paramref> and <paramref name="max">max</paramref>. /// </summary> /// <param name="min">An integer representing the minimum value of the return value.</param> /// <param name="max">An integer representing the maximum value of the return value.</param> /// <returns>An integer containing a number between <paramref name="min">min</paramref> and <paramref name="max">max</paramref>.</returns> public int Range(int min, int max) { return Convert.ToInt32(this.Range(Convert.ToUInt32(min), Convert.ToUInt32(max))); } /// <summary> /// Generates a random number between 0 and 100. /// </summary> /// <returns>A randomly generated integer value between 0 and 100.</returns> public int Percent() { return this.Range(0, 100); } /// <summary> /// Retrieves a value from the random number array. /// </summary> /// <returns>A randomly generated unsigned integer</returns> private uint Random() { if (this.index == 0) { this.Roll(); } uint y = this.randBuf[this.index]; y = y ^ (y >> 11); y = y ^ ((y << 7) + 3794); y = y ^ ((y << 15) + 815); y = y ^ (y >> 18); this.index = (this.index + 1) % 100; return y; } /// <summary> /// Initializes the number array from a seed provided by <paramref name="seed">seed</paramref>. /// </summary> /// <param name="seed">Unsigned integer value used to seed the number array.</param> private void Initialize(uint seed) { this.randBuf[0] = seed; for (uint i = 1; i < 100; i++) { this.randBuf[i] = (uint)(this.randBuf[i - 1] >> 1) + i; } } /// <summary> /// Checks to prevent <see cref="System.ArithmeticException">ArithmeticException</see>. /// </summary> private void OverflowCheck() { foreach (uint u in this.randBuf) { if (u > (uint.MaxValue / 3794)) { this.Initialize(this.origSeed + this.index); break; } } } /// <summary> /// Refreshes the list of values in the random number array. /// </summary> private void Roll() { this.OverflowCheck(); for (uint i = 0; i < 99; i++) { uint y = this.randBuf[i + 1] * 3794U; this.randBuf[i] = (((y >> 10) + this.randBuf[i]) ^ this.randBuf[(i + 399) % 100]) + i; if ((this.randBuf[i] % 2) == 1) { this.randBuf[i] = (this.randBuf[i + 1] << 21) ^ (this.randBuf[i + 1] * (this.randBuf[i + 1] & 30)); } } } }

Aquí hay un ejemplo de una serie de números entre 0-50 usando la clase anterior:

7 2 6 4 17 1 48 18 46 14 44 32 37 12 48 12 14 47 15 10 5 12 15 9 9 15 27 47 5 5 2 16 20 48 50 22 31 39 40 20 41 27 35 50 46 21 8 34 24 6

Los números aleatorios verdaderos a menudo no parecen aleatorios para la persona promedio, ya que las secuencias generadas al azar se interpretarán como estructura. ¿Hay algún algoritmo que genere un conjunto de números psicológicamente "parecidos" al azar, aunque no lo sean?


Hay dos requisitos en su pregunta.

  1. Psicológicamente parece aleatorio
  2. No realmente al azar

Necesita definir ambos requisitos mucho mejor. Propongo que definamos los requisitos de esta manera:

  1. Un usuario siempre podrá encontrar secuencias en un conjunto de números aleatorios si el conjunto es lo suficientemente largo. Incluso se puede demostrar matemáticamente que puede encontrar cualquier subsecuencia de números en una secuencia de datos aleatoria. Por lo tanto, un usuario casi seguramente encontrará una subsecuencia aleatoria.
  2. Sin embargo, no desea que la transmisión sea realmente aleatoria. Esto significa que quiere que la computadora pueda predecir el próximo número.

Propongo el siguiente algoritmo:

NEXT = RandomStartingNumber X = empty list loop { NEXT = HASH(NEXT) add NEXT to X }

Esto haría que los datos parezcan aleatorios, mientras que la computadora puede calcularlos con bastante facilidad.


Lo primero que debes considerar es cómo estás usando los números. Al mover un montón de monedas se obtiene una buena división de 50/50, donde lanzar dos o tres monedas puede ocasionarte 3 cabezas o colas molestas y no aparentes la mayor parte del tiempo. Lanzar muchos dados en busca de unos dará resultados muy desiguales, a veces sin ninguno y en algún momento con la mitad de los dados. Rodar muchos dados más ayudará aquí. Generalmente, cuantos más números generes, las personas más felices estarán con ellos.

Si solo estás generando algunos números, comenzaría con los verdaderamente aleatorios, veré qué te molesta y solucionarlo. Una cosa simple de hacer es reducir las probabilidades de que surja un número basado en la frecuencia con que ha aparecido antes. O incluso más simplemente, no devuelva el mismo número dos veces. Pero a menudo hay sutilezas. Si devuelve los números del 1 al 10, pero 1-4 cuentan de una forma y 5-10 la otra, una secuencia de 123451234512345 será muy molesta (80% baja, 20% alta). Si los rangos son 1-2 y 3-10, no sería (obtendrá el 40% esperado bajo, 60% alto). Peor aún, si tienes tiradas competitivas, son los resultados relativos los que importan. Los números de cada dado pueden parecer, por sí solos, aleatorios, pero si, 9 de cada 10 veces, un dado rueda más alto que el otro, los dados parecerán cargados.

Hay mucho más como esto. Si alguien está jugando un juego donde tiran un dado para ver cuánto se mueven, y luego ruedan para ver cuánto dinero obtienen, un conjunto de tiradas que serían psicológicamente aleatorias por sí mismas no le pueden dar a nadie movimientos ni toneladas de dinero, o viceversa, y parece seriamente amañado.

Así que generaría un número aleatorio, o un conjunto de números, y luego los rechazaría si no se ven lo suficientemente aleatorios en ese caso particular. (Es posible que desee rechazarlo un porcentaje del tiempo, o puede dejar de lado la aleatoriedad por completo.) (Si es inteligente, puede ajustar las probabilidades con anticipación y sobre la marcha para minimizar el número de regeneraciones que tiene hacer). Realmente no hay una solución general a este problema.

En realidad , puedo pensar en dos soluciones generales. Una es: simplemente no use números aleatorios. El otro es generar grandes cantidades de ellos y no dejar que nadie mire los detalles de la secuencia. Si tienes un juego con 5000 soldados en cada lado disparándose unos a otros con un 10% de probabilidad de golpear, el efecto general (486 hacia abajo en un lado y 512 hacia abajo en el otro) será psicológicamente aleatorio. Simplemente no permita que nadie mire los resultados de, digamos, 10 disparos individuales. ("¡Tuve 30 disparos y ni un solo golpe!" "¡Tenía 3 golpes en 5 tiros!")

Además: escribí lo anterior, luego me di cuenta de que podría haber un problema ético aquí. Si está generando un mapa aleatorio o haciendo muchas otras cosas, manipular los resultados de la generación de números aleatorios puede ser una muy buena idea. Sin embargo, un jugador en un juego puede tener derecho a un número aleatorio real. Si tienes un juego de póquer, y un trato real aleatorio le da a un jugador una escalera real, tu programa no tiene nada que decidir que eso sea demasiado extremo y que se vuelva a cerrar. Un jugador de un juego de guerra que decida realizar un ataque con una supuesta probabilidad de éxito de 50-50 no debe ser ignorado por el hecho de que, debido a que anteriormente ha ganado 3 concursos de 50-50 seguidos, sus probabilidades reales ahora son de solo 20-80. . El aspecto ético aquí probablemente podría llenar un libro que no tengo tiempo para escribir, pero sé muy consciente de ello.


Imposible

No existe una serie que, psicológicamente, parezca aleatoria para todos, pero no lo es.

Sabemos del experimento, cuando se les dice a las personas que escriban una serie de resultados de monedas o dados que se vean al azar. A menudo tienden a evitar series, pero ¿por qué lo hacen? ¿No tienen suficiente tiempo, instrumentos y conocimiento estadístico para producir mejores resultados? Al menos, si tomas suficientes estudiantes absueltos en educación matemática de la escuela secundaria, deberían ser capaces de detectar series mal inventadas, con suficiente tiempo y series lo suficientemente largas.

Pero incluso sin eso, una persona mal educada puede detectar una serie mal inventada por un diseño de generador roto.

Piensa en un dado, donde siempre barajas 6 números (2, 6, 1, 4, 3, 5) y los recoges en ese orden, antes de barajar de nuevo (6, 3, 2, 4, 1, 5) y elegir el próximo 6.

Este enfoque nunca llevaría a 3 números idénticos en serie, pero en algunos juegos podría ser muy útil tener, por ejemplo, 3x6 en una fila y, por supuesto, con el tiempo, será evidente que nunca sucede, solo usted solía jugar este juego, y sabes, que normalmente ocurre 2-3 veces por hora.

Otro caso en el que muy temprano será obvio es la ruleta, donde la gente, que cree en sus sistemas defectuosos, comenzará a ganar y romperá el banco muy temprano. Tales sistemas a menudo se basan en una suposición como "si tienes una serie larga de negro, apostar en blanco, porque tiene que suceder, cuanto más, más larga es la serie negra". Si juega con tales expectativas, y el generador satisface sus ideas, será muy obvio para el ganador, el banco y los observadores inteligentes, lo que está sucediendo.

Conclusión:

La detección de un RNG defectuoso depende de su conocimiento, de la duración de la serie y del esfuerzo que puede gastar en el problema, lo que podría aumentar si puede ganar o perder mucho dinero de esa manera.

No hay expectativas comunes, independientemente del conocimiento de la audiencia. Incluso si los números del 1 al 6 debieran - a la larga - aparecer con la misma frecuencia, deben ser conocidos, eso no es conocido por la intuición.

A partir de series cortas, nadie puede detectar si es defectuoso o no. A partir de series más largas, un RNG roto será detectable.

tl; dr

La idea de un RNG quebrantado intencionalmente, para ajustarla a un prejuicio mal educado, es defectuosa. Si necesita algo como un mezclador de música sin una repetición demasiado temprana, busque un nombre mejor para esa cosa.


Aquí hay un algoritmo:

  1. Use cualquier generador de números pseudoaleatorio para crear una secuencia de números que no sean aleatorios (porque están predeterminados por la semilla y el algoritmo).

  2. Utilice una serie de pruebas estadísticas de la batería Diehard (fuente) para descalificar las subsecuencias que se consideran subjetiva e históricamente sesgadas.

El resultado sería "números que psicológicamente" parecen "aleatorios, aunque no lo sean" .

Además, existen modelos cognitivos del juicio de aleatoriedad humana. Uno de esos modelos (de secuencias binarias) se basa en la complejidad de Kolmogorov, pero no le dará un algoritmo porque la complejidad de Kolmogorov no es computable. Sin embargo, podría darle más ideas para encontrar "números psicológicamente aleatorios" .

Abstracto

Presentamos una cuenta estadística de juicios de aleatoriedad humana que utiliza la idea de la complejidad algorítmica. Mostramos que una medida existente de la aleatoriedad de una secuencia corresponde a la suposición de que las secuencias no aleatorias son generadas por un autómata de estado finito probabilístico en particular, y lo utilizan como base para una cuenta que evalúa la aleatoriedad en términos de la duración de los programas para máquinas en diferentes niveles de la jerarquía de Chomsky. Este enfoque da como resultado un modelo que predice mejor los juicios humanos que las respuestas de otros participantes en el mismo experimento.

Griffiths, TL, y Tenenbaum, JB (2003). Probabilidad, complejidad algorítmica y aleatoriedad subjetiva. En R. Alterman y D. Kirsh (Eds.), Actas de la 25 ª Conferencia Anual de la Sociedad de Ciencias Cognitivas (pp. 480-485). Mahwah, NJ: Erlbaum. [PDF]