Formas de especificar la generación aleatoria en desafíos

16

Nota : Según el consenso sobre Meta , preguntas de están en el tema aquí.

A la luz de esta "cosa que debe evitarse al escribir desafíos" , comencé a pensar en los desafíos que implican la generación aleatoria de ciertos tipos de objetos.

A veces sucede que quiero publicar un desafío de que implica generar aleatoriamente un foo, donde

  1. es muy fácil verificar si una cosa determinada es un tonto, y
  2. es un poco más difícil generar rápidamente un foo aleatorio de "buena calidad".

Como ejemplo, un foo podría ser una matriz binaria donde no hay segmentos de 4 bits iguales en ninguna dirección. Es fácil verificar si una matriz binaria dada es un foo, pero generar un foo aleatorio con una distribución bien distribuida parece requerir un algoritmo de retroceso o algo similar.

De todos modos, ahora tendré que especificar objetivamente qué califica como un foo aleatorio, y me gustaría que sea "impredecible" en el sentido intuitivo de que cuando ejecuto el programa varias veces, los resultados siempre se ven diferentes. El enfoque más restrictivo es exigir que la salida sea uniformemente aleatoria: todos los foos válidos tienen la misma probabilidad de ser generados. Esto suele ser demasiado restrictivo, porque no tengo idea de cómo hacerlo, salvo para generar todos los foos válidos, eliminar duplicados y elegir uno, lo cual es aburrido y lento.

Mi siguiente idea es exigir que todos los foos válidos tengan una probabilidad positiva de ser generados. Sin embargo, esto significa que el siguiente enfoque es válido: generar una cosa aleatoria similar a un foo (en nuestro ejemplo, una matriz binaria aleatoria), si es un foo, devuélvala; de lo contrario, devuelva un foo codificado (por ejemplo, la matriz de identidad ) Esto también es algo aburrido, ya que básicamente es solo un reconocedor de foos agregado a un generador de matriz aleatorio.

¿Podría haber una buena definición general para un foo impredecible al azar?

TL; DR

¿Hay una buena manera de especificar un objeto "impredecible" generado aleatoriamente que no arregle la distribución pero desaliente la codificación rígida?

Zgarb
fuente
Tenemos una definición estándar de aleatorio en meta que prohibiría la codificación rígida, pero no la restringiría en la medida en que sea perfectamente uniforme.
Geobits
55
Gran pregunta En el pasado descubrí que especificar la aleatoriedad es difícil . Especialmente para el escenario que describe, también existe el problema de que puede generar candidatos aleatorios y rehacer si no son válidos. Eso incluso te da una distribución uniforme, pero un tiempo de ejecución no determinista. Al especificar una distribución uniforme, también existe el problema de que las soluciones reales nunca son perfectamente uniformes. Este es un tema muy sutil. +1
Martin Ender
@MartinEnder Correcto, olvidé ese enfoque. Puedo rechazarlo y el otro algoritmo lento con límites de tiempo, pero aún permiten la solución "un codificador rígido".
Zgarb
parece que podría especificar K3 / K4 CPRNG, la mayoría de los idiomas tendrán una biblioteca en.wikipedia.org/wiki/Pseudorandom_number_generator
Ewan
1
@Zgarb, un gran problema al no permitir "Generar y rehacer" es que la mayoría de las bibliotecas RNG del lenguaje hacen exactamente eso.
Nathan Merrill

Respuestas:

5

Devuelve mil foos diferentes

Esto hace que sea imposible devolver valores codificados y tener un golf medio decente. Sin embargo, un generador de foo legítimo tiene una pequeña posibilidad de generar foos duplicados a menos que realmente los esté verificando. Para eliminar la carga de la verificación, una tasa de falla comprobada empíricamente, digamos 10%, podría especificarse como aceptable.

Tenga en cuenta la paradoja del cumpleaños , que la probabilidad de duplicados puede ser mayor de lo que piensa. Si solo hay un millón de posibles foos, mil foos aleatorios tendrán una probabilidad de aproximadamente 0.6 de que haya un duplicado allí en alguna parte, y eso supone que la generación de foos es completamente uniforme. Si esto pudiera ser un problema, requiere decir 900 foos únicos por cada 1000 generados, lo cual es mucho más generoso para un generador de foo genuino pero aún no es práctico para la codificación rígida.

Esto también te permite generar repetidamente cosas parecidas a las de los foo y comprobar la locura hasta que te pongan foos. Creo que esta es una solución válida, pero si no te gusta:

Hazlo rápido

Las posibilidades de que una cosa parecida a un foo sea aleatoria son probablemente bastante bajas, por lo que especificar un límite de tiempo probablemente forzará un intento genuino de generación de foo.

Para adaptarse a las diferencias de velocidad entre diferentes idiomas, es posible que desee tener límites de tiempo diferentes según el idioma como Hackerrank: https://www.hackerrank.com/environment . Sin embargo, si especifica foos lo suficientemente grandes, la probabilidad de que las cosas parecidas a foo sean aleatorias podría ser realmente baja, por lo que una regla de "antes de la muerte por calor del Universo" podría ser suficiente.

James Hollis
fuente
Creo que tienes algo aquí. "Ejecutar el programa N veces no producirá duplicados al menos el 90% del tiempo" es concreto y bastante fácil de probar, y se puede combinar con un límite de tiempo para evitar el uso de fuerza bruta y el muestreo de rechazo simple también.
Zgarb
2

No pretendo tener la solución definitiva al problema (o que esta lista sea exhaustiva), pero quiero esbozar algunos enfoques posibles que se me ocurren y por qué funcionarían o no. Tampoco abordaré cuestiones tangenciales como si el uso de la marca de tiempo actual como fuente de aleatoriedad es lo suficientemente "impredecible" y cómo aplicar ciertas propiedades de la distribución de probabilidad: me concentraré en evitar soluciones que usen codificación rígida.

No es una solución: no permitir la codificación explícitamente

Esta es una mala idea. Es un requisito no observable (lo que significa que no puede determinar si se cumple simplemente ejecutando el programa), que se desaconseja firmemente en PPCG y puede ser absolutamente imposible si se ejecuta el programa en cualquier otra plataforma, donde las presentaciones se verifican en un manera automatizada El problema con un requisito como este es que tendría que comenzar por encontrar una definición objetiva para "codificación rígida". En general, si intentas esto, solo empeorarás las cosas.

Hacer que la codificación no sea factible

Si no puede rechazarlo por completo, pero no desea que las personas lo usen, puede intentar diseñar el desafío de manera que la codificación rígida simplemente no sea un enfoque competitivo. Esto es posible si los objetos que deberían generarse son lo suficientemente grandes e incompresibles como para poner un ejemplo en el código requeriría muchos más bytes que escribir un algoritmo que genere soluciones válidas al azar. En su ejemplo específico, ese no es el caso, por supuesto, porque las matrices de identidad son válidas y generalmente son fáciles de generar, pero para otros problemas, ese podría no ser el caso. Si los objetos de destino son lo suficientemente irregulares, solo es necesario que sean de gran tamaño, lo que probablemente no afectará el recuento de bytes de un algoritmo real, pero explotará la parte codificada.

Parametrizar la salida

A menudo, estos problemas vienen con uno o más parámetros naturales, como el tamaño de la matriz en su ejemplo. Si es así, hacer que ese parámetro sea una entrada puede ser suficiente para hacer imposible la codificación rígida o al menos poco práctica. En algunos casos, puede ser fácil codificar una solución específica para un valor de parámetro dado que se ha encontrado manualmente o mediante una búsqueda exhaustiva, pero tal vez no haya una forma cerrada simple para una instancia de estas soluciones en general, por lo que no es posible generar un valor predeterminado para entradas arbitrarias fácilmente. Nuevamente, este no es el caso para el ejemplo que menciona, porque la matriz de identidad funciona en cualquier tamaño, pero es una solución óptima para este problema relacionadogeneralmente es muy irregular, por lo que no es posible tener un valor predeterminado sin buscar activamente valores válidos de todos modos. Puede combinar esto con un límite de tiempo para evitar una búsqueda de fuerza bruta para un valor predeterminado.

Poner alguna restricción en la distribución de probabilidad

Si usted está dispuesto a renunciar a un completo distribución de probabilidad sin restricciones, puede poner algunas restricciones sobre el mismo, que todavía dan que responden mucha libertad en la elección de su distribución, sino que hacen difícil la codificación de una difícil o imposible:

  • La restricción más simple que viene a la mente es requerir la diferencia entre la probabilidad mínima y máxima para que cualquier salida posible esté por debajo de un cierto umbral. Un enfoque codificado probablemente tendrá probabilidades casi nulas para casi todas las salidas y una probabilidad cercana a 1 para el valor predeterminado. Si necesita que la diferencia máxima sea inferior a 0.1, por ejemplo, necesitaría tener 10 valores predeterminados (elegidos al azar) para que el enfoque sea una opción. Del mismo modo, también podría requerir una probabilidad mínima para cada salida posible, por ejemplo, 1 / (2 * N *), donde N es el número de salidas posibles.
  • Alternativamente, puede requerir que no haya espacios (de probabilidad) en la distribución, de modo que no exista un intervalo de tamaño δ (elegido por usted) de modo que existan probabilidades mayores y menores. Eso significa que no puede haber valores atípicos en términos de probabilidad, que probablemente se generan por un enfoque de codificación rígida.

El problema principal con estos enfoques es que es mucho más difícil razonar sobre ellos, es difícil demostrar que las respuestas son correctas y verificar experimentalmente la exactitud puede ser imposible para grandes espacios de salida. Aún así, proporcionan un requisito principalmente observable para el programa que puede hacer imposible la codificación rígida.

Es posible que estos enfoques también necesiten un límite de tiempo, porque una forma de aumentar la probabilidad de los valores no predeterminados sería intentar encontrar un valor aleatorio varias veces antes de volver al valor predeterminado.

Martin Ender
fuente