algorithm - Algoritmo O(log log n) para determinar si n es cuadrado perfecto
numbers big-o (1)
¿Hay algún algoritmo O (log b) publicado para determinar si un número b-bit es cuadrado de un entero?
(Me disculpo si esta pregunta está más allá del alcance de este sitio y me gustaría recuperarla si es así)
Actualización: me doy cuenta de que mi pregunta tal como se plantea no es razonable. Así que permítanme enmendarlo preguntando por cualquier algoritmo que sea operaciones sub-polinómicas en b. No necesariamente O (log ^ kb) para una constante k, y tiene una complejidad de espacio "razonable". Las operaciones se definen en el sentido habitual: algo que es razonable para la tarea en cuestión (por ejemplo, agregar, negar, xor, y, o, etc.)
Post script : ahora me doy cuenta de que mi pregunta no tiene sentido. El costo de calcular la raíz cuadrada del piso de un número de n bits es menor que la multiplicación de dos números de n bits.
- si
b
es lo suficientemente pequeño, entonces con el uso de la tablasqrt
es la complejidadO(1)
- si no, entonces con el uso de la aproximación de bit es la complejidad
O(b/2) = O(log n)
con el uso de la tabla cuadrada perfecta es la complejidad también
O(b/2) = O(log n)
pero con operaciones mucho más rápidas (solo comparar y operaciones de bits) el número de bit
b
puede ser un cuadrado perfecto de número máximo deb/2
bits, por lo que la tabla tiene2^(b/2)
entradas de números de bitb
y búsqueda aproximada de índice (similar a búsqueda binaria) tomab/2
pasosse puede hacer algo de mejora con la aproximación
crear la función approx
y=approx_sqrt(x);
y cómpralo Ahora puedes simplemente verificar los valores de< yc , y+c >
que tienen tiempo de ejecución~T(2c)
dondec
es constante dependiendo de la precisión de aproximación(1,2,3,...)
. La mayoría de las aproximaciones están desactivadas en los valores más grandes para que pueda hacerc=log(b)
y su complejidad sea repentinamenteO(log b) = O(log log n)
que es lo que está buscando, creo.
[Editar]
mucho después del voto negativo, descubrí que esa marca oculta parte de mi texto
Asumir algún formato o lo que sea por
< interval >
así que agregué algunos espacios para des-ocultarlo y también encontré que la viñeta # 5 estaba mal, así que la eliminé. Si esa fue la razón del voto negativo, no gracias por ello, lo pasé por alto ... hace poco estaba haciendo algo con primos ... para que mi cerebro lo copie allí sin pensarlo a fondocomo usualmente sin el código y la página de Wiki hay algunos de ustedes que no creen y simplemente votan a la baja así que aquí está mi implementación probada de lo de arriba:
//--------------------------------------------------------------------------- int is_square(int x,int &cnt) // return sqrt(x) if perfect or 0, cnt = num of cycles ~ runtime { int y,yy; // y=aprox_sqrt(x) for (y=x,yy=x;yy;y>>=1,yy>>=2); // halves the bit count if (y) y=(y+(x/y))>>1; // babylonian approximation if (y) y=(y+(x/y))>>1; if (y) y=(y+(x/y))>>1; // check estimated y and near values cnt=1; yy=y*y; if (yy==x) return y; if (yy<x) for (;;) { cnt++; y++; yy=y*y; if (yy==x) return y; if (yy> x) return 0; } else for (;;) { cnt++; y--; yy=y*y; if (yy==x) return y; if (yy< x) return 0; } } //---------------------------------------------------------------------------
Le agregué cnt para que pueda probar la complejidad usted mismo. Mi uso aproximado necesita un buen valor de inicio, así que utilizo la mitad del conteo de bits que obviamente es
O(log b)
pero para los puntosfloat
y los valoresfloat
el recuento de exponentes / bits ya es conocido, así que convierte solo a bit / palabra / base / exponente desplazarO(1)
. Por cierto, esa es la magia flotante IEEE hecha por la mayoría de las aproximaciones para funcionessqrt
olog
.Mis medidas son mejores que mis primeras estimaciones (incluso para la aproximación babilónica no precisa):
/*---------------- | N | T | ------------------ | 1000000000 | 6 | | 100000000 | 4 | | 10000000 | 2 | | 1000000 | 2 | ----------------*/
donde
N
es el bucleN
en el que se probó.T
es el valor máximo decnt
en los números probados< 0,N >
para una aproximación diferente (más adecuada para sus necesidades) puede mirar aquí
Entonces mi respuesta a su pregunta es SÍ , existe un algoritmo más rápido que O(log n)
para determinar si n
es el cuadrado perfecto (por ejemplo, el mío arriba que también calcula el sqrt
) pero si también está contando la complejidad de las funciones básicas que ¡Me temo que la respuesta es NO porque incluso las operaciones de bits son O(log n)
en bignums!
Por cierto, la búsqueda binaria sqrt
se puede hacer también sin multiplicación .
Espero eso ayude.