Foro de elhacker.net

Programación => Scripting => Mensaje iniciado por: camaleonh en 28 Febrero 2012, 08:16 am



Título: [Python] Optimizar busqueda de primos
Publicado por: camaleonh en 28 Febrero 2012, 08:16 am
Hola a todos
Este algoritmo es hasta el que he podido llegar con mayor velocidad a encontrar numeros primos, el problema es que busco encontrar un numero primo de más de 20 cifras pero demora una eternidad, entonces cualquier optimización me sirve de mucha ayuda

Código
  1. #!/usr/bin/env python
  2.  
  3. #Buscador de Numeros primos a partir de un numero dado
  4. # Juan Fernando Hernandez
  5. # Universidad de Antioquia - Matematicas Discretas
  6. # uso: python eratostenes_criba.py numero_inicial
  7.  
  8. from math import sqrt
  9. import sys
  10.  
  11. # Lista de primos y semaforo de llenado de lista
  12. lista_p = [2]
  13.  
  14.  
  15. ultimo_numero = 2
  16. breaker = 1
  17.  
  18. # Busqueda de primos (true->primo || false->compuesto)
  19. def primo(numero):
  20.  
  21. # si es divisible por la lista no es primo (Retorna falso)
  22. for i in lista_p:
  23. modulo = numero % i
  24. if (modulo == 0): return False
  25. # Se sabe que como el numero inmediatamente anterior en el bucle es
  26. # menor, todos los primos de la lista < raiz de numero actual
  27.  
  28. return llenar_lista(numero)
  29.  
  30. def llenar_lista(numero):
  31.  
  32. global breaker
  33. global ultimo_numero
  34.  
  35. raiz = long(sqrt(numero))
  36. # Necesario para no comprobar todos los primos de la lista
  37. # se establece un breaker
  38.  
  39. lista_p_len = len(lista_p)
  40. raiz_raiz = long(sqrt(raiz))
  41.  
  42. for i in range(breaker,lista_p_len):
  43. if (lista_p[i] >= raiz_raiz):
  44. breaker = i;
  45. break;
  46.  
  47. ultimo_numero += 1
  48.  
  49. for i in range(ultimo_numero,raiz+1):
  50. for n in range(0,breaker):
  51. modulo = i%lista_p[n]
  52. if (modulo == 0):
  53. break
  54. elif (n == breaker-1):
  55. lista_p.append(i)
  56. modulo_numero = numero % i
  57. if(modulo_numero == 0):
  58. ultimo_numero = i
  59. return False
  60.  
  61. ultimo_numero = raiz
  62. return True
  63.  
  64.  
  65.  
  66. def main():
  67.  
  68.    #n = 10000000000000000000 #Numero minimo
  69.    n = long(sys.argv[1])  # Minimo numero desde el cual buscar el proximo primo
  70.  
  71.  
  72.    while True:
  73.        print "Probando primo: ", n
  74.        if(primo(n)):
  75.            break;
  76.        n += 1
  77.  
  78.    print "Primo encontrado: ", n
  79.  
  80. if __name__ == "__main__":
  81.    main()
  82.  
  83.