Tamiz de Eratóstenes más allá de O (n). Prueba

En los comentarios a una de las publicaciones anteriores sobre el tamiz de Eratóstenes, se mencionó este breve algoritmo de Wikipedia :

Algoritmo 1:

1:  i := 2, 3, 4, ...,  n: 2:  lp[i] = 0: 3: lp[i] := i 4: pr[] += {i} 5:  p  pr  p ≤ lp[i]  p*i ≤ n: 6: lp[p*i] := p : lp -        n pr -     n. 

El algoritmo es simple, pero no para todos parece obvio. El problema principal es que no hay evidencia en Wikipedia, y el enlace a la fuente ( pdf ) contiene un algoritmo bastante diferente al anterior.

En esta publicación intentaré, espero, demostrar de manera accesible que este algoritmo no solo funciona, sino que también lo hace para la complejidad lineal.

Una nota sobre la complejidad del algoritmo.
Aunque este algoritmo es asintóticamente más rápido que el tamiz estándar de Eratóstenes en O (n log log n), requiere mucha más memoria. Por lo tanto, para n realmente grande, donde este algoritmo brilla en todo su esplendor, no es aplicable. Sin embargo, es muy útil incluso para n pequeña, si necesita no solo encontrar todos los números primos, sino también factorizar rápidamente todos los números hasta n.

Definiciones


 m a t h c a l P - Muchos primos.
l p ( x ) - mínimo divisor primo de un número: lp (x) = min \ {p \ in \ mathcal {P} \ \ vert \ p \ vert x \}lp (x) = min \ {p \ in \ mathcal {P} \ \ vert \ p \ vert x \}
r d ( x ) - otros factores: r d ( x ) = x / l p ( x )

Tenga en cuenta que todas las definiciones anteriores son para x g e 2  .

Algunas propiedades obvias de las funciones presentadas anteriormente, que se utilizarán más adelante:
lp(a timesb)=min(lp(a),lp(b))
rd(x)<x
p in mathcalP=>lp(p)=p

Prueba


Lema 1 : lp(x) lelp(rd(x)), forallx notin mathcalP,x>1
Prueba : porque cualquier divisor rd(x) también un divisor x y lp(x) no superior a ningún divisor x entonces lp(x) no supera ningún divisor rd(x) incluyendo el más pequeño de ellos. El único problema con esta declaración es si rd(x) no tiene divisores simples, pero esto solo es posible si x in mathcalP , que se excluye en la condición del lema.
 cuadrado

Dejar E = \ {(lp (x), rd (x)) \ vert \ forall x \ notin \ mathcal {P}, 2 \ le x \ le n \}

Porque lp(x) vecesrd(x)=x (por definición rd() ), si nos dieran mucho E entonces podríamos calcular lp() para todos los números compuestos hasta n. Esto se hace, por ejemplo, mediante el siguiente algoritmo:

Algoritmo 2:

 1:   (l,r)  E: 2: lp[l*r] := l; 

Tenga en cuenta que  vertE vert len por lo tanto, el algoritmo 2 anterior funciona para la complejidad lineal.

Además, demostraré que el algoritmo 1 de Wikipedia en realidad solo itera sobre todos los elementos de este conjunto, porque puede parametrizarse de una manera diferente.

Dejar E '= \ {(p, r) \ vert p \ in \ mathcal {P}, 2 \ le r <n, p \ le lp (r), p \ times r \ le n \}

Lema 2 : E=E
Prueba :

Dejar (a,b) enE =>  existex notin mathcalP, 2 lex len mida=lp(x),b=rd(x) .

Por definicion lp(),rd() : a in mathcalP , a timesb=x . Por Lemma 1, a lelp(b) .
porque rd(x)<x entonces b<n .
Desde x notin mathcalP , b ge2 .
Además, por definición E , x len por lo tanto a timesb len .
Las 4 condiciones E cumplido significa (a,b) enE => E subconjuntoE .

Dejar (a,b) enE . Dejar x=a vecesb .
Por definicion E , a in mathcalP . Significa a - división simple x .
lp(x)=lp(a timesb)=min(lp(a),lp(b))=min(a,lp(b)).
Porque a lelp(b) entonces lp(x)=a. Significa b=rd(x).
Por definición x=a timesb len. Obviamente también x=a timesb ge2.
Todas las condiciones para E completado => E subconjuntoE.

Por lo tanto E=E.
 cuadrado

Ahora queda resolver los correctos r y p de la definición del conjunto E y aplique el Algoritmo 2. Esto es exactamente lo que hace el Algoritmo 1 (solo se usa la variable i en lugar de r). Pero hay un problema! Para ordenar todos los elementos de un conjunto E calcular lp, necesitamos saber lp, porque hay una condición en la definición p lelp(r) .

Afortunadamente, este problema tiene el orden de clasificación correcto. Es necesario resolver r en el bucle externo, y p - En el interior. Entonces lp(r) ya será calculado Este hecho queda demostrado por el siguiente teorema.

Teorema 1:
El algoritmo 1 admite la siguiente invariante: después de la iteración del bucle externo para i = k, todos los primos hasta k inclusive se resaltarán en pr. También se contará lp() para todos x notin mathcalP midx len, rd(x) lek en la matriz de lp.

Prueba :
Probamos por inducción. Para k = 2, la invariante se verifica manualmente. El único primer 2 se agregará a la lista pr, porque la matriz lp [] se llena inicialmente con ceros. Además, el único número compuesto en el que rd(x) le2 Es 4. Es fácil verificar que el bucle interno se ejecutará exactamente una vez (para n> 3) y ejecutará correctamente lp [4]: ​​= 2.

Ahora suponga que el invariante se cumple para la iteración i = k-1. Probemos que también será válido para la iteración i = k.

Para hacer esto, es suficiente verificar que el número i, si es primo, se agregará a la lista pr y lp() se contará para todos los números compuestos x len, incluyendo rd(x)=i. Son estos números de la invariante para k que no están cubiertos por la invariante para k-1.

Si i es simple, entonces lp [i] será 0, porque la única operación de escritura en la matriz lp, que teóricamente podría calcular lp [i] (en la línea 6), siempre escribe en índices compuestos, porque p * i (para i> 1) - siempre compuesto. Por lo tanto, el número i se agregará a la lista de primos. Además, en la línea 3, se contará lp [i].

Si i es compuesto, al comienzo de la iteración lp [i] ya será calculado por el invariante para i = k-1, porque rd(i)<i o rd(i) lei1, por lo tanto, caigo bajo la condición invariante en la iteración anterior. Por lo tanto, el número compuesto i no se agregará a la lista de primos.

Además, teniendo el lp [i] correcto y todos los primos hasta i inclusive, el bucle en las líneas 5-6 iterará sobre todos los elementos (p,i) enE en el que la segunda parte es i:

  • p enP, porque es de la lista pr
  • p lelp(i), por condición para detener el ciclo
  • p vecesi len, por condición para detener el ciclo
  • i<n, se sigue de p vecesi len, p>1

Todos los primos necesarios en la lista pr son, porque solo números hasta lp(i) lei . Por lo tanto, los valores de lp [] se calcularán para todos los números compuestos x para que rd(x)=i . Estos son exactamente todos los números que faltaban durante la transición de la invariante para k-1 a la invariante para k.

Por lo tanto, la invariante se cumple para cualquier i = 2..n.

 cuadrado

Según el invariante del Teorema 1 para i = n, resulta que todos los números primos hasta n y todo lp [] se calculará mediante el algoritmo 1.

Además, dado que en las filas 5-6 se ordenan varios elementos del conjunto E , entonces el bucle interno total no se ejecutará más  vertE vert<n operaciones La operación de verificación en el bucle se ejecutará sin problemas  vertE vert+n1<2n veces (  vertE vert veces devolverá verdadero y n-1 veces, para cada i, devolverá falso). Todas las operaciones restantes están anidadas en un ciclo en i de 2 a n.
Se deduce que la complejidad del algoritmo 1 es O (n).

Source: https://habr.com/ru/post/452388/


All Articles