文件名字 | 用途 |
---|---|
CmakeList.txt | cmake文件 |
how.md | 简述思路以及其他说明 |
main.cpp | 主测试程序 |
SpMtx.cpp | 核心实现文件 |
SpMtx.h | 核心头文件 |
# 稀疏矩阵
- 是指在矩阵中,大部分元素都为零的情况,而只有少数非零元素。对于这种情况,为了节省存储空间,可以采用三元组表示法。
- 三元组表示法是指用三个数组来表示稀疏矩阵,分别存储非零元素的行、列坐标以及对应的值。
- 具体来说,假设一个 m × n 的稀疏矩阵中有 k 个非零元素,那么可以定义三个长度为 k 的数组:
row_idx:存储非零元素的行坐标;
col_idx:存储非零元素的列坐标;
value:存储非零元素的值
# 相关术语
#### 稀疏性(Sparsity):指矩阵中零元素的数量与元素总数的比值,用来衡量矩阵的稀疏程度。
#### 三元组压缩存储,如下理解
// 矩阵
0 0 0 0 0
0 0 2 0 0
0 1 0 0 0
0 0 0 3 0
0 0 0 0 0
// 表示
(2, 2, 2)
(3, 2, 1)
(4, 4, 3)
// 其中第一个三元组表示第二行第二列的元素为2,
// 第二个三元组表示第三行第二列的元素为1,
// 第三个三元组表示第四行第四列的元素为3。
#### 也可以这么表示 : 创建三个数组,分明别用来保存行、列、值
* 本文是基于三元组实现的方法
//
// Created by 20281 on 2023/5/5.
//
#include "SpMtx.h"
// vectors参数传入的是rows个数组,每个数组至少有cols个元素
SpMtx::SpMtx(int _rows, int _cols, Element** vectors) {
rows = _rows;
cols = _cols;
length = 0;
nodes = new Tuple [rows * cols];
// length属性仅代表非0元素或者说nodes长度
for (int r=0;r<rows;r++){
for (int c=0;c<cols;c++){
if (vectors[r][c] != .0){
nodes[length] = Tuple {r, c, vectors[r][c]};
++length;
}
}
}
}
SpMtx::~SpMtx() {
delete[] nodes;
}
void SpMtx::printTuples() {
cout << "\t===============当前稀疏组==============" <<endl;
for (int i=0;i<length;i++){
cout << "\t( " << nodes[i].row << ", " << nodes[i].col << ", " << nodes[i].value << " )";
NEWLINE
}
cout << "\tOrigin-Shape is " << " ( " << rows << ", " << cols << " )" <<endl;
cout << "\t=========================================" << endl;
}
void SpMtx::printMatrix() {
cout << "\t===============当前稀疏矩阵==============" <<endl;
int _count = 0;
for (int r=0;r<rows;r++){
cout << "\t[ ";
for (int c=0;c<cols;c++){
if (nodes[_count].col == c && nodes[_count].row == r){
cout << nodes[_count].value << " ";
++_count;
}else{
cout << 0 << " ";
}
}
cout << " ]\n";
}
cout << "\tOrigin-Shape is " << " ( " <<rows << ", " << cols << " )" <<endl;
cout << "\t=========================================" << endl;
}
Element SpMtx::getSparsity() const{
return (Element)length / (rows * cols);
}
//
// Created by 20281 on 2023/5/5.
//
#ifndef SPARSEMATRIX_SPMTX_H
#define SPARSEMATRIX_SPMTX_H
#include "iostream"
#include "iomanip"
using namespace std;
typedef double Element;
// 帮助我快速换行
#define NEWLINE cout << endl;
// 以下是稀疏矩阵两种不同的存储形式
// 使用三元组表示每个点
typedef struct _Tuple {
int row;
int col;
Element value;
} Tuple;
class SpMtx {
private:
Tuple * nodes;
int rows;
int cols;
public:
int length;
// methods
explicit SpMtx(int _rows, int _cols, Element **vectors);
~SpMtx();
// 以三元组呈现,另外打印形状
void printTuples();
// 以矩阵呈现,另外打印形状
void printMatrix();
// 输出稀疏度
Element getSparsity() const;
};
#endif //SPARSEMATRIX_SPMTX_H
//
// Created by 20281 on 2023/5/5.
//
#include "SpMtx.h"
int main(){
// 8个非0值
Element base_datas[4][8] = {
{0, 0, 0, 0, 0, 0, 2, 0},
{.2, 0, 0, 3, 0, 5, .1, 0},
{0, 0, 0, 0, 1, 1, 0, 0},
{0, 0, 2, 0, 0, 0, 0, 0}
};
auto **data = new Element * [4];
for (int i=0;i<4;i++) data[i] = new Element [8] ;
for (int i=0;i<4;i++){ for (int j=0;j<8;j++) { data[i][j] = base_datas[i][j]; } }
auto matSparse = SpMtx(4, 8, data);
cout << "非0值 : " << matSparse.length;NEWLINE
matSparse.printTuples();
matSparse.printMatrix();
cout << fixed << setprecision(3) << "稀疏度 : " << matSparse.getSparsity();NEWLINE
for (int i=0;i<4;i++) delete[] data[i];
return 0;
}
非0值 : 8
===============当前稀疏组==============
( 0, 6, 2 )
( 1, 0, 0.2 )
( 1, 3, 3 )
( 1, 5, 5 )
( 1, 6, 0.1 )
( 2, 4, 1 )
( 2, 5, 1 )
( 3, 2, 2 )
Origin-Shape is ( 4, 8 )
=========================================
===============当前稀疏矩阵==============
[ 0 0 0 0 0 0 2 0 ]
[ 0.2 0 0 3 0 5 0.1 0 ]
[ 0 0 0 0 1 1 0 0 ]
[ 0 0 2 0 0 0 0 0 ]
Origin-Shape is ( 4, 8 )
=========================================
稀疏度 : 0.250
cmake_minimum_required(VERSION 3.25)
project(SparseMatrix)
set(CMAKE_CXX_STANDARD 14)
include_directories(.)
add_executable(SparseMatrix
main.cpp
SpMtx.cpp
SpMtx.h)
源代码下载 :SparseMartix · PythonnotJava/自己实现的数据结构与算法合集 - 码云 - 开源中国 (gitee.com)