Data Structure-sparse matrix, data structure matrix

Source: Internet
Author: User

Data Structure-sparse matrix, data structure matrix

In general, the matrix is surrounded by square brackets, and the numbers of each coordinate are neatly arranged. As shown in:

After seeing the figure, the first response is of course represented by a two-dimensional array, which is simple and easy to understand. However, we will encounter the following matrix:

Look at this matrix. There are a lot of zeros (we call it a sparse matrix). If we use a two-dimensional array, We will store a lot of zeros repeatedly, which wastes space.

Therefore, we need to adopt a special method to store such a matrix. Here we propose an array method to store such a matrix.

Typedef struct {int row; // The row coordinate int col; // The column coordinate int value; // the value of this point} item;

Here, item indicates the midpoint of the matrix, so the description of a sparse matrix (the number of non-0 values is num) is as follows:

Use item [num + 1] to represent a matrix. For num + 1, first make a note:

The first value of the item array is in the structure of {number of rows, number of columns, number of non-zero values}. Except for the first value, other values represent the column coordinates of non-zero values in the matrix and their own values. First, let's explain the following example:

It is known that the number of non-0 values in the preceding matrix is 16-7 = 9, which is expressed by the array item test [9 + 1 ].

Array subscript (I) Row) Column (col) Value)
0 4 4 9
1 0 0 A
2 0 1 B
3 0 3 C
4 2 0 D
5 2 1 E
6 2 3 F
7 3 0 G
8 3 1 H
9 3 3 I

This method saves a lot of space, but it also brings a certain amount of trouble (mainly in matrix operations, it is not easy to understand ).

1,Matrix transpose operation

Matrix transpose: changes the row value of the Matrix to the column value and the column value to the row value. For a two-dimensional array, the subscript of the Two-dimensional array can be exchanged. Original: a [I] [j] = value; after conversion: a [j] [I] = value;

However, transpose is easy to understand for arrays, that is, to swap rows and columns.

Void transpose1 (item * a, item * B) {int col = a [0]. row; int row = a [0]. col; int value = a [0]. value; B [0]. row = row; // first fill the value of B [0] with B [0]. col = col; B [0]. value = value; int num = 1; // num indicates the array subscript of the B Matrix. Because the first value has been set, it starts from 1 for (int I = 0; I <row; I ++) // I is the row mark of B, and the layer loops through the matrix. Because j is small to large, the column mark of the B matrix is also in the same row, arranged from small to large {for (int j = 1; j <= value; j ++) // array subscript traversal from small to large {if (a [j]. col = I) // when the column mark of a matrix is equal to the row mark of B, perform the following processing: {B [num]. col = a [j]. row; // you can see from this B columns are listed under the same label and arranged from small to large. B [num]. row = I; B [num]. value = a [j]. value; num ++ ;}}}}

From the code, we can easily see that the time complexity is relatively large, because of two loops; O (row * (value); If the value is row * col, this overhead is very large.

The book provides a fast transpose method, which is briefly described as follows:

A. First, find the transpose matrix. The number of non-zero rows in each row. (Counts the number of times of col values by traversing the original array)

B. Obtain the subscript of the starting array with non-0 values in each row. (The subscript of the starting array with 0 rows is 1, the subscript of the starting array of a row is the number of the starting subscript of the 0 row + the number of non-zero values in the 0 row, which is also pushed down)

C. traverse the original array (starting from subscript 1). first obtain the subscript of the result array, marked by the column of the original array (row mark of the result array) determine the position of the current subscript of the loop in the result Array Based on step B.

Well, look at the program.

Void transpose (item * a, item * B) // a is the original matrix, and B is the transposed matrix. {Int row = a [0]. col; int col = a [0]. row; int value = a [0]. value; B [0]. row = row; B [0]. col = col; B [0]. value = value; // first count the number of non-zero rows in each row. // first, an array int * p = new int [row] that stores non-zero rows in each row. for (int I = 0; I <= row; I ++) {p [I] = 0;} for (int I = 1; I <= value; I ++) {p [a [I]. col] ++;} // calculate the start point of each row. int * start = new int [row]; start [0] = 1; for (int I = 1; I <row; I ++) {start [I] = start [I-1] + p [I-1];} for (int I = 1; I <= value; I ++) {int j = start [a [I]. col] ++; // used to obtain the array subscript. Note that the subscript shifts right to B [j]. row = a [I]. col; B [j]. col = a [I]. row; B [j]. value = a [I]. value;} delete [] start; delete [] p ;}

At this point, we have completed the transpose operation.

2. Matrix Multiplication

In the previous article, we talked about matrix multiplication, so we will not repeat it here.

For a sparse matrix, multiplication is relatively difficult to process and is not as brainless as processing a two-dimensional array. Because the number of non-zero values in the result matrix after the product cannot be directly obtained from the number of non-zero values in the two matrices. For example:

It can be seen that the processing is still complicated.

Void mult (item * a, item * B, item * result) {// detailed algorithm step for multiplying a matrix, that is, the result matrix (I, j) multiply the number of rows I in matrix a and column j in matrix B. // you can perform a conversion, it can be seen that the I row of matrix a is multiplied by the j row after the transpose of matrix B. // The result is as follows: the number of columns in matrix a corresponds to the number of columns in the matrix after matrix B is transposed. // first, the right matrix is transposed. int a_row = a [0]. row, a_col = a [0]. col, a_value = a [0]. value; int B _row = B [0]. row, B _col = B [0]. col, B _value = B [0]. value; if (a_col! = B _row) {std: cout <"error"; return ;} // transpose matrix with a c matrix of B // first obtain the maximum length of the result matrix item * c = new item [B _value + 1]; transpose (B, c ); // The row described below indicates the row mark of the result array, and col indicates that the column mark of the result array is int row = a [1]. row; // The row mark row of the result matrix must be int col = 0 from here; // The column label col is temporarily set to 0 // _ begin to mark the initial position of the row. Int _ begin = 1; // For example, when the previous row is processed, the row before array a does not make sense for subsequent calculations, here _ begin is used to record the row + 1 row position of array a, and int sum, num = 1; // result array stored by sum (row, col) value. num is used to store the subscript of the result array for (int I = 1; I <= a_value;) // traverses from array a 1, until the end of array a {col = c [1]. row; // Since c is the transpose matrix of array B, its row mark is the column label col of the result array, which is known by the multiplication property of the matrix. Each col is derived from c [1]. the row starts, so you need to reset it at the beginning of each loop. Sum = 0; for (int j = 1; j <= B _value + 1;) // here value + 1 is used to cope with this situation: array a is not completely traversed, the j value has already passed the subscript of c, and the effect of j ++ leads to exceeding the range of the c array and may cross the border, the first if action below is to handle this situation {if (j> B _value) // j value has exceeded B _value, which means the array has been completely traversed, it indicates that the row value of the current row has been completely found. {Result [num]. row = row; // in this case, we can enter the sum of the previous records into the result array, and Add 1 result [num] To the subscript num. col = col; result [num]. value = sum; num ++; break; // all non-0 values of the current row have been found, you can skip this loop.} if (I> a_value | a [I]. row! = Row) // 1. At this time, the row of matrix a has been iterated, and no value can be calculated. 2. The current row has been iterated. If the iteration continues, the row value changes, {result [num]. row = row; // you can store the sum value in the result array, and add the subscript num to the result array. result [num]. col = col; result [num]. value = sum; num ++; I = _ begin; // to calculate the next (next col value) non-zero value of the current row, I want to start traversing for (; j <= B _value & c [j]. row = col; j ++); // mainly used to traverse all rows whose current value is col without any other processing, then enter the next col value if (j> B _value) break; // The value of j may be larger than that of B _value, so it is necessary to jump out of the loop. Col = c [j]. row; // set the column value to the next col value} else if (c [j]. row! = Col) // because the row in the c array represents the column value of the result value, this condition indicates that the current column value is different from the row value in the c array, this means that the column value of the result array should be moved down. {Result [num]. row = row; // The processing method is similar to the preceding result [num]. col = col; result [num]. value = sum; num ++; I = _ begin; col = c [j]. row;} else if (a [I]. col <c [j]. col) // the following three conditions are well understood. {I ++;} else if (a [I]. col = c [j]. col) {sum + = a [I ++]. value * c [j ++]. value;} else if (a [I]. col> c [j]. col) {j ++ ;}}for (; I <= a_value & a [I]. row = row; I ++); // uses recursion to iterate the current row until the next row value is performed. If (I> a_value) // if the I value exceeds the maximum value, all rows have been calculated. Break; // terminate the loop row = a [I]. row; _ begin = I; // write down the start subscript corresponding to the row at the same time.} Result [0]. row = a_row; result [0]. col = B _col; result [0]. value = num-1; delete [] c ;}

If you are free, the image will be drawn to help you understand it.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.