19 votos

La forma más rápida de factorizar enteros < 2^60

Llevo unos 12 meses buscando curvas de Mordell de rango >=8 y he identificado aproximadamente 280.000 curvas en nuestro rango archivable, entre muchos millones que no lo están.

Para esta búsqueda he estado utilizando hasta 60 cpus de 3Ghz+ a la vez. Ahora estoy llegando a un punto en el que el rendimiento disminuye y los requisitos de memoria aumentan considerablemente. Por lo tanto, tengo que ser un poco más inteligente en algunas de las matemáticas.

Mi pregunta es, entonces, cuál se cree (o se sabe) que es el algoritmo de factorización más rápido para enteros positivos < 2^60.

No estoy muy dispuesto a consumir más décadas de GHz de potencia de procesamiento a menos que pueda obtener un rendimiento razonable de la inversión, para lo cual un algoritmo de factorización rápido sin duda ayudaría.

Cualquier idea será más que bienvenida.

EDITAR:

Leyendo las respuestas me doy cuenta de que probablemente debería añadir que quiero mantener la factorización dentro de la aritmética de 64 bits. El algoritmo Pollard Rho era interesante, pero probablemente superaría el límite de 64 bits durante su ejecución.

Otra parte del rompecabezas es que, a partir de las factorizaciones, estoy almacenando las diferencias de pares de divisores para cada número factorizado. Esto puede, potencialmente, dejarme con una matriz de alrededor de 50.000.000 valores que luego, posteriormente, necesita ser ordenada.

He estado utilizando Pari/GP para este proyecto y, hasta ahora, ha ido genial. Mi problema actual es principalmente con el uso de memoria, ya que cada tarea de Pari/GP ocupa más de 8GByte de memoria. Esto está impidiendo que mi máquina de 32 núcleos sea tan eficiente como podría haber sido de otra manera. De ahí mi intención de pasar a la aritmética de 64 bits y al código 'C', con la esperanza de ganar eficiencia tanto en tiempo como en espacio, dando así nueva vida a un proyecto que de otro modo se estancaría.

Actualización:

Gracias a todos los que han respondido con tan buenas sugerencias sobre cómo proceder.

Al final he decidido utilizar la biblioteca flint, como sugirió William Hart, en lugar de intentar reinventar la rueda. La capacidad de flint para trabajar directamente con enteros de 64 bits me da una gran ventaja en cuanto a uso de memoria y velocidad en comparación con mi configuración actual. En particular, ahora puedo ejecutar los 32 núcleos en mi máquina principal y todavía tener memoria de sobra, potencialmente dando una mejora de 8 veces en el rendimiento de procesamiento.

Kevin.

2voto

thattolleyguy Puntos 128

Después de su edición: otro anuncio de C++ STL . El tipo de plantilla "set" se implementa como una plantilla árbol rojo/negro que clasifica en cada paso de inserción. También se trata de una asignación dinámica de memoria. Mientras tanto, el usuario crea una "clase", cada instancia será un nodo en el árbol, y el usuario define las dos relaciones == para igualdad y < para estrictamente menor que.

Como dije en un comentario, cada nodo podría tener algún número de identificación para la curva, el número que está factorizando, tal vez una factorización completa (parece que desea continuar con una curva sólo si tiene una factorización completa), y el conjunto de diferencias divisoras, tal vez implementado como otro "conjunto" si lo desea.

Esto es en gran medida opuesto a las factorizaciones difíciles: el número de divisores $d(n)$ de algún número entero positivo $n$ satisface $$ d(n) \leq n^{\left( \frac{\log 2}{\log \log n} \right) \left( 1.5379396\ldots \right)} $$ o aproximadamente $ n^{0.28596} $ hasta $2^{60}.$ Así que un número altamente compuesto superior de ese tamaño podría tener unos 146214 divisores. Oh, vaya. Bueno, esos son raros e instantáneamente factorizados.

2voto

Rasmus Faber Puntos 24195

Una buena fuente de algoritmos e implementaciones muy eficientes para este tipo de problemas es Página de Dan Bernstein . Allí He encontrado un algoritmo que puede ser útil para eliminar todos los factores primos pequeños:

Si tiene $y/(\log y)^{O(1)}\;$ enteros, cada uno con un máximo de $(\log y)^{O(1)}\;$ bits, entonces se pueden encontrar todos los factores primos pequeños de cada entero en tiempo $(\log y)^{O(1)}\;$ por número entero.

[No he mirado los detalles, así que tendrás que probarlo para ver si los números de 60 bits ya son lo suficientemente grandes].

1voto

Matt Puntos 11

Si sus números se generan siguiendo un patrón regular, podría utilizar un tamiz para encontrar rápidamente muchos factores de tamaño medio.

1voto

Nyxynyx Puntos 425

El libro de Neil Koblitz "A Course in Number Theory and Cryptography" contiene un buen estudio de los algoritmos de factorización, incluidos varios que funcionan bien en este rango de tamaño. Los métodos de curva elíptica están cubiertos (no estaban en Knuth vol 2 la última vez que miré) y podrían ser candidatos razonables.

1voto

memegame Puntos 61

Podrías probar el paquete de software MIRACL de Mike Scott, que es algo antiguo pero implementa varios algoritmos de factorización hasta el tamiz cuadrático. Parece que ahora vive aquí:

i-Ciencias.com

I-Ciencias es una comunidad de estudiantes y amantes de la ciencia en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X