¿Cuál es la forma más eficiente de representar una matriz binaria dispersa?

Si el número de bits es fijo y pequeño, puede usar un sistema de número combinatorio, que produce un número natural correspondiente a cada elección de bits. En este sistema, si el número de bits establecido es 3, entonces la representación para bits en posiciones de índice cero [matemática] x_3> x_2> x_1 [/ matemática] es [matemática] {x_3 \ elegir 3} + {x_2 \ elegir 2} + {x_1 \ elegir 1} [/ matemáticas]. El valor máximo requerido para una matriz de tamaño 50 es [matemática] {49 \ elige 3} + {48 \ elige 2} + {47 \ elige 1} = 19599 [/ matemática], que puede representarse en solo 15 bits. Eso es lo mejor que puede hacer para representar las posibilidades [matemáticas] {50 \ elegir 3} [/ matemáticas] si todas son igualmente probables.

¿Qué pasa si el número de bits es variable pero limitado? Una opción es codificar el número de bits establecido, seguido de la representación del sistema de números combinatorios de esos bits.

Otra es extender la matriz con algunas posiciones “scratch”. Por ejemplo, si necesitamos acomodar en cualquier lugar entre 1 y 10 bits, pretenda que tenemos una matriz de 59 elementos en su lugar, y configure los bits 51 a 59 para que el número total de bits sea 10. Entonces, el número máximo que necesitamos almacenar es 61,440,330,665, que toma 36 bits. Esta sigue siendo una representación de longitud fija que, dependiendo de su aplicación, puede ser positiva.

(Sin embargo, ya no se garantiza que ninguna de estas representaciones sea óptima, depende de los tamaños exactos, en algún momento tiene sentido representar directamente el vector de bits).

También puede tener un mecanismo de escape para manejar ocasionalmente un mayor número de bits. El sistema de números combinatorios generalmente no completará el número exacto de bits requeridos, por lo que un número mayor como [math] 2 ^ {36} -1 [/ math] podría significar “interpretar el resto de este valor de longitud variable como un máscara de bits “, ¡a costa de usar 86 bits en este caso en lugar de solo 50! Por lo tanto, podría ser mejor, si necesita manejar esta situación, tener un “bit de tipo” donde 1 = representación combinatoria y 0 = representación de máscara de bits.

Depende de lo pocos que haya. Si hay 8 o menos, puede representarlos con 8 conjuntos de 6 bits donde cada conjunto representa el índice del bit activado (eso suena divertido).

Otra opción es comenzar con el conjunto de tamaño 6 para definir la posición del primer bit activado (imagine ir de izquierda a derecha y encontrará el primer bit distinto de cero a la derecha). Si este bit está en el índice, digamos 22, puede ver que la capacidad de la derecha ahora será 50 – 22 = 28. Para obtener el número hasta 28 no necesita 6 bits … 5 bits son suficientes. Ahora puede resolver el mismo problema solo en un tamaño más pequeño, lo único que debe hacer es agregar al siguiente bit a la derecha, la suma de índices de 1s que ya visitó a la izquierda. Entonces, por ejemplo, si tuviera el siguiente en la posición 9, su posición real sería 22 + 9 = 31.

Estos métodos no le garantizan que podrá describirlo con menos bits.

Si los 1 en su matriz se inclinan hacia el lado izquierdo o derecho, esto podría ser útil.

Depende de para qué lo quieras. En cuanto al uso estándar de estructura de datos, el tamaño del orden de 50 bits se ajusta a una palabra de máquina estándar (o dos palabras en una máquina antigua). Eso me parece muy eficiente, y también simple y relativamente rápido de consultar / modificar.

OTOH, si el propósito es la compresión sin necesidad de operaciones rápidas de estructura de datos, puede usar cosas como la codificación Entropy. De manera similar a lo anterior, uno puede crear varios híbridos con compensaciones intermedias.

Puede usar la codificación de longitud de ejecución – Codificación de longitud de ejecución