¿Cuál es el mejor enfoque para calcular el factor primo más grande de un número?
Estoy pensando que lo más eficiente sería lo siguiente:
- Encuentra el número primo más bajo que se divide limpiamente
- Compruebe si el resultado de la división es primo
- Si no, encuentre el siguiente más bajo
- Ir a 2.
Estoy basando esta suposición en que es más fácil calcular los factores primos pequeños. ¿Es esto correcto? ¿Qué otros enfoques debería considerar?
Editar: ahora me he dado cuenta de que mi enfoque es inútil si hay más de 2 factores primos en juego, ya que el paso 2 falla cuando el resultado es producto de otros dos números primos, por lo tanto, se necesita un algoritmo recursivo.
Edite nuevamente: Y ahora me he dado cuenta de que esto todavía funciona, porque el último número primo encontrado tiene que ser el más alto, por lo tanto, cualquier prueba adicional del resultado no primo del paso 2 daría como resultado un primo menor.
fuente
1.
encuentre cualquier número que se divida claramente (para i = 2 a int (sqr (num)))2.
divida por ese número (num = num / i) y repita hasta que no se encuentre nada en el intervalo de 1.3.
num es el factor más importanteRespuestas:
En realidad, hay varias formas más eficientes de encontrar factores de números grandes (para los más pequeños, la división de prueba funciona razonablemente bien).
Un método que es muy rápido si el número de entrada tiene dos factores muy cercanos a su raíz cuadrada se conoce como factorización de Fermat . Utiliza la identidad N = (a + b) (a - b) = a ^ 2 - b ^ 2 y es fácil de entender e implementar. Lamentablemente no es muy rápido en general.
El método más conocido para factorizar números de hasta 100 dígitos es el tamiz cuadrático . Como beneficio adicional, parte del algoritmo se realiza fácilmente con procesamiento paralelo.
Otro algoritmo del que he oído hablar es el algoritmo Rho de Pollard . No es tan eficiente como el tamiz cuadrático en general, pero parece ser más fácil de implementar.
Una vez que haya decidido cómo dividir un número en dos factores, aquí está el algoritmo más rápido que se me ocurre para encontrar el factor primo más grande de un número:
Cree una cola prioritaria que inicialmente almacena el número en sí. En cada iteración, elimina el número más alto de la cola e intenta dividirlo en dos factores (por supuesto, no permite que 1 sea uno de esos factores). Si este paso falla, ¡el número es primo y usted tiene su respuesta! De lo contrario, agrega los dos factores a la cola y repite.
fuente
Aquí está el mejor algoritmo que conozco (en Python)
El método anterior se ejecuta en
O(n)
el peor de los casos (cuando la entrada es un número primo).EDITAR: a
continuación se muestra la
O(sqrt(n))
versión, como se sugiere en el comentario. Aquí está el código, una vez más.fuente
O(sqrt(n))
el peor de los casos" - No, corre enO(n)
el peor de los casos (por ejemplo, cuandon
es primo)Mi respuesta se basa en el tríptico , pero mejora mucho. Se basa en el hecho de que más allá de 2 y 3, todos los números primos tienen la forma 6n-1 o 6n + 1.
Recientemente escribí un artículo de blog explicando cómo funciona este algoritmo.
Me atrevería a decir que un método en el que no hay necesidad de una prueba de primalidad (y sin construcción de tamiz) funcionaría más rápido que uno que los use. Si ese es el caso, este es probablemente el algoritmo más rápido aquí.
fuente
while (multOfSix - 1 <= n)
Código JavaScript:
Ejemplo de uso:
Aquí hay un ejemplo del código :
fuente
Similar a la respuesta de @Triptych pero también diferente. En este ejemplo, no se usa la lista o diccionario. El código está escrito en Ruby.
fuente
Todos los números se pueden expresar como el producto de primos, por ejemplo:
Puede encontrarlos simplemente comenzando en 2 y simplemente dividiendo hasta que el resultado no sea un múltiplo de su número:
usando este método no tiene que calcular ningún primo: todos serán primos, basados en el hecho de que ya ha factorizado el número tanto como sea posible con todos los números anteriores.
fuente
currFactor = 3513642
, sabemos que 12345678987667 es primo y debería devolverlo como respuesta. En cambio, este código continuará la enumeración hasta 12345678987667 en sí. Eso es 3,513,642x más lento de lo necesario.fuente
while
ciclo pasará pori
valores de2,2,2,2,2,2,2,2,2,2,2,2, 2,3,4,5, 2,3,4,5, 2,3,4,5, 2,3,4,5, 2,3,4,5, 2,3,4,5, 2,3,4,5, 2,3,4,5, 2,3,4,5, 2,3,4,5, 2,3,4,5, 2,3,4,5
. Todas las 60 iteraciones. Pero para (10 ^ 12 + 39) habrá (10 ^ 12 + 38) iteraciones,i=2,3,4,5,6,...,10^12+39
. Incluso si 10 ^ 10 operaciones toman un segundo, 10 ^ 12 tomarán 100 segundos. Pero solo se necesitan 10 ^ 6 iteraciones, y si 10 ^ 10 operaciones toman un segundo, 10 ^ 6 tomarían 1/10 000 de segundo.long n = 2*1000000000039L
? ¿Funciona tan rápido como debería? (también, ¿puede simplificar su código usando unareturn;
declaración?). (si quieres que deje de empujarte, solo dilo;))La solución más simple es un par de funciones recursivas mutuamente .
La primera función genera todos los números primos:
La segunda función devuelve los factores primos de un número dado
n
en orden creciente.n
.El factor primo más grande de
n
es el último número dado por la segunda función.Este algoritmo requiere una lista perezosa o un lenguaje (o estructura de datos) con semántica llamada por necesidad .
Para aclarar, aquí hay una implementación (ineficiente) de lo anterior en Haskell:
Hacer esto más rápido es solo una cuestión de ser más inteligente para detectar qué números son primos y / o factores
n
, pero el algoritmo sigue siendo el mismo.fuente
Hay algunas pruebas de módulo que son superfluas, ya que n nunca se puede dividir por 6 si se han eliminado todos los factores 2 y 3. Solo podría permitir primos para i, que se muestra en varias otras respuestas aquí.
En realidad, podría entrelazar el tamiz de Eratóstenes aquí:
También vea esta pregunta .
fuente
Soy consciente de que esta no es una solución rápida. Publicar como es de esperar una solución lenta más fácil de entender.
fuente
Enfoque iterativo de Python eliminando todos los factores primos del número
fuente
Estoy usando un algoritmo que continúa dividiendo el número por su factor primo actual.
Mi solución en python 3:
Entrada:
10
Salida:5
Entrada:
600851475143
Salida:6857
fuente
Aquí está mi intento en c #. La última impresión es el factor primo más grande del número. Lo comprobé y funciona.
fuente
fuente
Calcula el factor primo más grande de un número usando la recursividad en C ++. El funcionamiento del código se explica a continuación:
fuente
Aquí está mi enfoque para calcular rápidamente el factor primo más grande. Se basa en el hecho de que modificado
x
no contiene factores no primos. Para lograr eso, dividimosx
tan pronto como se encuentra un factor. Entonces, lo único que queda es devolver el factor más grande. Ya sería primo.El código (Haskell):
fuente
El siguiente algoritmo de C ++ no es el mejor, pero funciona para números de menos de mil millones y es bastante rápido
fuente
Encontré esta solución en la web por "James Wang"
fuente
Factor primo utilizando tamiz:
fuente
Me parece que el paso # 2 del algoritmo dado no será un enfoque tan eficiente. No tienes expectativas razonables de que sea primo.
Además, la respuesta anterior que sugiere el Tamiz de Eratóstenes es totalmente errónea. Acabo de escribir dos programas para factorizar 123456789. Uno se basó en el Tamiz, el otro se basó en lo siguiente:
Esta versión fue 90 veces más rápida que la Sieve.
La cuestión es que, en los procesadores modernos, el tipo de operación importa mucho menos que el número de operaciones, sin mencionar que el algoritmo anterior puede ejecutarse en caché, el Sieve no. El tamiz utiliza muchas operaciones eliminando todos los números compuestos.
Tenga en cuenta, también, que mis factores de división a medida que se identifican reducen el espacio que debe probarse.
fuente
Calcule primero una lista que almacena números primos, por ejemplo, 2 3 5 7 11 13 ...
Cada vez que factoriza un número primo, use la implementación por Triptych pero iterando esta lista de números primos en lugar de enteros naturales.
fuente
Con Java:
Para
int
valores:Para
long
valores:fuente
Probablemente esto no siempre sea más rápido, pero es más optimista acerca de que encuentre un gran divisor principal:
N
es tu numeroreturn(N)
Sqrt(N)
N is divisible by Prime
entoncesReturn(Prime)
Editar: en el paso 3 puedes usar el Tamiz de Eratóstenes o el Tamiz de Atkins o lo que quieras, pero por sí mismo el tamiz no te encontrará el factor primo más grande. (Es por eso que no elegiría la publicación de SQLMenace como respuesta oficial ...)
fuente
Creo que sería bueno almacenar en algún lugar todos los números primos posibles más pequeños que ny e iterar a través de ellos para encontrar el mayor divisor. Puede obtener primos de prime-numbers.org .
Por supuesto, supongo que su número no es demasiado grande :)
fuente
¡No es el más rápido pero funciona!
fuente
Aquí está la misma función @ Triptych proporcionada como generador, que también se ha simplificado ligeramente.
el máximo primo se puede encontrar usando:
y una lista de factores encontrados usando:
fuente
fuente