Usando la secuencia de Bruijn para encontrar el


11

Sean Anderson publicó trucos de bit twiddling que contienen el algoritmo de Eric Cole para encontrar el de un entero de N bits v en operaciones O ( lg ( N ) ) con multiplicación y búsqueda.log2vNvO(lg(N))

El algoritmo se basa en un número "mágico" de la secuencia De Bruijn. ¿Alguien puede explicar las propiedades matemáticas fundamentales de la secuencia utilizada aquí?

uint32_t v; // find the log base 2 of 32-bit v
int r;      // result goes here

static const int MultiplyDeBruijnBitPosition[32] = 
{
  0, 9, 1, 10, 13, 21, 2, 29, 11, 14, 16, 18, 22, 25, 3, 30,
  8, 12, 20, 28, 15, 17, 24, 7, 19, 27, 23, 6, 26, 5, 4, 31
};

v |= v >> 1; // first round down to one less than a power of 2 
v |= v >> 2;
v |= v >> 4;
v |= v >> 8;
v |= v >> 16;

r = MultiplyDeBruijnBitPosition[(uint32_t)(v * 0x07C4ACDDU) >> 27];

2
2kkn2kkn

1
log2v

1
@Sasho Convertir en una respuesta?
Yuval Filmus

@SashoNikolov Gracias, agregó una función de techo a la pregunta
Yury Bayda

Respuestas:


9

log2vv32

v2log2v1

{0,1}s2kkXkk2iXii<k


3
i2ii2i11

v

5

c

  • c

    11111011100110101100010100100000
    
  • 2ici=0,1,...,31

    00000100011001010011101011011111
    00001111101110011010110001010010
    
  • (2i+11)ci=0,1,...,31

    00000111110001001010110011011101  (07C4ACDD)
    10000111110001001010110011011101
    01111000001110110101001100100011
    11111000001110110101001100100011
    

Algunas observaciones basadas en experimentos rápidos (espero haberlo hecho bien):

  1. Hay 65536 enteros de tipo X.

  2. Hay 4096 enteros de tipo X + Y. Estos son precisamente esos enteros de tipo X que comienzan con la secuencia '0000 ...'

    • intuición: con ceros a la izquierda, rotación = desplazamiento?
  3. Hay 256 enteros de tipo X + Y + Z. Estos son precisamente esos enteros de tipo X que comienzan con la secuencia '0000011111 ...'

    • intuición: ??
  4. Todos los enteros de tipo Y también son de tipo X.

  5. Sin embargo, también hay 768 enteros de tipo Z que no son del tipo X ni del tipo Y. Estos comienzan con '1000011111 ...', '0111100000 ...' o '1111100000 ...'


1
Esta es la única respuesta que trata de por qué la multiplicación de De Bruijn por 2 ^ n-1 funciona, a diferencia de 2 ^ n, que es solo un cambio. Me encantaría que alguien pudiera ampliar la "intuición" del # 3 anterior. ¿Cómo se le ocurrió a Eric Cole? ¿Prueba y error? ¿O alguna comprensión de lo que realmente les sucede a los bits cuando multiplicas por 2 ^ n-1?
FarmerBob

1
  • ¿De dónde viene esta constante?

Cita: "El 10 de diciembre de 2009, Mark Dickinson eliminó un par de operaciones al exigir que v se redondeara a una menos que la siguiente potencia de 2 en lugar de la potencia de 2". [graphics.stanford.edu/~seander/bithacks.html]

Esta constante particular es una secuencia de De Bruijn con alfabeto binario pero con una propiedad adicional. Lo llamaré la 'Propiedad de Marc Dickinson' ya que el algoritmo original podría implementarse sin estas secuencias especiales de DB. Al agregar 2 operaciones adicionales, podríamos usar cualquier secuencia DB común. Operación: v ^ = (v >> 1); // clr todos los bits excepto MSB establecido después del cambio en cascada o-shift.

  • Resultados (fuerza bruta)

Seq.Type | No. enteros | No. DBSeq. con | sin rotaciones | con Dickinson Propiedad
B (2, 3) | 256 16 2 | 1
B (2, 4) | 64Ki | 256 16 4
B (2, 5) | 04Gi | 64Ki | 02Ki | 256
B (2, 6) | 16Ei | 04Gi | 64Mi | ??

  • La propiedad especial

0x7C4ACDD 2k132 k 1 2 k 1(mod232)32k1ingrese la descripción de la imagen aquí2k - )1

  • Secuencias binarias de Bruijn lexicográficamente más pequeñas con la propiedad Dickinson

    [B (2,3): 0x1D] [B (2,4): 0x0F2D] [B (2,5): 0x7C4ACDD] [B (2,6): Todavía buscando]

Si esperaba una fórmula matemática elegante para describirlos o un teorema para producirlos o algo similar, creo que esto requeriría una comprensión profunda de la teoría de números y posiblemente otros campos que están más allá de mi conjunto de habilidades. Si tuviera que adivinar, apostaría a que podrían ser producidos por autómatas celulares. Esta no es una respuesta, ¿por qué? sobre una base rigurosa pero un intento de comprender intuitivamente por qué funciona y por qué funciona correctamente, para que pueda usarlo con confianza.

PD: No cubrí la construcción LUT, que se deduce fácilmente si entiendes los principios de funcionamiento de los algoritmos.


Finalmente encontrado: B (2,6) 0x3f08a4c6acb9dbd - una secuencia de 64 bits de bruijn con la 'propiedad dickinson'. He encontrado al menos 122K de tales secuencias.
FranG
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.