[Principio de estructura de datos] Matriz dispersa - LA MATRIZ ESPERA

contenido

Matriz dispersa (LA MATRIZ DISPERSA)

0x00 ADT

 0x01 ADT - matriz dispersa

0x02 Representación de matriz dispersa

0x03 Transpose of Matrix - Transposición de una matriz

0x04 multiplicación de matrices


Matriz dispersa (LA MATRIZ DISPERSA)

0x00 ADT

Matriz dispersa: si A el número de elementos distintos de cero en la matriz es mucho menor que el número de elementos cero, lo A llamamos matriz dispersa

Si usa un arreglo 2D para representar una matriz dispersa, usará mucho espacio para almacenar el mismo valor (0), no solo eso, cuando la matriz es grande, esta implementación no funciona, porque la mayoría de los compiladores lo hacen. not Las matrices tienen un tamaño limitado.

 0x01 ADT - matriz dispersa

0x02 Representación de matriz dispersa

Podemos representar de forma única cualquier elemento en la matriz, y podemos usar fila, columna, valor para almacenar y ubicar elementos distintos de cero en una matriz dispersa. Esta forma de almacenar una matriz dispersa se llama triple.

by a triple <row, col, value>.

Organizamos las tripletas para que los índices de fila estén en orden ascendente, y dentro de las tripletas con los mismos índices de fila, estén en orden ascendente de índices de columna.

Para asegurarnos de que la operación pueda detenerse, debemos saber el número de filas y columnas, y el número de elementos distintos de cero en la matriz.

// Sparse_Matrix Create(max_row, max_col) ::=

#define Max_TERMS 101 /* maximum number of terms +1*/
typedef struct {
    int col;
    int row;
    int value;
} term;
term a[MAX_TERMS];

0x03 Transpose of Matrix - Transposición de una matriz

<un algoritmo simple>

por cada fila I

        toma el elemento  <i,j,valor> y guárdalo

        como un elemento transpuesto <j,i,valor> 

No sabremos exactamente qué elemento está en la transposición hasta que hayamos procesado todos los elementos anteriores. <j,i,valor>

Dónde se coloca, como:

 Se requieren inserciones consecutivas. Tenemos que mover los elementos para mantener el orden correcto.

Podemos evitar este movimiento de datos utilizando el índice de la columna para determinar la posición del elemento en la matriz.

Para  j todos los elementos en columna, coloque los elementos  <i,j,valor> en elementos  <j,i,valor>.

[Programa 2.8]

complejidad del tiempo:  O(columnas\cdot elementos)

Si   elementos = O(filas\columnas cdot), O(columnas\cdot elementos) se convierte en  O(filas\columnas cdot^2).

 Un algoritmo de transposición que utiliza una representación densa

for (j = 0; j < columns; j++)
    for (i = 0; i < rows; i++)
        b[j][i] = a[i][j];

complejidad del tiempo:O(filas\cdot columnas)

Mejores algoritmos usando un poco más de espacio de almacenamiento

fast_transpose

El algoritmo primero determina el número de elementos en cada columna de la matriz original.

Este número da el número de elementos en cada fila de la matriz transpuesta.

complejidad del tiempo:O(filas\cdot elementos)

si  elementos = O(filas\columnas cdot) ,

entonces  O(columnas+elementos) se convierte O(filas\cdot columnas)

Se utilizan matrices adicionales, terminos_de_fila y pos_inicial.

Si colocamos la posición inicial en el espacio utilizado por row_terms, podemos reducir el espacio a una matriz.

0x04 Multiplicación de matrices

Dadas dos sumas de matrices  A ,  Bdonde  A es  Minnesota y B es notario público

La matriz del producto  D es  m*p, y sus  <yo, j> elementos son:

d_ {i, j} = \ suma_ {k = 0} ^ {n-1} \, \, a_ {ik} \, \, b_ {kj}        0\geq i< metro, \, \, 0\leq j< pag

<Algoritmo de multiplicación de matrices usando notación densa>

for (i = 0; i < rows_a; i++) {
    for (j = 0; j < cols_b; j++) {
        sum = 0;
        for (k = 0; k < cols_a; k++)
            sum += a[i][k]*b[k][j];
        d[i][j] = sum;
    }
}

complejidad del tiempo: O(filas\, a \cdot cols\, a\cdot cols\, b)

Tenga en cuenta que es posible que el producto de dos matrices dispersas ya no lo sea. P.ej:

[Programa 2.10]

Las matrices  ABD se almacenan por separado en matrices  abd y B la transposición se almacena en new_b.

Usar variables variables:

row - 目前正在与B的列相乘的A的行
row_begin - 当前行的第一个元素在a中的位置
column - 目前正在与A的某一行相乘的B的列
totald - 乘积矩阵D的当前元素数
i, j - 用于连续检查A行和B列中的元素的指针
void mmult(term a[], term b[], term d[])
/* multiply two sparse matrices */
{
    int i, j, column, totalb = b[0].value, totald = 0;
    int rows_a = a[0].row, cols_a = a[0].col, totala = a[0].value;
    int cols_b = b[0].col;
    int row_begin = 1, row = a[1].row, sum = 0;

    term new_b[MAX_TERMS];
    if (col_a != b[0].row) {
        fprintf(stderr, “Incompatible matrices\n”);
        exit(1);
    }
    fast_transpose(b, new_b);
    /* set boundary condition */
    a[totala+1].row = rows_a;
    new_b[totalb+1].row = cols_b; new_b[totalb+1].col = -1;
   
    for (i = 1; i <= totala; ) {
        column = new_b[1].row;
        for (j = 1; j <= totalb+1; ) {
        /* multiply row of a by column of b */
            if (a[i].row != row) {
                storesum(d, &totald, row, column, &sum);
                i = row_begin;
                for ( ; new_b[j].row == column; j++)
                                ;
                column = new_b[j].row;
            }
            else if (new_b[j].row != column) {
                storesum(d, &totald, row, column, &sum);
                i = row_begin;
                column = new_b[j].row;
            }
            else switch (COMPARE(a[i].col, new_b[j].col)) {
                case –1 : /* go to next term in a */
                    i++; break;
                case 0 : /* add terms, go to next term in a and b */
                    sum += (a[i++].value * new_b[j++].value);
                    break;
                case 1 : /* go to next term in b */
                    j++;
            }
        } /* end of for j <= totalb+1 */
        for ( ; a[i].row == row; i++)
                ;
        row_begin = i; row = a[i].row;
    } /* end of for i <= totala */
    d[0].row = row_a; d[0].col = cols_b;
    d[0].value = totald;
}

Tenga en cuenta que introducimos un elemento adicional tanto en a como en new_b:

a[totala+1].row = rows_a;
new_b[totalb+1].row = cols_b;
new_b[totalb+1].col = -1;

complejidad del tiempo

Antes del bucle for:

fast transpose - O(cols_b + totalb) time.

El bucle for externo se itera filas_a veces:

En cada iteración, el bucle for interno calcula una fila de la matriz de productos D; en cada iteración, i o j se incrementan en 1, o i se restablece a row_begin

El incremento total máximo de j es totalb+1. Luego, cuando se procesa la k-ésima fila, i puede incrementarse como máximo varias veces, y se restablece a cols_b veces de row_begin como máximo. Por lo tanto, el incremento total máximo de i es cols_b-. El bucle for interno toma O(coles_b- + totalb) tiempo y las columnas se restablecen. Por lo tanto, el bucle for externo debe

\sum_{k=0}^{filas_a-1}O(cols_b\cdot r_k+totalb)

= O(cols_b\cdot \sum_{k=0}^{rows_a-1}r_k+rows_a\cdot totalb)

= O(cols_b\cdot totala+rows_a\cdot totalb)

Vale la pena señalar que si  totala = O(filas_a\cdot cols_a) y  totalb = O(filas_b\cdot cols_b) , entonces su complejidad temporal se convierte en  O(filas_a\cdot cols_a\cdot cols_b) .

Supongo que te gusta

Origin blog.csdn.net/weixin_50502862/article/details/123682726
Recomendado
Clasificación