Articulo de referencia

Tamiz de Pritchard

Criba de Pritchard: pasos del algoritmo para números primos hasta 150 En matemáticas , la criba de Pritchard es un algoritmo para hallar todos los números primos hasta un límite...

Criba de Pritchard: pasos del algoritmo para números primos hasta 150

En matemáticas , la criba de Pritchard es un algoritmo para hallar todos los números primos hasta un límite especificado. Al igual que la antigua criba de Eratóstenes , tiene una base conceptual sencilla en la teoría de números . [ 1 ] Es especialmente adecuada para cálculos manuales rápidos con límites pequeños.

Mientras que la criba de Eratóstenes descarta cada número no primo para cada uno de sus factores primos, la criba de Pritchard evita considerar casi todos los números no primos mediante la construcción de ruedas progresivamente más grandes, que representan el patrón de números no divisibles por ninguno de los primos procesados ​​hasta el momento. De este modo, logra una mejor complejidad asintótica y fue la primera criba con un tiempo de ejecución sublineal en el límite especificado. Su tiempo de ejecución asintótico no ha sido mejorado y elimina menos compuestos que cualquier otra criba conocida. Fue creada en 1979 por Paul Pritchard. [ 2 ]

Dado que Pritchard ha creado varios otros algoritmos de criba para encontrar números primos, [ 3 ] [ 4 ] [ 5 ] la criba de Pritchard a veces se destaca por ser llamada la criba de rueda (por el propio Pritchard [ 1 ] ) o la criba de rueda dinámica . [ 6 ]

Descripción general

Un número primo es un número natural que no tiene divisores naturales aparte del número 1 y él mismo.

Para encontrar todos los números primos menores o iguales a un entero N dado , un algoritmo de criba examina un conjunto de candidatos en el rango 2, 3, ... , N , y elimina los que no son primos, dejando los primos al final. La criba de Eratóstenes examina todo el rango, eliminando primero todos los múltiplos del primer primo 2, luego del siguiente primo 3, y así sucesivamente. La criba de Pritchard, en cambio, examina un subconjunto del rango que consiste en números que aparecen en ruedas sucesivas, que representan el patrón de números que quedan después de que cada primo sucesivo sea procesado por la criba de Eratóstenes.

Para i > 0 , la i -ésima rueda W i representa este patrón. Es el conjunto de números entre 1 y el producto P i = p 1 · p 2 p i de los primeros i números primos que no son divisibles por ninguno de estos números primos (y se dice que tiene una longitud asociada P i ). Esto se debe a que sumar P i a un número no cambia si es divisible por uno de los primeros i números primos, ya que el resto de la división por cualquiera de estos primos no cambia.

Así, W 1 = {1} con longitud P 1 = 2 representa el patrón de números impares; W 2 = {1,5} con longitud P 2 = 6 representa el patrón de números no divisibles por 2 o 3; etc. Las ruedas se llaman así porque W i se puede visualizar como un círculo de circunferencia P i con sus lados marcados a sus distancias correspondientes desde un origen. Al hacer rodar la rueda a lo largo de la recta numérica, se marcan puntos que corresponden a números sucesivos no divisibles por ninguno de los primeros i números primos. La animación muestra cómo W 2 se hace rodar hasta 30.

Haciendo rodar la segunda rueda hasta 30.

Resulta útil definir W in para n > 0 como el resultado de extender W i hasta n . Entonces la animación genera W 2 30 = {1,5,7,11,13,17,19,23,25,29} . Nótese que hasta 5 2 1 = 24 , esto consiste únicamente en 1 y los primos entre 5 y 25.

La criba de Pritchard se deriva de la observación [ 1 ] de que esto se cumple en general: para todo i > 0 , los valores en W i ( p 2 i +1 1) son 1 y los primos entre p i +1 y p 2 i +1 . Incluso se cumple para i = 0 , donde la rueda tiene longitud 1 y contiene solo 1 (que representa todos los números naturales). Así, la criba de Pritchard comienza con la rueda trivial W 0 y construye ruedas sucesivas hasta que el cuadrado del primer miembro de la rueda después de 1 sea al menos N. Las ruedas crecen muy rápidamente, pero solo se necesitan y generan sus valores hasta N.

Queda por encontrar un método para generar la siguiente rueda. Nótese en la animación que W 3 = {1,5,7,11,13,17,19,23,25,29} {5 · 1 , 5 · 5} se puede obtener haciendo rodar W 2 hasta 30 y luego eliminando 5 veces cada miembro de W 2 . Esto también se cumple en general: para todo i 0 , W i +1 = ( W i P i +1 ) { p i +1 · w | w W i } . [ 1 ] Hacer rodar W i más allá de P i simplemente añade valores a W i , por lo que la rueda actual se extiende primero obteniendo cada miembro sucesivo comenzando con w = 1 , sumándole P i y insertando el resultado en el conjunto. Luego se eliminan los múltiplos de p i +1 . Se debe tener cuidado de evitar que se elimine un número que a su vez deba multiplicarse por p i +1 . La criba de Pritchard, tal como se presentó originalmente [ 2 ], realiza primero las eliminaciones saltándose los elementos sucesivos hasta encontrar el máximo necesario, y luego recorriendo el conjunto en orden inverso. Este es el método utilizado en la primera animación anterior. Un enfoque más sencillo consiste en reunir los múltiplos de p i +1 en una lista y luego eliminarlos. [ 7 ] Gries y Misra proponen otro enfoque. [ 8 ]

Si el bucle principal termina con una rueda cuya longitud es menor que N , se extiende hasta N para generar los primos restantes.

Por lo tanto , el algoritmo para encontrar todos los números primos hasta N es el siguiente:

  1. Comience con un conjunto W = {1} y longitud = 1 que representa la rueda 0, y primo p = 2 .
  2. Siempre que p 2 N , haga lo siguiente:
    1. si longitud < N , entonces
      1. extender W obteniendo repetidamente miembros sucesivos w de W comenzando con 1 e insertando longitud + w en W siempre que no exceda p · longitud o N ;
      2. aumentar la longitud hasta el mínimo de p · longitud y N.
    2. Elimine repetidamente p veces cada miembro de W , primero encontrando la longitud más grande y luego trabajando hacia atrás.
    3. anote el número primo p , luego establezca p al siguiente miembro de W después de 1 (o 3 si p era 2).
  3. si length < N , entonces extiende W a N obteniendo repetidamente miembros sucesivos w de W comenzando con 1 e insertando length + w en W mientras no exceda N ;
  4. Al finalizar, el resto de los números primos hasta N son los miembros de W después del 1.

Ejemplo

Para encontrar todos los números primos menores o iguales a 150, proceda de la siguiente manera.

Comience con la rueda 0 de longitud 1, que representa todos los números naturales 1, 2, 3...:

 1

El primer número después del 1 para la rueda 0 (al ser lanzada) es 2; obsérvelo como un número primo. Ahora forme la rueda 1 con una longitud de 2 × 1 = 2 extendiendo primero la rueda 0 hasta 2 y luego eliminando 2 veces cada número en la rueda 0, para obtener:

 1 2

El primer número después del 1 para la rueda 1 (cuando se lanza) es 3; obsérvelo como un número primo. Ahora forme la rueda 2 con una longitud de 3 × 2 = 6 extendiendo primero la rueda 1 hasta 6 y luego eliminando 3 veces cada número en la rueda 1, para obtener

 1 2 3 5

El primer número después del 1 para la rueda 2 es 5; obsérvelo como un número primo. Ahora forme la rueda 3 con una longitud de 5 × 6 = 30 extendiendo primero la rueda 2 hasta 30 y luego eliminando 5 veces cada número en la rueda 2 (en orden inverso), para obtener

 1 2 3 5 7 11 13 17 19 23 25 29

El primer número después del 1 en la rueda 3 es 7; obsérvelo como un número primo. Ahora la rueda 4 tiene una longitud de 7 × 30 = 210, por lo que solo extendemos la rueda 3 hasta nuestro límite de 150. (No se realizará ninguna extensión adicional una vez alcanzado el límite). Luego eliminamos 7 veces cada número en la rueda 3 hasta superar nuestro límite de 150, para obtener los elementos de la rueda 4 hasta 150:

 1 2 3 5 7 11 13 17 19 23 25 29 31 37 41 43 47 49 53 59 61 67 71 73 77 79 83 89 91 97 101 103 107 109 113 119 121 127 131 133 137 139 143 149

El primer número después del 1 para esta rueda parcial 4 es 11; obsérvelo como un número primo. Como hemos terminado de rodar, eliminamos 11 veces cada número en la rueda parcial 4 hasta superar nuestro límite de 150, para obtener los elementos en la rueda 5 hasta 150:

 1 2 3 5 7 11 13 17 19 23 25 29 31 37 41 43 47 49 53 59 61 67 71 73 77 79 83 89 91 97 101 103 107 109 113 119 121 127 131 133 137 139 143 149

El primer número después del 1 para esta rueda parcial 5 es 13. Como 13 al cuadrado es al menos nuestro límite de 150, nos detenemos. Los números restantes (aparte del 1) son el resto de los números primos hasta nuestro límite de 150.

Solo se eliminan 8 números compuestos, una vez cada uno. El resto de los números considerados (excepto el 1) son primos. En comparación, la versión natural del cribado de Eratóstenes (que se detiene en el mismo punto) elimina los números compuestos 184 veces.

Pseudocódigo

El tamiz de Pritchard se puede expresar en pseudocódigo de la siguiente manera: [ 1 ]

El algoritmo Criba de Pritchard tiene como entrada : un número entero N >= 2. La salida es: el conjunto de números primos en {1,2,..., N }. Sean W y Pr conjuntos de valores enteros , y todas las demás variables valores enteros . k , W , length , p , Pr := 1, {1}, 2, 3, {2}; { invariante : p = p k +1 y W = W k{\displaystyle \cap }{1,2,..., N } y longitud = mínimo de P k , N y Pr = los primos hasta p k } mientras p 2 <= N hacer si ( longitud < N ) entonces Extender W , longitud al mínimo de p * longitud , N ; Eliminar los múltiplos de p de W ; Insertar p en Pr ; k , p := k + 1, siguiente( W , 1) si ( longitud < N ) entonces Extender W , longitud a N ; devolver Pr{\displaystyle \cup }W - {1};

donde next(W, w) es el siguiente valor en el conjunto ordenado W después de w .

El procedimiento Extender W , longitud a n es { en: W = W k y longitud = P k y n > longitud } { salida: W = W k{\displaystyle \rightarrow }n y longitud = n } entero w, x;  w , x := 1, longitud +1;  mientras x <= n hacer Insertar x en W ;  w := next( W , w );  x := longitud + w ;  longitud := n ;
procedimiento Eliminar múltiplos de p de W , longitud es entero w; w := p ; mientras p * w <= longitud hacer w := next( W , w ); mientras w > 1 hacer w := prev( W , w ); Eliminar p * w de W ;

donde prev(W, w) es el valor anterior en el conjunto ordenado W antes de w . El algoritmo puede inicializarse con W 0 en lugar de W 1 con la pequeña complicación de hacer next(W, 1) un caso especial cuando k = 0 .

Este algoritmo abstracto utiliza conjuntos ordenados que admiten las operaciones de inserción de un valor mayor que el máximo, eliminación de un miembro, obtención del siguiente valor después de un miembro y obtención del valor anterior a un miembro. Utilizando uno de los teoremas de Mertens (el tercero), se puede demostrar que utiliza O ( N /log log N ) de estas operaciones, sumas y multiplicaciones. [ 2 ]

Implementación

Una lista doblemente enlazada basada en arreglos s puede usarse para implementar el conjunto ordenado W , donde s[w] almacena next(W,w) y s[w-1] almacena prev(W,w) . Esto permite que cada operación abstracta se implemente en un pequeño número de operaciones. (El arreglo también puede usarse para almacenar el conjunto Pr "gratis"). Por lo tanto, la complejidad temporal de la criba de Pritchard para calcular los primos hasta N en el modelo de máquina de acceso aleatorio es O ( N /log log N ) operaciones en palabras de tamaño O (log N ) . Pritchard también muestra cómo se pueden eliminar las multiplicaciones usando tablas de multiplicación muy pequeñas, [ 2 ] por lo que la complejidad de bits es O ( N log N /log log N ) operaciones de bits.

En el mismo modelo, la complejidad espacial es O ( N ) palabras, es decir, O ( N log N ) bits. La criba de Eratóstenes requiere solo 1 bit para cada candidato en el rango de 2 a N , por lo que su complejidad espacial es menor, de O ( N ) bits. Nótese que el espacio necesario para los números primos no se cuenta, ya que pueden imprimirse o escribirse en almacenamiento externo a medida que se encuentran. Pritchard [ 2 ] presentó una variante de su criba que requiere solo O ( N /log log N ) bits sin comprometer la complejidad temporal sublineal, lo que la hace asintóticamente superior a la versión natural de la criba de Eratóstenes tanto en tiempo como en espacio.

Sin embargo, la criba de Eratósteos puede optimizarse para requerir mucha menos memoria operando sobre segmentos sucesivos de los números naturales. [ 9 ] Su complejidad espacial puede reducirse a O ( N ) bits sin aumentar su complejidad temporal. [ 3 ] Esto significa que, en la práctica, puede utilizarse para límites N mucho mayores de los que cabrían en la memoria, y también aprovechar la memoria caché rápida. Para obtener la máxima velocidad, también se optimiza utilizando una rueda pequeña para evitar el cribado con los primeros primos (aunque esto no cambia su complejidad temporal asintótica). Por lo tanto, la criba de Pritchard no es competitiva como criba práctica en rangos suficientemente grandes.

Modelo geométrico

Generando ruedas sucesivas hastaW3{\displaystyle W_{3}}

En el núcleo del tamiz de Pritchard se encuentra un algoritmo para construir ruedas sucesivas. Tiene un modelo geométrico simple como el siguiente:

  1. Comience con un círculo de circunferencia 1 con una marca en 1.
  2. Para generar la siguiente rueda:
    1. Recorre la rueda y encuentra (la distancia a) la primera marca después de 1; llámala p .
    2. Crea un nuevo círculo con una circunferencia p veces mayor que la de la rueda actual.
    3. Haz girar la rueda actual alrededor del nuevo círculo, marcándolo donde una marca lo toque.
    4. Amplíe la rueda actual por p y elimine las marcas que coincidan.

Para las dos primeras iteraciones es necesario continuar dando vueltas en círculo hasta llegar de nuevo al número 1.

El primer círculo representa W 0 = {1} , y los círculos sucesivos representan las ruedas W 1 , W 2 , . La animación de la derecha muestra este modelo en acción hasta W 3 .

Del modelo se desprende que las ruedas son simétricas. Esto se debe a que P kw no es divisible por ninguno de los primeros k primos si y solo si w no es divisible por ellos. Es posible aprovechar esta característica para evitar procesar algunos números compuestos, pero a costa de un algoritmo más complejo.

Una vez que la rueda en el tamiz de Pritchard alcanza su tamaño máximo, las operaciones restantes son equivalentes a las realizadas por el tamiz de Euler .

El tamiz de Pritchard es único por combinar el conjunto de candidatos primos con una rueda dinámica utilizada para acelerar el proceso de tamizado. Pero una rueda estática separada (como la que se usa frecuentemente para acelerar el tamiz de Eratóstenes) puede dar una aceleración de O (log log N ) a este último, o a tamices lineales, siempre que sea lo suficientemente grande (en función de N ). Ejemplos son el uso de la rueda más grande de longitud que no exceda N / log 2 N para obtener una versión del tamiz de Eratóstenes que toma O ( N ) adiciones y requiere solo O ( N / log log N ) bits, [ 3 ] y la aceleración del tamiz naturalmente lineal de Atkin para obtener una versión optimizada sublineal.

Bengalloun encontró una criba incremental suave lineal, [ 10 ] es decir, una que (en teoría) puede ejecutarse indefinidamente y requiere un número limitado de operaciones para incrementar el límite actual N. También mostró cómo hacerla sublineal adaptando la criba de Pritchard para construir incrementalmente la siguiente rueda dinámica mientras se usa la actual. Pritchard [ 5 ] mostró cómo evitar las multiplicaciones, obteniendo así la misma complejidad asintótica de bits que la criba de Pritchard.

Runciman proporciona un algoritmo funcional [ 11 ] inspirado en el tamiz de Pritchard.

Véase también

Referencias

  1. 1 2 3 4 5 Pritchard, Paul (1982). "Explicando el tamiz de rueda". Acta Informatica . 17 (4): 477– 485. doi : 10.1007/BF00264164 . S2CID 122592488 . 
  2. 1 2 3 4 5 Pritchard, Paul (1981). "Una criba aditiva sublineal para encontrar números primos" . Communications of the ACM . 24 (1): 18– 23. doi : 10.1145/358527.358540 . S2CID 16526704 . 
  3. 1 2 3 Pritchard, Paul (1983). "Talas rápidas y compactas de números primos (entre otras)". Journal of Algorithms . 4 (4): 332– 344. doi : 10.1016/0196-6774(83)90014-7 . hdl : 1813/6313 . S2CID 1068851 . 
  4. Pritchard, Paul (1987). "Criadores lineales de números primos: Un árbol genealógico" . Science of Computer Programming . 9 (1): 17– 35. doi : 10.1016/0167-6423(87)90024-4 . S2CID 44111749 . 
  5. 1 2 Pritchard, Paul (1980). "Sobre el ejemplo primordial de la programación". Diseño de lenguajes y metodología de programación . Notas de clase en ciencias de la computación. Vol. 877. págs. 280–288 . CiteSeerX 10.1.1.52.835 . doi : 10.1007/3-540-09745-7_5 . ISBN    978-3-540-09745-7. S2CID 9214019 . 
  6. Dunten, Brian; Jones, Julie; Sorenson, Jonathan (1996). "Una criba rápida de números primos que ahorra espacio". Information Processing Letters . 59 (2): 79– 84. CiteSeerX 10.1.1.31.3936 . doi : 10.1016/0020-0190(96)00099-3 . S2CID 9385950 .  
  7. Mairson, Harry G. (1977). "Algunos nuevos límites superiores en la generación de números primos" . Communications of the ACM . 20 (9): 664– 669. doi : 10.1145/359810.359838 . S2CID 20118576 . 
  8. Gries, David; Misra, Jayadev (1978). "Un algoritmo de criba lineal para encontrar números primos". Communications of the ACM . 21 (12): 999– 1003. doi : 10.1145/359657.359660 . hdl : 1813/6407 . S2CID 11990373 . 
  9. Bays, Carter; Hudson, Richard H. (1977). "La criba segmentada de Eratóstenes y los números primos en progresiones aritméticas hasta 10 12 ". BIT . 17 (2): 121– 127. doi : 10.1007/BF01932283 . S2CID 122592488 . 
  10. ^ Bengelloun, SA (2004). "Un tamiz primario incremental". Acta Informática . 23 (2): 119– 125. doi : 10.1007/BF00289493 . S2CID 20118576 . 
  11. Runciman, C. (1997). "Lazy Wheel Sieves and Spirals of Primes" (PDF) . Journal of Functional Programming . 7 (2): 219– 225. doi : 10.1017/S0956796897002670 . S2CID 2422563 .