¿Cuál es la intuición detrás de los algoritmos aleatorios y la aleatorización en general?

Explicaré esto con la ayuda de un ejemplo. Uno de los métodos más utilizados es el método de Monte Carlo. Básicamente, este método implica ejecutar simulaciones muchas veces para obtener el valor o resultado esperado. ¿Cómo ayudaría esto?

Considere renderizar una imagen realista de foto. Un método común para hacer esto es “trazar” el camino de un rayo de luz desde cada píxel de la cámara (u ojo) a través de toda la escena para descubrir con qué objetos interactúa (este método se llama trazado de rayos).

Ahora, una forma sería rastrear cada rayo en cada dirección que posiblemente pueda generarse. Puedes ver por qué esto podría ser una tarea enorme. Otra forma es generar un rayo y calcular cuál es la probabilidad de que se genere este rayo en particular (existen modelos matemáticos que puede usar para resolverlo). Entonces, simplemente puede sopesar la contribución de este rayo por su probabilidad. Haga esto varias veces y podrá calcular el valor esperado. Por supuesto, esto nunca será perfecto, pero siempre puede elegir la cantidad de rayos que desea generar para obtener un porcentaje de error esperado. Mucho mejor que tratar de generar cada rayo posible. (Nota: Todo esto es un poco simplificador, pero correcto)

Muchos algoritmos funcionan de esta manera, especialmente aquellos que tienen un gran espacio de búsqueda. El truco consiste en usar un subconjunto de posibilidades y calcular cuál es la probabilidad de que se generaron y usar eso para calcular el valor esperado de un determinado cálculo, en lugar de buscar el valor perfecto real que tomaría años en calcular.

Ah, los algoritmos aleatorios son ciertamente muy hermosos. A menudo pueden expresarse de manera muy simple e intuitiva , y aún así ser un dolor de analizar. Después de haber hecho un curso sobre el tema, puedo empatizar totalmente contigo.

En el núcleo de los algos aleatorizados, está el análisis . El hecho de que pueden ser bastante prácticos e intuitivos está muy bien, pero en el momento en que te pones a analizar, ¡ es cuando todo pasa por alto ! Si alguna vez siente que es “simplemente teórico”, estoy seguro de que es solo porque el análisis es bastante complejo.

Métodos de Monte Carlo:
Hay bastantes sabores de algoritmos aleatorios. Como mencionó Devansh Gupta, existe el método Monte Carlo , que estima las probabilidades ejecutando una gran cantidad de simulaciones.

Considera esta pregunta:
Q. Estime el número de divisores de un número dado [math] n [/ math].
Resp. Considere el siguiente algoritmo …

  para iteraciones M, haga:
     d = número aleatorio en 1 a n
     si (d es un divisor de n):
         cnt incremental
 retorno cnt / M * n

Entonces, aquí tenemos un gran espacio de búsqueda (tamaño [matemático] n [/ matemático]), y si tuviéramos que probar cada valor, tomaría [matemático] O (n) [/ matemático] tiempo. Pero si hiciéramos lo anterior, solo tomaría tiempo [matemático] O (M) [/ matemático]. Estaría apagado, pero luego la pregunta pide una estimación .

Bueno, claramente la intuición del algoritmo es bastante sencilla. Pero cualquiera haría la pregunta “¿Pero qué tan bueno es el algoritmo? ¿Qué tan lejos del valor real está la respuesta? Si tuviera que probar el algoritmo con una [matemática] M [/ matemática] mayor , ¿cuánto mejor sería mi estimación? ? “ Y ahí es donde entra el análisis . Ahí es donde parece que “los algoritmos aleatorios son solo sobre teoría”.

Supongamos que debo usar el hecho de que, si [matemática] d [/ matemática] es un factor, entonces también lo es [matemática] n / d [/ matemática], y simplemente estimar el número de divisores en el rango [matemática] [ 1, \ sqrt {n}] [/ math] y duplica eso?

  para iteraciones M, haga:
     d = número aleatorio en 1 a sqrt (n)
     si (d es un divisor de n):
         cnt incremental
 devuelve 2 * cnt / M * root (n)

Bueno, bastante intuitivamente, este segundo enfoque es mejor que el primero. ¿Pero cómo mostramos eso? Esta es solo una ilustración simple de cómo se pueden usar diferentes esquemas de simulación para estimar la misma cantidad usando los métodos de Monte Carlo, y sin embargo, uno es mejor que el otro.

Palabra final: en general, está tratando de responder la pregunta: “¿Cuál es el menor número de simulaciones que necesito ( M ) para asegurar que con al menos probabilidad p (algún tipo de valor de confianza) no me salga de la respuesta correcta? más de dx (algún valor de tolerancia)? ”

Muestreo:
Otro tipo de área donde uno podría usar algoritmos aleatorios es prácticamente solo buscar un tipo particular de estructura. El espacio de búsqueda puede ser enorme, y en tales casos uno probará un montón de ejemplos y luego dirá “encontrado” o “probablemente no existe”. Además, versiones como “Esta estructura se da para existir. Encuéntrela”.

Podemos modificar nuestro ejemplo anterior aquí también.

  isPrime (n):
     para iteraciones M, haga:
         d = número aleatorio en 2 a n-1
         si (d es divisor de n):
             volver "no es primo"
     volver "probablemente sea primo"

Ahora, si tuviéramos que compararlo con

  isPrime (n):
     para iteraciones M, haga:
         d = número aleatorio en 2 a sqrt (n)
         si (d es divisor de n):
             volver "no es primo"
     volver "probablemente sea primo"

Algunos analisis:
Sea [math] d (n) [/ math] = número de divisores de [math] n [/ math] distintos de 1 y n
Ahora, en algo (1), el problema de encontrar un factor [matemática] p_1 (n) = d (n) / (n-2) [/ matemática]
Entonces, la probabilidad de estar equivocado = Prob que n es compuesto y devuelve “es probablemente primo” = [matemática] (1-p_1 (n)) ^ M [/ matemática]

En algo (2), problema de encontrar un factor [matemática] p_2 (n) = (d (n) / 2) / \ sqrt {n} -1) [/ matemática]
Entonces, la probabilidad de estar equivocado = … = [matemática] (1-p_2 (n)) ^ M [/ matemática].

Nota, [matemáticas] p_2 (n)> p_1 (n) [/ matemáticas]

Por lo tanto, para un valor de tolerancia dado, necesitamos ejecutar muchas menos iteraciones del algoritmo 2.

Un ejemplo de programación competitiva:
Teniendo en cuenta que “Codechef”, “Codeforces” y “TopCoder” se han etiquetado como temas de preguntas, me gustaría ofrecer este ejemplo como voluntario, ya que uno de “existe una estructura: encuéntrelo”.

Esta pregunta apareció en una ronda reciente de Codeforces (# 192, Div1, C): Problema – C – Codeforces. La pregunta básicamente pregunta lo siguiente:
Dado un gráfico sobre los vértices [matemáticos] n [/ matemáticos] y los bordes [matemáticos] m [/ matemáticos] , donde cada vértice tiene un grado máximo de 2, encuentre una subgrafía de su complemento que tenga las mismas propiedades (grado limitado, número de vértices, número de aristas) .

Debido al hecho de que el grado de cada vértice es al menos 2, para large-ish [math] n [/ math], el grado del vértice en el complemento también es grande. Por lo tanto, las posibilidades de encontrar un gráfico de este tipo son bastante altas.

Lo que había hecho fue que, para [matemáticas] n <= 7 [/ matemáticas], verifiqué todas las posibles subgrafías del complemento para las propiedades. Para [matemáticas] n> 7 [/ matemáticas], busqué un ciclo de longitud [matemáticas] m [/ matemáticas] en el gráfico del complemento.

  aunque cierto:
     seleccione x [] una permutación aleatoria de 1 a n
     para i en 1 a m-1:
         if (x [i], x [i + 1]) es una arista en el gráfico original:
             baraja la permutación desde (x [i-1] ... x [i + 2])
             reiniciar la comprobación desde i = i-2
     si (x [1], x [m]) están conectados:
         repetir todo el procedimiento
     más:
         ciclo de salida definido por vértices x [1], x [2], ..., x [m] y salir

Tenga en cuenta que, dado que sé que x [1], x [2], …, x [i-2] no causan ningún conflicto, después de mi reorganización solo necesito verificar si hay conflictos desde i-2 en adelante. Este tipo de técnica de “arreglo local” se ha utilizado mucho recientemente como el lema local Algorithmic Lovász (por desgracia, parece que la página de wikipedia es bastante compleja :()

El editorial de Ashar Fuadi describe una solución similar (Codeforces Round # 192 Editorial – Codeforces se desplaza hacia abajo a “solución no determinista” 329C), excepto que el procedimiento se repite desde cero tan pronto como se encuentra un borde. Esto también aparentemente funciona lo suficientemente bien en 100 iteraciones.

Intuición

La forma en que pienso sobre los algoritmos aleatorios es que aprovechan la simetría.

Piensa en los algoritmos que conoces. Un ejercicio que me gusta hacer es pensar en la pregunta “¿Cuál es el peor de los casos? ¿Cómo se ve?” Si hace esto para cada algoritmo que encuentre, un patrón que encontrará es la siguiente situación:

Todo iba bien hasta que golpeaste una bifurcación en el camino. Su algoritmo tomó una decisión desgarradora en algún lugar de la línea que lo atornilló. En ese paso el problema era simétrico; era imposible distinguir la buena elección de la mala.

La intuición que tengo para los algoritmos aleatorios se convierte en: si solo lanza una moneda en la bifurcación en el camino, tiene mejores expectativas de lo que es actualmente. ¿Por qué no dar el paso? No tienes nada que perder.

Aplicaciones

Algunos ejemplos fuera de mi cabeza donde esto entra en juego:

  • Aleatorizar el algoritmo simplex para programas lineales (el peor de los casos es un hipercubo “ruidoso” en el que siempre te engañan para elegir la dirección incorrecta).
  • Quicksort aleatorizado! La selección de pivote es difícil y a menudo tomas una mala decisión con cualquier regla de pivote que se te ocurra. ¡Rompe la simetría eligiendo uniformemente al azar!
  • Proyecciones aleatorias como técnica estándar para problemas de datos de alta dimensión. Los malos ejemplos de algoritmos de “big data” suelen ser cuando se tiene un vector masivo, pero solo unas pocas coordenadas importantes. Si el patrón está allí, probablemente pueda eliminar una tonelada de trabajo eliminando las coordenadas.
  • Estructuras de datos aleatorizados, como tablas de hash, listas de salto y Treaps. Aquí, estamos aprovechando la simetría en la forma en que se almacenan los datos. Agregar un lanzamiento de moneda aumenta nuestra probabilidad de elegir la ruta de acceso correcta.

Más aplicaciones incluyen muchos problemas teóricos de juegos y problemas en línea. Uno es el problema de coincidencia en línea y el algoritmo de clasificación. Las solicitudes de su equilibrador de carga están llegando a su fin, ¡debe elegir ahora! ¿Cómo garantiza que no le va mucho peor que lo óptimo en las expectativas? Agrega una elección al azar. Romper la simetría en las solicitudes.

Algunas veces sus estrategias en ciertos juegos no tienen “equilibrios tradicionales”. Un ejemplo es el juego de monedas a juego. Tienes dos jugadores, cada uno con una moneda de caras o colas. Cada uno puede elegir cara o cruz como estrategia. El jugador 1 gana si ambas caras coinciden, el jugador 2 gana si no lo hacen. Si escribe la matriz de pagos en este juego, verá que no hay equilibrio de Nash. Esta simetría (¡esta vez en la matriz!) Lo llevaría a creer que tal vez la mejor estrategia implica un lanzamiento de moneda.

Muchos de estos juegos bien estudiados se manifiestan en campos como finanzas o redes de computadoras (ancho de banda limitado, cada jugador es un ISP y tienen ancho de banda como un recurso limitado, agentes financieros que juegan el juego comercial, etc.).

Referencias

EL libro sobre algoritmos aleatorios es Motwani y Raghavan:

Algoritmos aleatorizados: Rajeev Motwani, Prabhakar Raghavan: 9780521474658: Amazon.com: Libros

No puedo recomendar este libro lo suficiente. Este libro cambió la forma en que pienso sobre los algoritmos. Tanta sabiduría en esas páginas.

También recomiendo estos otros libros de texto de algoritmos generales si no quieres sumergirte directamente en el tema:

  • CLRS: Introducción a los algoritmos: Thomas H. Cormen, Charles E. Leiserson, Ronald L. Rivest, Clifford Stein: 9780262033848: Amazon.com: Libros
  • K&T: Diseño de algoritmo: Jon Kleinberg, Éva Tardos: 9780321295354: Amazon.com: Libros

También recomendaría estas notas del curso si está buscando entrar rápidamente:

  • Página sobre el noroeste
  • Página sobre Yale

Nuevamente, no puedo recomendar Motwani y Raghavan lo suficiente.
TL; DR Comprar Motwani y Raghavan. Todo lo que quieras saber y más está en esas páginas.

Me gustaría responder a esta pregunta, pero no puedo hacer incluso [matemáticas] \ epsilon [/ matemáticas] mejor que la respuesta de Avi Wigderson a esta pregunta (y muchas más) de su charla:

En muchas situaciones, la intuición detrás del Algoritmo aleatorizado es que mueve la aleatoriedad de la entrada al algoritmo.

El ejemplo más simple es quicksort: como sabes, se ejecuta en O (n ^ 2) en el peor de los casos, pero en O (nlgn) en promedio. “En promedio” significa aquí “si la entrada es aleatoria”, que rara vez lo es. Pero, ¿qué sucede si agrego random_shuffle (input) como la primera instrucción a mi quick_sort? Ahora funciona con datos aleatorios, aunque la entrada original no fue aleatoria.

Si lo piensas por un momento, entonces te darás cuenta de que random_shuffle no difiere mucho de decir, eligiendo el pivote al azar.

La intuición principal para mí es: Usas “aleatoriedad” y obtienes una compensación entre incertidumbre y eficiencia.
Básicamente, los algoritmos aleatorios tienen un uso práctico siempre que pueda ejecutar un algoritmo varias veces, hasta que obtenga el buen resultado. El requisito previo para “obtener el resultado” que desea es tener un buen generador aleatorio. En ese caso, si repite un algoritmo una cantidad suficiente de veces, donde las entradas son buenos números aleatorios (que es algo difícil de obtener), definitivamente obtendrá el resultado que desea. En muchas aplicaciones, como la estructura de datos, la seguridad y la teoría de la información, los algoritmos aleatorios son prácticos y eficientes. Además, en la mayoría de los casos cuando tiene un problema NP, los algoritmos aleatorios son su mejor opción.

Una fuente buena y completa que puedo sugerir es el libro de texto “Algoritmos aleatorios” de Raghavan y Motwani (Cambridge Univ Press).

Digamos que quiere verificar si [math] A \ times B = C [/ math] (todas las matrices [math] n \ times n [/ math]).

Una forma ingenua pero determinista sería calcular el producto y combinarlo elemento por elemento con C.

El algoritmo de multiplicación matricial más conocido se ejecuta en [math] O (n ^ {2.3727}) [/ math] [1], por lo que el trabajo aquí, que implica más que multiplicación, debería necesitar más tiempo que esto. [?]

O podemos generar [math] n \ times 1 [/ math] dope aleatorio [math] \ hat {r} [/ math] en su lugar y verificar si [math] P = A \ times B \ hat {r} -C \ hat {r} = (0,0,0…) ^ T [/ math], que a su vez significa que [math] A \ times B = C [/mathfont>.This cuesta [math] O (n ^ 2) [/ math] tiempo de ejecución (que también es mínimo teórico ya que no puede verificar algo sin leerlo una vez.) Es justo sospechar más error ya que [math] \ hat {r} [/ math] fue aleatorio, lo que por cierto se reduce a [math] 2 ^ {- k} [/ math], por cada [math] k [/ math] veces que lo ejecutas.
Ese era un algoritmo aleatorio que era más rápido que el correspondiente algoritmo determinista más eficiente, por magnitudes.

[1] Respuesta de Alok Tripathy a ¿Cuál es el algoritmo más rápido para la multiplicación de matrices?

La aleatorización garantiza probabilidades iguales para elegir un candidato entre los disponibles.

Un buen ejemplo es en la Clasificación rápida, en la que elige aleatoriamente un pivote.
Y hay un 50% de posibilidades de que su número elegido al azar se encuentre entre el grupo ‘25% a 75% ‘.
Esto ofrece una muy buena elección de división con un pivote elegido al azar.

Además, el beneficio adicional es: no hay mucho que necesite codificar para la aleatorización, solo use el método de la biblioteca para elegir un número aleatorio.

Por el contrario, si usa versiones deterministas, debe emplear un algoritmo especial para que su elección sea óptima. por ejemplo, clasificación rápida determinista

More Interesting

¿Cuál es más grande: el universo computacional o el matemático? ¿Alguno subsume al otro?

Cómo demostrar esta congruencia si p es un primo mayor que 3 de modo que 1 ^ 2 + 2 ^ 2 + 3 ^ 2 + 4 ^ 2… (p-1) ^ 2 = 0 (mod p)

¿En qué se diferencia la teoría lógica de las matemáticas de la teoría lógica de la informática?

¿P = NP sería algo bueno?

¿Cuál es la mejor manera de manejar los problemas de coma flotante con cálculos financieros en JavaScript?

Recientemente he entregado mis tableros (12) y quiero hacer una mecánica BTech. Espero 85% en tableros, pero estoy seguro de que no romperé el avance de IIT. ¿Qué debo hacer, dejar un año y tomar clases de IIT o elegir la universidad solo este año? ¿Es seguro dejar caer un año?

¿Qué clases de problemas no se pueden resolver con métodos de optimización?

¿Cuáles son las ventajas de tener un título en matemáticas y trabajar como programador?

¿Cuál es la mejor manera de obtener una estimación numérica de la cantidad de conocimiento científico en el mundo? Sabemos con certeza que está aumentando, pero ¿cuánto más es ahora que, por ejemplo, en 1970?

¿Cuáles son algunos de los problemas NP-completos más difíciles?

¿Qué problemas originalmente se pensaban que solo podían resolverse con una computadora pero luego tenían una prueba de papel y lápiz?

¿Cómo hago para hacer investigación de pregrado en CS?

Cómo construir una computadora fuera del agua, y cómo ayuda esto con Navier-Stokes

Criptografía: ¿Cuál es una explicación intuitiva del algoritmo de cifrado RC4 y sus debilidades?

¿Se puede encontrar la intersección de dos listas en menos de tiempo lineal (las listas están ordenadas)?