Data Structure-Sparse Matrix

Source: Internet
Author: User

Data Structure-Sparse Matrix
In general, the matrix is surrounded by square brackets, and the numbers of each coordinate are neatly arranged. As shown in: After clip_image001 is displayed, the first response is expressed by a two-dimensional array, which is simple and easy to understand. But we will encounter the matrix shown in the following figure: clip_image001 [8]. Look at this matrix. There are a lot of zeros (we call it a sparse matrix). If we use a two-dimensional array, it 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. Copy the code typedef struct {int row; // The line coordinate int col; // The column coordinate int value; // the value of this point} item; copy the code here the item indicates the matrix midpoint, 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. Why num + 1 is required first: 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 look at the last small example. clip_image001 [10] We know that the number of non-0 values in the preceding matrix is 16-7 = 9; use the array item test [9 + 1] to represent the array subscript (I) row (row) Column (col) value (value) 0 4 4 91 0 0 a2 0 1 b3 0 3 c4 2 0 d5 2 1 e6 2 3 f7 3 0 g8 3 1 h9 3 3 I am stored in this way, it 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 matrix row value 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, the columns will be exchanged. Copy the code 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; // from It can be seen that the column of B is listed under the same label and arranged from small to large. B [num]. row = I; B [num]. value = a [j]. value; num ++ ;}}} copy the code from the code, we can easily see that the time complexity is relatively large, because of two-layer 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, and the number of non-zero rows in each row. (Calculate the number of times of col values by traversing the original array) B. Obtain the subscript of the starting array with non-zero values in each row. (The subscript of the starting array with zero rows is 1, the subscript of the starting array of a row is the number of non-zero values in 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. The column mark (row mark of the result array) of the original array determines the position of the current subscript of the loop in the result Array Based on step B. Well, look at the program. Copy the code 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 = star T [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;} copy the code here, And the transpose operation is completed. 2. In the previous article, we talked about Matrix Multiplication. Here we will not repeat it here. For sparse matrices, multiplication is comparatively difficult to process, it is not as brainless as 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, clip_image001 [12] shows that the processing is still complicated. Copy the code void mult (item * a, item * B, item * result) {// detailed algorithm step of matrix multiplication, 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 ;}

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.