Sparse matrix: The matrix of most elements in the matrix is 0, and intuitively, when the number of non-0 elements is less than 30% of the total element, such matrices are sparse matrices.
Such as:
int array [6][5] = {{1, 0, 3, 0, 5},
{0, 0, 0, 0, 0},
{0, 0, 0, 0, 0},
{1, 0, 3, 0, 5},
{0, 0, 0, 0, 0},
{0, 0, 0, 0, 0}};
Compressed storage of sparse matrices: use {row,col,value} ternary group to store each valid data, ternary group according to the position in the original matrix, in order to store the priority of the row in succession.
Transpose of the matrix: swap the rows and columns of the original matrix, that is, the data on [I][j] and [j][i] positions.
650) this.width=650; "src=" Http://s1.51cto.com/wyfs02/M00/80/6C/wKioL1dBWJ_T1ftIAACWhMc0MGo557.png "title=" capture. PNG "alt=" Wkiol1dbwj_t1ftiaacwhmc0mgo557.png "/>
Sequence increment method for sparse matrices:
In order to transpose the sequence of the ternary table A of the transpose matrix (that is, the row order of the three-tuple table B after the transpose), the three-tuple table B of the transpose matrix happens to be "the main order of the line order".
One-time positioning quick Transpose method:
In the column transpose the time waste of the algorithm is mainly in the double cycle, in order to improve the performance of the algorithm, we must remove the double loop, so that the entire transpose process through a cycle to complete.
In order for the elements in the ternary table A to be transferred to the three-tuple table B, the following data needs to be calculated:
1) rowcounts, the number of valid values for each column in the ternary table A, that is, the number of valid values for each row in the matrix ternary table B after the transpose.
2)Rowstart, the starting position of the valid values for each row in the Triples table B.
Rowstart[i] = Rowstart[i-1] + rowcounts[i-1];
Code implementation:
#include <iostream>
using namespace Std;
#include <vector>//dynamic Array
Ternary group
Template<class t>
struct Triple
{
size_t _row;
size_t _col;
T _value;
Triple (size_t row = 0, size_t col = 0, const t& value = t ())
: _row (Row)
, _col (COL)
, _value (value)
{}
};
Template<class t>
Class Sparsematrix
{
Public://invalid Non-0 value
Sparsematrix (t* a = NULL, size_t M = 0, size_t N = 0, const t& invalid = T ())
: _rowsize (M)
, _colsize (N)
, _invalid (invalid)
{
for (size_t i = 0; i < M; ++i)
{
for (size_t j = 0; j < N; ++j)
{
if (A[i*n + j]! = _invalid)//number of elements per line is the number of columns
{
Triple<t> T;
T._row = i;
T._col = j;
T._value = A[i*n + j];
_a.push_back (t);//In the vector class, insert an element
}
}
}
}
void Display ()
{
size_t index = 0;
for (size_t i = 0; i < _rowsize; ++i)
{
for (size_t j = 0; j < _colsize; ++j)
{
if (Index < _a.size () && (_a[index]._row = = i) && (_a[index]._col = = j))
{
cout << _a[index++]._value << "";
}
Else
{
cout << _invalid << "";
}
}
cout << Endl;
}
}
Matrix sequence increment transpose algorithm, time complexity is O (number of valid data * Number of columns of the original matrix)
Sparsematrix<t> Transport ()
{
sparsematrix<t> SM;
Sm._colsize = _rowsize;
Sm._rowsize = _colsize;
Sm._invalid = _invalid;
for (size_t i = 0; i < _colsize; ++i)//sequence increment
{
size_t index = 0;
while (Index < _a.size ())
{
if (_a[index]._col = = i)
{
Triple<t> T;
T._row = _a[index]._col;
T._col = _a[index]._row;
T._value = _a[index]._value;
Sm._a.push_back (t);
}
++index;
}
}
return SM;
}
One position count quick transpose time complexity is O (number of valid data + number of columns of original matrix)
Sparsematrix<t> Fasttransport ()
{
sparsematrix<t> SM;
Sm._rowsize = _colsize;
Sm._colsize = _rowsize;
Sm._invalid = _invalid;
int* rowcounts = new int[_colsize];//count
int* Rowstart = new int[_colsize];//position
memset (rowcounts, 0, sizeof (int) *_colsize);
memset (rowstart, 0, sizeof (int) *_colsize);
size_t index = 0;//index non-0 elements
while (Index < _a.size ())
{
++rowcounts[_a[index]._col];
++index;
}
for (size_t i = 1; i < _colsize; ++i)
{
Rowstart[i] = Rowstart[i-1] + rowcounts[i-1];
}
index = 0;
Sm._a.resize (_a.size ());
while (Index < sm._a.size ())
{
Triple<t> T;
T._row = _a[index]._col;
T._col = _a[index]._row;
T._value = _a[index]._value;
Sm._a[rowstart[_a[index]._col]] = t;
++rowstart[_a[index]._col];
++index;
}
Delete[] rowcounts;
Delete[] Rowstart;
return SM;
}
Protected
Vector<triple<t>> _a;
size_t _rowsize;
size_t _colsize;
T _invalid;
};
void Test ()
{
int array[5][4] =
{
{1, 0, 3, 0},
{0, 0, 0, 0},
{0, 0, 0, 0},
{2, 0, 4, 5},
{0, 0, 0, 0},
};
Sparsematrix<int> SM1 ((int*) array, 5, 4, 0);
cout << "Printing the original matrix:" <<endl;
Sm1. Display ();
cout << Endl;
cout << "Print transpose matrix:" << Endl;
sparsematrix<int> sm2 = sm1. Transport ();
/*sparsematrix<int> sm2 = sm1. Fasttransport (); */
Sm2. Display ();
}
int main ()
{
Test ();
System ("pause");
return 0;
}
Operation Result:
Print the original matrix:
1 0 3 0
0 0 0 0
0 0 0 0
2 0 4 5
0 0 0 0
Print the matrix after transpose:
1 0 0) 2 0
0 0 0) 0 0
3 0 0) 4 0
0 0 0) 5 0
Please press any key to continue ...
Comparison of two algorithms:
Assuming that the number of valid data is 100, the original matrix column number is 100, the matrix sequence increment transpose algorithm, time consumption is O (number of valid data * The number of columns of the original matrix), that is, 100*100=10000 times; a fast transpose algorithm with time complexity of O (number of valid data + number of columns of original matrix) ), that is, about 100+100=200 times. Obviously, the time efficiency of the fast transpose algorithm is much higher than the sequential increment transpose method in time performance, but it increases the space cost by two auxiliary vector space, namely rowcounts and Rowstart, Thus, the time savings of the algorithm are at the expense of more storage space.
This article is from the "Rock Owl" blog, please be sure to keep this source http://yaoyaolx.blog.51cto.com/10732111/1775877
Sequential increment method of sparse matrix and fast transpose method of one position