Pregunta: Dado un bits número natural , cómo calcular utilizando sólo adiciones y cambios (BIT)?
El consejo es utilizar la búsqueda binaria. Sin embargo, no pude lograr la complejidad requerida (obtuve ).
¿Qué quiere decir con using only $O(n)$ (bit) additions and shifts
:
Este es un ejercicio en un libro de algoritmos.
En mi opinión, significa que agregar dos, digamos -bit, números naturales cuesta y cambiar a, digamos -bit, número natural también cuesta . Entonces solo se nos permite usar tales operaciones veces.
No menciona el costo de la comparación. Supongo que podemos ignorarlo o suponer que comparar dos, digamos -bit, números naturales también cuesta .
Mi algoritmo :
- Determine el rango del número de bits de :
Por lo tanto,
t_1 \ triangleq \ lfloor \ frac {n-1} {2} \ rfloor + 1 \ le t \ le \ lceil \ frac {n} {2} \ rceil + 1 \ triangleq t_2.
- Búsqueda binaria: busque entre y utilizando la búsqueda binaria. Para cada número , para calcular usando adiciones y cambios como primitivas y compararla con .
La complejidad es, por lo tanto, para veces de búsqueda binaria y computación , cada una de las cuales toma adiciones y desplazamientos.
fuente
¿Estamos hablando enteros aquí? Donde N es n bits de largo?
El bucle se realiza n / 2 veces, lo que debería proporcionarle un rendimiento de O (n)
Editar: ¿Cómo funciona y por qué?
Esta es una versión de Aproximación sucesiva, que también se utiliza en algoritmos CORDIC.
Comenzando con el bit único más grande posible (con un cuadrado menor que N), establece un bit a la vez y calcula el nuevo cuadrado.
Si el nuevo cuadrado aún es menor que N, mantenga el bit como establecido.
Si el nuevo cuadrado es demasiado grande, borre el bit, deshaga el efecto de agregarlo y pase al siguiente bit.
Ejemplo: N = 441 (1 1011 1001 binario), n = 9
fuente
El método principal es la de rellenar los trozos de de izquierda a derecha, manteniendo nuestra estimación por debajo de ella, o más bien la plaza de nuestra estimación por debajo de . Cada bit es una potencia de 2, por lo que cuadrar o multiplicar otro número por siempre es un cambio de bit.N−−√ N b b
Si la estimación actual es , , y ya conocemos , obtenemos , y podemos reescribir los términos segundo y tercero como y . A continuación, se suma todo y prueba (supongo que puede hacer ) y establecer el bit si la plaza está todavía por debajo .a b=2i a2 (a+b)2=a2+2ab+b2 a<<(i+1) 1<<(i<<1) < i N
Comenzamos el ciclo en y hacemos cuenta regresiva a cero, manteniendo y medida que avanzamos. Es una especie de búsqueda binaria, pero una donde los límites se asignan a diferencias de un solo bit.i=n/2=n>>1 a a2
fuente
Me gusta la respuesta de Alan Campbell : con un seguimiento cuidadoso de las conjeturas anteriores, la nueva resta es fácil cada vez, y la raíz cuadrada binaria shift-and-add es casi tan rápida como una división binaria shift-and-add.
Pero puede ser posible ir más rápido, en lugar de hacer su próxima suposición con un solo dígito binario, en lugar de usar un algoritmo "Ab" x "Ab", y hacer que su próxima suposición sea el promedio de su suposición anterior, y el número original dividido por la suposición anterior. Parece que llevaría más tiempo, no más corto. Sin embargo, la división no tiene que ser exacta. Entonces, si la división solo se ejecuta en la raíz cuadrada del número de dígitos restantes para encontrar, entonces en realidad podría ahorrar tiempo. Además, si para su división usa el método francés, de división de taquigrafía, entonces podría romper algo de velocidad en su cálculo para divisiones realmente grandes.
Ahora, si agregamos cálculos en paralelo que producen resultados corregibles preliminares antes de encontrar la respuesta ... entonces podríamos estar en algo.
fuente