编程基础 - 特殊矩阵的压缩存储 (Compressed Storage of Special Matrix)

版权声明:本文为博主原创文章,未经允许不得转载。 https://blog.csdn.net/darkrabbit/article/details/89574603

编程基础 - 特殊矩阵的压缩存储 (Compressed Storage of Special Matrix)

返回分类:全部文章 >> 基础知识

本文将用C++实现特殊方阵和稀疏矩阵的压缩存储。

在查看本文之前,需要一些程序语言的基础,还要对“矩阵”与“二维数组”有一定了解。



1 特殊矩阵 (Special Matrix)

特殊矩阵:非零元素或零元素的分布有一定规律的矩阵。

压缩存储:在特殊矩阵中为了节省空间,有一些元素不必存储。

在程序中,最常见的特殊矩阵:

  • 上三角矩阵:方阵中只在上三角有元素;

  • 下三角矩阵:方阵中只在下三角有元素;

  • 对称矩阵:方阵中的上三角与下三角关于对角线对称;

  • 三对角矩阵:方阵中只有主对角线及其上下临近平行线有元素;

  • 稀疏矩阵:非零元素的数量远远小于矩阵元素数量。

    • 稀疏因子e:非零元素与长宽乘积的比值(有人认为e小于0.05才能称为稀疏矩阵)

10x10特殊矩阵格式如下:

上三角矩阵:
  1   2   3   4   5   6   7   8   9  10
  0  11  12  13  14  15  16  17  18  19
  0   0  20  21  22  23  24  25  26  27
  0   0   0  28  29  30  31  32  33  34
  0   0   0   0  35  36  37  38  39  40
  0   0   0   0   0  41  42  43  44  45
  0   0   0   0   0   0  46  47  48  49
  0   0   0   0   0   0   0  50  51  52
  0   0   0   0   0   0   0   0  53  54
  0   0   0   0   0   0   0   0   0  55

下三角矩阵:
  1   0   0   0   0   0   0   0   0   0
  2   3   0   0   0   0   0   0   0   0
  4   5   6   0   0   0   0   0   0   0
  7   8   9  10   0   0   0   0   0   0
 11  12  13  14  15   0   0   0   0   0
 16  17  18  19  20  21   0   0   0   0
 22  23  24  25  26  27  28   0   0   0
 29  30  31  32  33  34  35  36   0   0
 37  38  39  40  41  42  43  44  45   0
 46  47  48  49  50  51  52  53  54  55

对称矩阵:
  1   2   4   7  11  16  22  29  37  46
  2   3   5   8  12  17  23  30  38  47
  4   5   6   9  13  18  24  31  39  48
  7   8   9  10  14  19  25  32  40  49
 11  12  13  14  15  20  26  33  41  50
 16  17  18  19  20  21  27  34  42  51
 22  23  24  25  26  27  28  35  43  52
 29  30  31  32  33  34  35  36  44  53
 37  38  39  40  41  42  43  44  45  54
 46  47  48  49  50  51  52  53  54  55

三对角矩阵:
  1   2   0   0   0   0   0   0   0   0
  3   4   5   0   0   0   0   0   0   0
  0   6   7   8   0   0   0   0   0   0
  0   0   9  10  11   0   0   0   0   0
  0   0   0  12  13  14   0   0   0   0
  0   0   0   0  15  16  17   0   0   0
  0   0   0   0   0  18  19  20   0   0
  0   0   0   0   0   0  21  22  23   0
  0   0   0   0   0   0   0  24  25  26
  0   0   0   0   0   0   0   0  27  28

稀疏矩阵:
  0   0   0   0   0   0   0   0   0   0
 17   0   0   0   3   0   0   0   0   0
  0   0  69   0   0   0   0   0   0   0
  0   0   0   0   0   0   0   0  61   0
  0   0   0  42   0  98   0   0   0   0
  0   0   0   0   0   0   0   0   0  88
  0   0   0   0   0   0   0  53   0   0
  0   0   0   0   0   0   0   0   2   0
  0   0   0   0   0   0   0   0   0   0
  0   0   0   0  60   0   0   0   0   0


2 压缩矩阵 (Compress Matrix)

压缩存储,一般是采用数组或列表形式存储它们。

我们要干的是:

  • 计算它们存储位置(下标)

  • 如何根据压缩结构还原成矩阵

(提示:在CSDN的app中,公式有可能会乱码,可以用网页查看)

我们在这里,假设 n × n n \times n 矩阵二维数组或向量的纵下标 i i ,横下标 j j ,压缩后下标 k k 。它们都是从0开始。稀疏矩阵比较特殊。

压缩后数组长度size:

  • 上三角矩阵、下三角矩阵和对称矩阵: s i z e = n × ( n + 1 ) 2 size = \frac{n \times (n + 1)}{2}

  • 三对角矩阵(第一行,最后一行是2个元素,其余都是3个元素): s i z e = 3 × n 2 size = 3 \times n - 2

  • 稀疏矩阵:非零元素数量

矩阵下标转压缩数组下标 (按行)

  • 上三角方阵

    • i i 行之前的元素数量: ( n ( i 1 ) ) + n 2 × i \frac{(n - (i - 1)) + n}{2} \times i
    • i i 行第 j j 列之前的元素数量: j i j - i
    • 最终下标 k k 为:
      k = ( 2 × n i + 1 ) × i 2 + ( j i ) k = \frac{(2 \times n - i + 1) \times i}{2} + (j - i)
  • 下三角方阵与对称矩阵

    • i i 行之前的元素数量: ( 1 + i ) × i 2 \frac{(1 + i) \times i}{2}
    • i i 行第 j j 列之前的元素数量: j j
    • 最终下标 k k 为:
      k = ( 1 + i ) × i 2 + j k = \frac{(1 + i) \times i}{2} + j
  • 三对角方阵

    • i i 行之前的元素数量: 0 , ( i = 0 ) ; 3 × i 1 , ( i > 0 ) 0,(i=0); \quad 3 \times i - 1, (i>0)
    • i i 行第 j j 列之前的元素数量: j , ( i = 0 ) ; j i + 1 , ( i > 0 ) j ,(i=0); \quad j - i + 1,(i>0)
    • 最终下标 k k 为:
      k = 2 × i + j k = 2 \times i + j
  • 稀疏矩阵

    • 按非零元素的出现顺序存储行号、列号与元素值

3 压缩矩阵C++实现 (Compress Matrix C++ Code)

3.1 特殊方阵 (Special Square Matrix)

// Author: https://blog.csdn.net/DarkRabbit
// Compressed Storage of Special Matrix
// 压缩方阵
// params:
//      matrix:     需要压缩的特殊方阵
//      side:       方阵边长
//      type:       方阵类型
//      size:       输出的压缩后长度
// return:
//      压缩后的一位数组
int* CompressSquareMatrix(int** matrix,
                          const int side,
                          const SpecialMatrixType type,
                          int& size)
{
    if (matrix == 0)
    {
        throw std::invalid_argument("`matrix` is null.");
    }

    if (side < 1)
    {
        throw std::invalid_argument("Argument named `side` must be greater than 0.");
    }

    int k;
    int* compressed;
    switch (type)
    {
        case SpecialMatrixType::Up:
            size = side * (side + 1) / 2; // 上三角压缩后的元素个数
            compressed = new int[size];
            for (int i = 0; i < side; i++)
            {
                for (int j = i; j < side; j++)
                {
                    k = (2 * side - i + 1) * i / 2 + j - i;
                    compressed[k] = matrix[i][j];
                }
            }
            break;
        case SpecialMatrixType::Down:
        case SpecialMatrixType::Symmetric:
            size = side * (side + 1) / 2; // 下三角与对称矩阵压缩后的元素个数
            compressed = new int[size];
            for (int i = 0; i < side; i++)
            {
                for (int j = 0; j <= i; j++)
                {
                    k = (1 + i) * i / 2 + j;
                    compressed[k] = matrix[i][j];
                }
            }
            break;
        case SpecialMatrixType::Tridiagonal:
            size = 3 * side - 2; // 三对角矩阵压缩后的元素个数
            compressed = new int[size];
            for (int i = 0; i < side; i++)
            {
                for (int j = (i == 0) ? 0 : (i - 1); j <= i + 1 && j < side; j++)
                {
                    k = 2 * i + j;
                    compressed[k] = matrix[i][j];
                }
            }
            break;
        default:
            throw std::invalid_argument("Argument named `type` is not supported.");
    }

    return compressed;
}

3.2 稀疏矩阵 (Sparse Matrix)

稀疏矩阵要存储的有:行号、列号和值。所以我们需要一个结构:

// 稀疏矩阵元素
struct SparseElement
{
    int row;
    int col;
    int value;
};

而我们的稀疏矩阵也同样需要一个结构,来记录原本矩阵的长宽与元素数量:

// 稀疏矩阵结构定义
struct SparseMatrix
{
    int height;
    int length;
    int elementCount;
    SparseElement* elements;

    SparseMatrix() : elements(0){ }
    ~SparseMatrix()
    {
        if (elements != 0)
        {
            delete[] elements;
            elements = 0;
        }
    }
};

最后压缩矩阵:

// Author: https://blog.csdn.net/DarkRabbit
// Compressed Storage of Special Matrix
// 压缩稀疏矩阵
// params:
//      matrix:     需要压缩的稀疏矩阵
//      height:     矩阵宽度
//      length:     矩阵长度
//      outMatrix:  输出的压缩后矩阵
void CompressSparseMatrix(int** matrix,
                          const int height,
                          const int length,
                          SparseMatrix& outMatrix)
{
    if (matrix == 0)
    {
        throw std::invalid_argument("`matrix` is null.");
    }

    if (height < 1)
    {
        throw std::invalid_argument("Argument named `height` must be greater than 0.");
    }

    if (length < 1)
    {
        throw std::invalid_argument("Argument named `length` must be greater than 0.");
    }

    outMatrix.height = height;
    outMatrix.length = length;
    
    outMatrix.elementCount = 0;
    for (int i = 0; i < height; i++)
    {
        for (int j = 0; j < length; j++)
        {
            if (matrix[i][j] != 0)
            {
                outMatrix.elementCount++;
            }
        }
    }

    if (outMatrix.elements != 0)
    {
        delete[] outMatrix.elements;
    }

    outMatrix.elements = new SparseElement[outMatrix.elementCount];

    int k = 0;
    for (int i = 0; i < height; i++)
    {
        for (int j = 0; j < length; j++)
        {
            if (matrix[i][j] != 0)
            {
                outMatrix.elements[k].row = i;
                outMatrix.elements[k].col = j;
                outMatrix.elements[k].value = matrix[i][j];
                k++;
            }
        }
    }
}

4 还原矩阵 (Restore Matrix)

就像压缩矩阵一样,我们要做的还是先要获取矩阵的大小(除稀疏矩阵)。

还原矩阵大小:

  • 上三角矩阵、下三角矩阵和对称矩阵:它们的求解方法是一样的,只是反向求解需要解方程,显然在程序中比较麻烦,不过我们依然可以正向求解,使用累加,求解一共加了多少次。
    s i z e = 1 + 2 + . . . + n size = 1 + 2 + ... + n

  • 三对角矩阵:三对角矩阵就相对简单,只需要:
    n = ( s i z e + 2 ) ÷ 3 n = (size + 2) \div 3

关于特殊方阵的行号列号都可以使用压缩矩阵中的循环还原,其中三对角矩阵也可以使用如下公式:

i = ( k + 1 ) ÷ 3 j = k 2 × i \begin{aligned} i &amp;= \lfloor (k + 1) \div 3 \rfloor \\ j &amp;= k - 2 \times i \end{aligned}


5 还原矩阵C++代码 (Restore Matrix C++ Code)

5.1 特殊方阵 (Special Square Matrix)

// Author: https://blog.csdn.net/DarkRabbit
// Compressed Storage of Special Matrix
// 还原特殊方阵
// params:
//      compressed:     压缩存储的特殊方阵
//      size:           存储长度
//      type:           特殊方阵类型
//      side:           输出方阵的边长
// return:
//      还原的二维方阵
int** RestoreSquareMatrix(int* compressed, 
                          const int size, 
                          const SpecialMatrixType type,
                          int& side)
{
    if (compressed == 0)
    {
        throw std::invalid_argument("`compressed` matrix is null.");
    }

    if (size < 1)
    {
        throw std::invalid_argument("Argument named `size` must be greater than 0.");
    }

    // 求边长
    int k = 0;
    side = 0;
    switch (type)
    {
        case SpecialMatrixType::Up:
        case SpecialMatrixType::Down:
        case SpecialMatrixType::Symmetric:
            while (k < size)
            {
                side++; // 每行元素
                k += side; // k加上每行元素数量
            }
            break;
        case SpecialMatrixType::Tridiagonal:
            side = (size + 2) / 3;
            break;
        default:
            throw std::invalid_argument("Argument named `type` is not supported.");
    }

    // 初始化全0矩阵
    int** matrix = new int*[side];
    for (int i = 0; i < side; i++)
    {
        matrix[i] = new int[side];
        for (int j = 0; j < side; j++)
        {
            matrix[i][j] = 0;
        }
    }
    
    // 填充数值,和压缩一样
    switch (type)
    {
        case SpecialMatrixType::Up:
            for (int i = 0; i < side; i++)
            {
                for (int j = i; j < side; j++)
                {
                    k = (2 * side - i + 1) * i / 2 + j - i;
                    matrix[i][j] = compressed[k];
                }
            }
            break;
        case SpecialMatrixType::Down:
        case SpecialMatrixType::Symmetric:
            for (int i = 0; i < side; i++)
            {
                for (int j = 0; j <= i; j++)
                {
                    k = (1 + i) * i / 2 + j;
                    matrix[i][j] = compressed[k]; // 下三角矩阵
                    if (type == SpecialMatrixType::Symmetric) // 如果是对称对称
                    {
                        matrix[j][i] = compressed[k];
                    }
                }
            }
            break;
        case SpecialMatrixType::Tridiagonal:
            for (int i = 0; i < side; i++)
            {
                for (int j = (i == 0) ? 0 : (i - 1); j <= i + 1 && j < side; j++)
                {
                    k = 2 * i + j;
                    matrix[i][j] = compressed[k];
                }
            }
            //// 或
            //for (k = 0; k < size; k++)
            //{
            //    i = (k + 1) / 3;
            //    j = k - 2 * i;
            //    matrix[i][j] = compressed[k];
            //}
            break;
    }

    return matrix;
}

5.2 稀疏矩阵 (Sparse Matrix)

// Author: https://blog.csdn.net/DarkRabbit
// Compressed Storage of Special Matrix
// 还原稀疏矩阵
// params:
//      sparse:     稀疏矩阵
// return:
//      还原的矩阵
int** RestoreSparseMatrix(const SparseMatrix& sparse)
{
    if (sparse.height < 1 || sparse.length < 1)
    {
        throw std::invalid_argument("Argument named `sparse` has size error.");
    }

    // 初始化全0矩阵
    int** matrix = new int*[sparse.height];
    for (int i = 0; i < sparse.height; i++)
    {
        matrix[i] = new int[sparse.length];
        for (int j = 0; j < sparse.length; j++)
        {
            matrix[i][j] = 0;
        }
    }

    // 赋值
    for (int k = 0; k < sparse.elementCount; k++)
    {
        matrix[sparse.elements[k].row][sparse.elements[k].col] = sparse.elements[k].value;
    }

    return matrix;
}

6 主函数C++代码与测试 (Main Method C++ Code and Testing)

6.1 一些定义与声明 (Definition and Declaration)

文件special_matrix.h:

// Author: https://blog.csdn.net/DarkRabbit
// Compressed Storage of Special Matrix

#pragma once

#include <string> // 字符串
#include <time.h> // 时间,随机稀疏矩阵用
#include <stdexcept> // 错误库

// 特殊矩阵类型
enum SpecialMatrixType
{
    Up,             // 上三角
    Down,           // 下三角
    Symmetric,      // 对称
    Tridiagonal,    // 三对角
    Sparse          // 稀疏
};

// 稀疏矩阵元素
struct SparseElement
{
    int row;
    int col;
    int value;
};

// 稀疏矩阵结构定义
struct SparseMatrix
{
    int height;
    int length;
    int elementCount;
    SparseElement* elements;

    SparseMatrix() : elements(0){ }
    ~SparseMatrix()
    {
        if (elements != 0)
        {
            delete[] elements;
            elements = 0;
        }
    }
};

// 生成一个全0的矩阵
// params:
//      height:     矩阵宽度
//      length:     矩阵长度
// return:
//      matrix:     返回的矩阵
int** InitMatrix(const int height, const int length);

// 销毁一个矩阵
// params:
//      matrix:     需要销毁的矩阵
//      height:     矩阵宽度
void DestroyMatrix(int** matrix, const int height);

// 获取矩阵字符串
// params:
//      matrix:     打印的矩阵
//      height:     矩阵宽度
//      length:     矩阵长度
//      char:       每个元素的分隔符(默认空格)
// return:
//      string:     打印的字符串
std::string Matrix2String(int** matrix,
                          const int height,
                          const int length,
                          const char seq = ' ');

// 以随机数填充一个全0矩阵成稀疏矩阵
// params:
//      matrix:     填充的矩阵
//      height:     矩阵宽度
//      length:     矩阵长度
void FillSparseMatrixRandom(int** matrix,
                            const int height,
                            const int length);

// 默认以1开头填充一个全0的方阵成特殊方阵
// params:
//      matrix: 填充的方阵
//      side:   方阵的边长
//      type:   特殊矩阵类型
void FillSpecialMatrix(int** matrix,
                       const int side,
                       const SpecialMatrixType type);

// 压缩稀疏矩阵
// params:
//      matrix:     需要压缩的稀疏矩阵
//      height:     矩阵宽度
//      length:     矩阵长度
//      outMatrix:  输出的压缩后矩阵
void CompressSparseMatrix(int** matrix,
                          const int height,
                          const int length,
                          SparseMatrix& outMatrix);

// 压缩方阵
// params:
//      matrix:     需要压缩的特殊方阵
//      side:       方阵边长
//      type:       方阵类型
//      size:       输出的压缩后长度
// return:
//      压缩后的一维数组
int* CompressSquareMatrix(int** matrix,
                          const int side,
                          const SpecialMatrixType type,
                          int& size);

// 还原稀疏矩阵
// params:
//      sparse:     稀疏矩阵
// return:
//      还原的矩阵
int** RestoreSparseMatrix(const SparseMatrix& sparse);

// 还原特殊方阵
// params:
//      compressed:     压缩存储的特殊方阵
//      size:           存储长度
//      type:           特殊方阵类型
//      side:           输出方阵的边长
// return:
//      还原的二维方阵
int** RestoreSquareMatrix(int* compressed,
                          const int size,
                          const SpecialMatrixType type,
                          int& side);

6.2 主函数 (Main Method)

主函数文件main.cpp:

// Author: https://blog.csdn.net/DarkRabbit
// Compressed Storage of Special Matrix

#include <string>
#include "special_matrix.h";

#include <iostream>
using namespace std;


string Array2String(int* compressed, const int size, const char seq = ' ')
{
    string str = "";
    for (int i = 0; i < size; i++)
    {
        str += to_string(compressed[i]) + seq;
    }
    return str;
}

// 主函数
int main()
{
    int n = 10;
    
    // 创建全0矩阵
    int** upMatrix = InitMatrix(n, n);
    int** downMatrix = InitMatrix(n, n);
    int** symmetricMatrix = InitMatrix(n, n);
    int** tridiagonalMatrix = InitMatrix(n, n);
    int** sparseMatrix = InitMatrix(n, n);

    // 填充成示例特殊矩阵
    FillSpecialMatrix(upMatrix, n, SpecialMatrixType::Up);
    FillSpecialMatrix(downMatrix, n, SpecialMatrixType::Down);
    FillSpecialMatrix(symmetricMatrix, n, SpecialMatrixType::Symmetric);
    FillSpecialMatrix(tridiagonalMatrix, n, SpecialMatrixType::Tridiagonal);
    FillSpecialMatrix(sparseMatrix, n, SpecialMatrixType::Sparse);

    // 获取打印字符串
    string upStr = Matrix2String(upMatrix, n, n, ' ');
    string downStr = Matrix2String(downMatrix, n, n, ' ');
    string symmetricStr = Matrix2String(symmetricMatrix, n, n, ' ');
    string tridiagonalStr = Matrix2String(tridiagonalMatrix, n, n, ' ');
    string sparseStr = Matrix2String(sparseMatrix, n, n, ' ');

    // 打印特殊矩阵
    cout << "上三角矩阵:" << endl << upStr << endl;
    cout << "下三角矩阵:" << endl << downStr << endl;
    cout << "对称矩阵:" << endl << symmetricStr << endl;
    cout << "三对角矩阵:" << endl << tridiagonalStr << endl;
    cout << "稀疏矩阵:" << endl << sparseStr << endl;

    // 压缩矩阵
    int upSize, doSize, sySize, trSize;
    int* upCM = CompressSquareMatrix(upMatrix, n, SpecialMatrixType::Up, upSize);
    int* doCM = CompressSquareMatrix(downMatrix, n, SpecialMatrixType::Down, doSize);
    int* syCM = CompressSquareMatrix(symmetricMatrix, n, SpecialMatrixType::Symmetric, sySize);
    int* trCM = CompressSquareMatrix(tridiagonalMatrix, n, SpecialMatrixType::Tridiagonal, trSize);
    SparseMatrix *spCM = new SparseMatrix();
    CompressSparseMatrix(sparseMatrix, n, n, *spCM);

    // 获取压缩矩阵字符串
    upStr = Array2String(upCM, upSize);
    downStr = Array2String(doCM, doSize);
    symmetricStr = Array2String(syCM, sySize);
    tridiagonalStr = Array2String(trCM, trSize);
    sparseStr = "";
    for (int i = 0; i < spCM->elementCount; i++)
    {
        SparseElement e = spCM->elements[i];
        sparseStr += "(" + to_string(e.row) + ", " + to_string(e.col) + ", " + to_string(e.value) + ")";
        sparseStr += " ";
    }

    // 打印压缩矩阵
    cout << "上三角压缩:长度" << upSize << endl << upStr << endl;
    cout << "下三角压缩:长度" << doSize << endl << downStr << endl;
    cout << "对称压缩:长度" << sySize << endl << symmetricStr << endl;
    cout << "三对角压缩:长度" << trSize << endl << tridiagonalStr << endl;
    cout << "稀疏压缩:压缩长度" << spCM->elementCount << "原高度" << spCM->height << "原宽度" << spCM->length << endl;
    cout << sparseStr << endl;
    cout << endl;

    // 销毁原矩阵
    DestroyMatrix(upMatrix, n);
    DestroyMatrix(downMatrix, n);
    DestroyMatrix(symmetricMatrix, n);
    DestroyMatrix(tridiagonalMatrix, n);
    DestroyMatrix(sparseMatrix, n);

    // 还原矩阵
    int upSide, doSide, sySide, trSide, spHeight, spLength;
    upMatrix = RestoreSquareMatrix(upCM, upSize, SpecialMatrixType::Up, upSide);
    downMatrix = RestoreSquareMatrix(doCM, doSize, SpecialMatrixType::Down, doSide);
    symmetricMatrix = RestoreSquareMatrix(syCM, sySize, SpecialMatrixType::Symmetric, sySide);
    tridiagonalMatrix = RestoreSquareMatrix(trCM, trSize, SpecialMatrixType::Tridiagonal, trSide);
    sparseMatrix = RestoreSparseMatrix(*spCM);
    spHeight = spCM->height;
    spLength = spCM->length;

    // 销毁压缩矩阵
    delete[] upCM;
    delete[] doCM;
    delete[] syCM;
    delete[] trCM;
    delete spCM;

    // 打印还原的矩阵
    upStr = Matrix2String(upMatrix, upSide, upSide, ' ');
    downStr = Matrix2String(downMatrix, doSide, doSide, ' ');
    symmetricStr = Matrix2String(symmetricMatrix, sySide, sySide, ' ');
    tridiagonalStr = Matrix2String(tridiagonalMatrix, trSide, trSide, ' ');
    sparseStr = Matrix2String(sparseMatrix, spHeight, spLength, ' ');
    cout << "还原上三角矩阵:" << endl << upStr << endl;
    cout << "还原下三角矩阵:" << endl << downStr << endl;
    cout << "还原对称矩阵:" << endl << symmetricStr << endl;
    cout << "还原三对角矩阵:" << endl << tridiagonalStr << endl;
    cout << "还原稀疏矩阵:" << endl << sparseStr << endl;

    // 销毁还原矩阵
    DestroyMatrix(upMatrix, upSide);
    DestroyMatrix(downMatrix, doSide);
    DestroyMatrix(symmetricMatrix, sySide);
    DestroyMatrix(tridiagonalMatrix, trSide);
    DestroyMatrix(sparseMatrix, spHeight);

    system("pause");
    return 0;
}

6.3 打印结果 (Print Output)

上三角矩阵:
  1   2   3   4   5   6   7   8   9  10
  0  11  12  13  14  15  16  17  18  19
  0   0  20  21  22  23  24  25  26  27
  0   0   0  28  29  30  31  32  33  34
  0   0   0   0  35  36  37  38  39  40
  0   0   0   0   0  41  42  43  44  45
  0   0   0   0   0   0  46  47  48  49
  0   0   0   0   0   0   0  50  51  52
  0   0   0   0   0   0   0   0  53  54
  0   0   0   0   0   0   0   0   0  55

下三角矩阵:
  1   0   0   0   0   0   0   0   0   0
  2   3   0   0   0   0   0   0   0   0
  4   5   6   0   0   0   0   0   0   0
  7   8   9  10   0   0   0   0   0   0
 11  12  13  14  15   0   0   0   0   0
 16  17  18  19  20  21   0   0   0   0
 22  23  24  25  26  27  28   0   0   0
 29  30  31  32  33  34  35  36   0   0
 37  38  39  40  41  42  43  44  45   0
 46  47  48  49  50  51  52  53  54  55

对称矩阵:
  1   2   4   7  11  16  22  29  37  46
  2   3   5   8  12  17  23  30  38  47
  4   5   6   9  13  18  24  31  39  48
  7   8   9  10  14  19  25  32  40  49
 11  12  13  14  15  20  26  33  41  50
 16  17  18  19  20  21  27  34  42  51
 22  23  24  25  26  27  28  35  43  52
 29  30  31  32  33  34  35  36  44  53
 37  38  39  40  41  42  43  44  45  54
 46  47  48  49  50  51  52  53  54  55

三对角矩阵:
  1   2   0   0   0   0   0   0   0   0
  3   4   5   0   0   0   0   0   0   0
  0   6   7   8   0   0   0   0   0   0
  0   0   9  10  11   0   0   0   0   0
  0   0   0  12  13  14   0   0   0   0
  0   0   0   0  15  16  17   0   0   0
  0   0   0   0   0  18  19  20   0   0
  0   0   0   0   0   0  21  22  23   0
  0   0   0   0   0   0   0  24  25  26
  0   0   0   0   0   0   0   0  27  28

稀疏矩阵:
  0   0   0  45   0   0   0   0   0   0
  0   0   0   0   0   0   0   0   0   0
  0   0   0   0  46   0   0   0   0   0
  0   0   0   0   0   0   0   0   0   0
  0   0   0   0   0   0   0   0   0   0
 29   0   0   0   0  95   0   0   0  94
  0   0   0   0   0   0   0   0   0   0
  0   0  73  49   0   0   0   0   0   0
  0   0   0   0   0   0   0   0  39   0
  0   0   0   0  58   0   0   0   0  36

上三角压缩:长度55
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 
29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55
下三角压缩:长度55
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 
29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55
对称压缩:长度55
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 
29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55
三对角压缩:长度28
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
稀疏压缩:压缩长度10原高度10原宽度10
(0, 3, 45) (2, 4, 46) (5, 0, 29) (5, 5, 95) (5, 9, 94) (7, 2, 73) 
(7, 3, 49) (8, 8, 39) (9, 4, 58) (9, 9, 36)

还原上三角矩阵:
  1   2   3   4   5   6   7   8   9  10
  0  11  12  13  14  15  16  17  18  19
  0   0  20  21  22  23  24  25  26  27
  0   0   0  28  29  30  31  32  33  34
  0   0   0   0  35  36  37  38  39  40
  0   0   0   0   0  41  42  43  44  45
  0   0   0   0   0   0  46  47  48  49
  0   0   0   0   0   0   0  50  51  52
  0   0   0   0   0   0   0   0  53  54
  0   0   0   0   0   0   0   0   0  55

还原下三角矩阵:
  1   0   0   0   0   0   0   0   0   0
  2   3   0   0   0   0   0   0   0   0
  4   5   6   0   0   0   0   0   0   0
  7   8   9  10   0   0   0   0   0   0
 11  12  13  14  15   0   0   0   0   0
 16  17  18  19  20  21   0   0   0   0
 22  23  24  25  26  27  28   0   0   0
 29  30  31  32  33  34  35  36   0   0
 37  38  39  40  41  42  43  44  45   0
 46  47  48  49  50  51  52  53  54  55

还原对称矩阵:
  1   2   4   7  11  16  22  29  37  46
  2   3   5   8  12  17  23  30  38  47
  4   5   6   9  13  18  24  31  39  48
  7   8   9  10  14  19  25  32  40  49
 11  12  13  14  15  20  26  33  41  50
 16  17  18  19  20  21  27  34  42  51
 22  23  24  25  26  27  28  35  43  52
 29  30  31  32  33  34  35  36  44  53
 37  38  39  40  41  42  43  44  45  54
 46  47  48  49  50  51  52  53  54  55

还原三对角矩阵:
  1   2   0   0   0   0   0   0   0   0
  3   4   5   0   0   0   0   0   0   0
  0   6   7   8   0   0   0   0   0   0
  0   0   9  10  11   0   0   0   0   0
  0   0   0  12  13  14   0   0   0   0
  0   0   0   0  15  16  17   0   0   0
  0   0   0   0   0  18  19  20   0   0
  0   0   0   0   0   0  21  22  23   0
  0   0   0   0   0   0   0  24  25  26
  0   0   0   0   0   0   0   0  27  28

还原稀疏矩阵:
  0   0   0  45   0   0   0   0   0   0
  0   0   0   0   0   0   0   0   0   0
  0   0   0   0  46   0   0   0   0   0
  0   0   0   0   0   0   0   0   0   0
  0   0   0   0   0   0   0   0   0   0
 29   0   0   0   0  95   0   0   0  94
  0   0   0   0   0   0   0   0   0   0
  0   0  73  49   0   0   0   0   0   0
  0   0   0   0   0   0   0   0  39   0
  0   0   0   0  58   0   0   0   0  36

请按任意键继续. . .


猜你喜欢

转载自blog.csdn.net/darkrabbit/article/details/89574603