Calificación:
  • 0 voto(s) - 0 Media
  • 1
  • 2
  • 3
  • 4
  • 5
Programa tarda demasiado en finalizar al mostrar números perfectos.[python]
#1
Hola, ¿cómo están?
El caso es que no puedo mejorar el tiempo que tarda el programa en mostrar los números
perfectos desde 1 a 100000, 6-28-496 y 8128 luego no finaliza nunca, si alguien me ayuda
a solucionar esto muy agradecido. -

Código:
def n_perfecto(n):
sumatorio = 0
for i in range(1, n):
if n % i == 0:
sumatorio += i
return sumatorio == n

n = 1
print('\n === Números perfectos ===\n')
while n < 100000:
if n_perfecto(n):
print(f'{str(n).rjust(10, " ")}')
n += 1
Saludos.
abraza las cosas y personas malas como si fueran tu mas preciada joya,Son tus mas grandes maestros de paciencia sabiduría y amor y cuando lo abrazas dejan de causar dolor.-
Responder
#2
Hola Daniel, ¿cómo estás? Es interesante el programa (no conocía el concepto de número perfecto). Ahora, por lo que pude investigar, el siguiente número sería 33.550.336; es natural que el código se tome su tiempo. Hay dos cosas que puedes hacer en estos casos para que el script corra más rápido:

  1. Buscar un algoritmo más eficiente en lugar de ir número por número calculando la sumatoria de sus divisores. Por ejemplo, a simple vista, parece ser un patrón que un número perfecto es siempre mayor al doble de su inmediatamente anterior: 28 es mayor que el doble de 6, 496 es mayor que el doble de 28, etc. Sabiendo esto puedes hacer que tu código se ahorre el procesamiento de varios números y así optimizar el rendimiento en general (aunque insisto en que no puedo probar que sea realmente una propiedad de estos números).
  2. Compilar el código con Cython. Algo similar hice en este artículo: https://recursospython.com/guias-y-manuales/obtener-lista-numeros-primos/. Así tu algoritmo es ejecutado directamente por el procesador, sin el intérprete de Python de intermediario.
Saludos!
Responder
#3
Buen día.
Francisco luego que me tranquilice un poco voy a analizar con detenimiento lo que propones, estoy muy alborotado con este tema, ahora te pido un pequeño esfuerzo y favor, encontré este algoritmo y me pareció interesante solo que no logro inplementarlo, no sé dónde poner el print para mostrar los números perfectos y si estoy llamando a la función correcta. - 

Página


Código:
#!/usr/bin/env python

def getPerfect(n) : 
    return 2**(n - 1) * (2**n - 1) 
 
def isPrimal(n) : 
    for i in range(2, n) : 
         if (n % i == 0) : 
              return False 
 
    return True 
 
def getGreaterPerfectNumSmallerThan(num) : 
    for i in range(num) : 
         m = 2**i - 1 
         if (isPrimal(m)) : 
              if (getPerfect(i) > num) : 
                   return perfect 
              perfect = getPerfect(i) 
 
    return perfect 

n = 1
while n < 100000:
    getGreaterPerfectNumSmallerThan(n)
    n += 1
Saludos.
abraza las cosas y personas malas como si fueran tu mas preciada joya,Son tus mas grandes maestros de paciencia sabiduría y amor y cuando lo abrazas dejan de causar dolor.-
Responder
#4
El código al parecer está pensado para retornar únicamente un número perfecto:

  1. print(getGreaterPerfectNumSmallerThan(100000000)) # 33550336


Pero puede retocarse un poco para que retorne una lista:

  1. def getGreaterPerfectNumSmallerThan(num):
  2. for i in range(num) :
  3. m = 2**i - 1
  4. if (isPrimal(m)) :
  5. perfect = getPerfect(i)
  6. if perfect > num:
  7. return
  8. else:
  9. if i > 1:
  10. yield getPerfect(i)
  11.  
  12. # [6, 28, 496, 8128, 33550336]
  13. print(list(getGreaterPerfectNumSmallerThan(100000000)))


Incluso esta otra función derivada que no tiene ningún límite:

  1. def getPerfectNums():
  2. i = 0
  3. while True:
  4. m = 2**i - 1
  5. if (isPrimal(m)) :
  6. perfect = getPerfect(i)
  7. if i > 1:
  8. print(getPerfect(i))
  9. i += 1
  10.  
  11. getPerfectNums()


Saludos!
Responder
#5
Hola, Francisco gracias por el código.
En realidad esperaba sacar más provecho, me había entusiasmado con descubrir el octavo número perfecto pero ahora me entero que hay como 20 y unos de los últimos tiene como 26000 dígitos. -
Cuando avance un poco más voy a compilar con Cython, a ver que pasa. -
Bueno es todo, gracias y un abrazo. -
abraza las cosas y personas malas como si fueran tu mas preciada joya,Son tus mas grandes maestros de paciencia sabiduría y amor y cuando lo abrazas dejan de causar dolor.-
Responder


Salto de foro:


Usuarios navegando en este tema: 1 invitado(s)