1. 程式人生 > >對稱矩陣及稀疏矩陣淺談

對稱矩陣及稀疏矩陣淺談

1.對稱矩陣

特點:
關於對角線對稱,Aij == Aji。
下面實現:
①對稱矩陣的壓縮儲存
②對稱矩陣的訪問
③對稱矩陣的還原

實現程式碼如下:

#define _CRT_SECURE_NO_WARNINGS 1
#include<iostream>
using namespace std;
//對稱矩陣的壓縮儲存
template<class T>
class SymmetricMatrix
{
public:
    SymmetricMatrix(T* array, size_t N)
        :_N(N)
        ,_a(NULL)
    {
        _a = new
T[(N * (N + 1))>> 1]; for (size_t i = 0; i < N; ++i) { for (size_t j = 0; j < N; ++j) { if (i >= j)//表明是下三角資料時 { _a[(i * (i + 1))>>1 + j] = array[i * N + j]; } else
{ break; } } } } T& Access(size_t x, size_t y) { if (x < y)//如果訪問上三角元素 { swap(x, y); } return _a[(x * (x + 1)) >> 1 + y]; } void DisPlay() { for
(size_t i = 0; i < _N; ++i) { for (size_t j = 0; j < _N; ++j) { if (i >= j)//訪問下三角元素 { cout<<Access(i, j)<<" "; } else { cout << Access(j, i) << " "; } } cout << endl; } cout << endl; } ~SymmetricMatrix() { if (_a) { delete[] _a; _a = NULL; } } private: T* _a; size_t _N; };

測試程式碼如下:

void Test()
{
    int a[5][5] =
    {
        { 0, 1, 2, 3, 4 },
        { 1, 0, 1, 2, 3 },
        { 2, 1, 0, 1, 2 },
        { 3, 2, 1, 0, 1 },
        { 4, 3, 2, 1, 0 },
    };
    SymmetricMatrix<int> sm((int*)a, 5);
    cout << sm.Access(0, 3) << endl;
    cout << sm.Access(3, 0) << endl;
    sm.DisPlay();
}

int main()
{
    Test();
    return 0;
}

2.稀疏矩陣:

這裡寫圖片描述

(1)稀疏矩陣的壓縮儲存:

所謂稀疏矩陣的壓縮儲存,其實就是將稀疏矩陣中的有效元素儲存起來,但由於稀疏矩陣中有效元素的分佈沒有規律可尋,所以需要使用一個三元組來儲存其位置(row、col)以及有效值。—>三元組最好使用結構體來儲存。

因為不知道矩陣中究竟有多少個有效元素(即就是不知需要多少個結構體),那麼就可以使用vector(動態增長型)來儲存有效元素。

//三元組--->儲存有效元素的位置及值
    template<class T>
    struct Trituple
    {
        Trituple(size_t row, size_t col, const T& data)
        :_row(row)
        , _col(col)
        , _data(data)
        {}

        size_t _row;
        size_t _col;
        T _data;
    };
//稀疏矩陣的壓縮儲存
    SparseMatrix(T* array, int row, int col,const T& invalid)
        :_row(row)
        , _col(col)
        ,_invalid(invalid)
    {
        for (int i = 0; i < row; ++i)
        {
            for (int j = 0; j < col; ++j)
            {
                if (array[i * col + j] != invalid)
                {
                    _sm.push_back(Trituple<T>(i, j, array[i * col + j]));
                }
            }
        }
    }

(2)稀疏矩陣的轉置:

這裡寫圖片描述

稀疏矩陣的轉置過程如下:

這裡寫圖片描述

實現程式碼如下:

   // 稀疏矩陣的轉置
   //時間複雜度:(稀疏矩陣的列*稀疏矩陣中有效元素的個數)
    SparseMatrix<T> Transprot()
    {
        SparseMatrix<T> sm;
        sm._row = _col;
        sm._col = _row;

        for (size_t index = 0; index < _col; ++index)
        {
            vector<Trituple<T> >::iterator it = _sm.begin();
            while (it != _sm.end())
            {
                if ( it->_col == index)
                {
                    sm._sm.push_back(Trituple<T>(it->_col, it->_row, it->_data));
                }
                it++;
            }
        }
        return sm;
    }

3.稀疏矩陣的快速轉置:

稀疏矩陣的轉置的時間複雜度:(稀疏矩陣的列N*稀疏矩陣中有效元素的個數)—-》時間複雜度較大,所以引出了快速轉置

稀疏矩陣的快速轉置的時間複雜度(2*有效元素的個數 + 稀疏矩陣的列)

快速轉置的思想如下:

這裡寫圖片描述

程式碼實現:


//快速轉置
SparseMatrix<T,N,M> FastTransport(const size_t m,const size_t n)
    {
    SparseMatrix < T, N, M> sm;//轉置後的壓縮矩陣
        sm._row = _col;
        sm._col = _row;
        sm._v.resize(_v.size());//為了保證後面可以直接訪問vector中的資料(呼叫operator[])
        //儲存轉置前的每列有效元素的個數,即就是轉置後每行有效元素的個數
        int rows[N] = {0};
        size_t index = 0;
        while (index < _v.size())
        {
            rows[_v[index]._col]++;
            index++;
        }
        //儲存轉置後的每行第一個有效元素在轉置後的三元組陣列中的下標
        int starts[N] = { 0 };
        for (size_t i = 1; i < _col; ++i)
        {
            starts[i] = starts[i - 1] + rows[i - 1];
        }

        for (size_t i = 0; i < _v.size(); ++i)
        {
            int row = _v[i]._col;//轉置前列的下標即是轉置後行的下標
            Triple<T> t;
            t._value = _v[i]._value;
            t._col = _v[i]._row;
            t._row = _v[i]._col;
            sm._v[starts[row]] = t;
            starts[row]++;//每次需要更新starts陣列中的資料
        }
        return sm;
    }

全部程式碼如下:

#define _CRT_SECURE_NO_WARNINGS 1
#include<iostream>
using namespace std;
#include<vector>

//三元組
template<class T>
struct Triple
{
    Triple()
    {}
    Triple(T& data, size_t row, size_t col)
        :_value(data)
        , _row(row)
        , _col(col)
    {}
    T _value;
    size_t _row;
    size_t _col;
};

template<class T,size_t M,size_t N>
class SparseMatrix
{
public:
    SparseMatrix()
    {}

    //稀疏矩陣的壓縮儲存
    SparseMatrix(T* array, const T& invalid)
        :_invalid(invalid)
        , _row(M)
        , _col(N)
    {
        for (size_t i = 0; i < _row; ++i)
        {
            for (size_t j = 0; j < _col; ++j)
            {
                if (array[i * N + j] != invalid)
                {
                    Triple<T> t;
                    t._value = array[i * N + j];
                    t._row = i;
                    t._col = j;
                    _v.push_back(t);
                }
            }
        }
    }

    //稀疏矩陣的還原
    void Display()
    {
        int index = 0;
        for (size_t i = 0; i < _row; ++i)
        {
            for (size_t j = 0; j < _col; ++j)
            {
                if (index < _v.size() && _v[index]._row == i && _v[index]._col == j)
                {
                    cout << _v[index]._value << " ";
                    index++;
                }
                else
                {
                    cout << _invalid << " ";
                }
            }
            cout << endl;
        }
        cout << endl;
    }

    //稀疏矩陣的轉置
    SparseMatrix<T,N,M> Transport()
    {
        SparseMatrix<T,N,M> _sm;//轉置後的
        _sm._invalid = _invalid;
        _sm._row = _col;
        _sm._col = _row;
        //按列查詢(轉置前的列優先即就是轉置後的行優先)
        for (size_t i = 0; i < _col; ++i)
        {
            size_t index = 0;
            while (index < _v.size())
            {
                if (_v[index]._col == i)
                {
                    Triple<T> t;
                    t._value = _v[index]._value;
                    t._row = _v[index]._col;
                    t._col = _v[index]._row;
                    _sm._v.push_back(t);
                }
                index++;
            }
        }
        return _sm;
    }

    template<class T, size_t N, size_t M>
    friend class SparseMatrix;

//快速轉置
SparseMatrix<T,N,M> FastTransport(const size_t m,const size_t n)
    {
    SparseMatrix < T, N, M> _sm;//轉置後的壓縮矩陣
        _sm._row = _col;
        _sm._col = _row;
        _sm._v.resize(_v.size());//為了保證後面可以直接訪問vector中的資料(使用operator[])
        //儲存轉置前的每列有效元素的個數,即就是轉置後每行有效元素的個數
        int rows[N] = {0};
        size_t index = 0;
        while (index < _v.size())
        {
            rows[_v[index]._col]++;
            index++;
        }
        //儲存轉置後的每行第一個有效元素在轉置後的三元組陣列中的下標
        int starts[N] = { 0 };
        for (size_t i = 1; i < _col; ++i)
        {
            starts[i] = starts[i - 1] + rows[i - 1];
        }

        for (size_t i = 0; i < _v.size(); ++i)
        {
            int row = _v[i]._col;//轉置前列的下標即是轉置後行的下標
            Triple<T> t;
            t._value = _v[i]._value;
            t._col = _v[i]._row;
            t._row = _v[i]._col;
            _sm._v[starts[row]] = t;
            starts[row]++;//每次需要更新starts陣列中的資料
        }
        return _sm;
    }

private:
    vector<Triple<T> >  _v;
    T _invalid;
    size_t _row;
    size_t _col;
};

測試程式碼如下:


void Test()
{
    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 },
    };
    SparseMatrix<int,6,5> sm((int*)array, 0);
    sm.Display();
    SparseMatrix<int,5,6> sm2 = sm.FastTransport(5,6);
    sm2.Display();
}

int main()
{
    Test();
    return 0;
}

由於能力有限,又是剛開始學習資料結構,難免會有思考的不正確或是不完善的地方,歡迎大家批評指正。。。

相關推薦

對稱矩陣稀疏矩陣

1.對稱矩陣 特點: 關於對角線對稱,Aij == Aji。 下面實現: ①對稱矩陣的壓縮儲存 ②對稱矩陣的訪問 ③對稱矩陣的還原 實現程式碼如下: #define _CRT_SECURE_NO_WARNINGS 1 #include<

轉載:全局拉普拉斯平滑之(1)Strucutre extraction from texture via relative total variation稀疏矩陣求解

場景 solid b2c eas ont 進行 hidden tis watermark 全局拉普拉斯平滑之(1)Strucutre extraction from texture via relative total variation及稀疏矩陣求解 2018年01月3

session,cookie,sessionStorage,localStorage的區別應用場景 session,cookie,sessionStorage,localStorage的區別應用場景

 轉載自 cencenyue 淺談session,cookie,sessionStorage,localStorage的區別及應用場景 瀏覽器的快取機制提供了可以將使用者資料儲存在客戶端上的方式,可以利用cookie,session等跟

資料結構與演算法(Java描述)-15、稀疏矩陣以及稀疏矩陣的三元組實現

一、稀疏矩陣 對一個m×n的矩陣,設s為矩陣元素個數的總和,有s=m*n,設t為矩陣中非零元素個數的總和,滿足t<<s的矩陣稱作稀疏矩陣。符號“<<”讀作小於小於。簡單說,稀疏矩陣就是非零元素個數遠遠小於元素個數的矩陣。相對於稀疏矩陣來說,一個不稀疏的矩陣也稱作稠密矩陣。

PHP陣列鍵值Key越界後涉及的資料型別值範圍

做專案時遇到一個問題: 獲取專案介面返回的資料存入PHP陣列作為Key,但是取出來值就不一樣了,嗶--- 經過一番大腦回路,發現竟然是PHP陣列Key越界,既然遇到就簡單記錄一下,哎,這一生犯的錯實在

矩陣》——稀疏矩陣(Java)

轉載請註明出處: 轉載自  Thinkgamer的CSDN部落格:blog.csdn.net/gamer_gyt 1:稀疏矩陣的背景 2:什麼是稀疏矩陣? 3:為什麼要對稀疏矩陣進行壓縮儲存以及壓縮

矩陣變換——Matrix

hit res ngs com 之間 map wid can 位置 矩陣變換在圖形學上經常用到。基本的常用矩陣變換操作包括平移、縮放、旋轉、斜切。 每種變換都對應一個變換矩陣,通過矩陣乘法,可以把多個變換矩陣相乘得到復合變換矩陣。 矩陣乘法不支持交換律,因此不同

協方差矩陣(轉)

但是 資料 sample 可能 tlab 原來 data- 一個 處理 原文地址:http://pinkyjie.com/2010/08/31/covariance/ 今天看論文的時候又看到了協方差矩陣這個破東西,以前看模式分類的時候就特困擾,沒想到現在還是搞不清楚,索性開

python中scipy學習——隨機稀疏矩陣操作

http 坐標 head num value 可選 https import pan 1.生成隨機稀疏矩陣: scipy中生成隨機稀疏矩陣的函數如下: scipy.sparse.rand(m,n,density,format,dtype,random_state) 1

矩陣分解以及應用

轉自 https://blog.csdn.net/BPSSY/article/details/17552839 https://blog.csdn.net/carrierlxksuper/article/details/8487276 矩陣分解 (matrix decomposit

稀疏矩陣的儲存方法(3種)C語言程式碼實現

稀疏矩陣,即含有少量非 0 元素的矩陣,如圖 1 所示:   圖 1 稀疏矩陣    該矩陣中非 0 元素的數量比較少,與其使用普通方式將矩陣中的所有資料元素一一儲存,不如只儲存非 0 元素更節省記憶體空間,拿圖 1 中矩陣來說,只需儲存元素 3、4、5 即可(此類儲存方式被稱為稀疏矩陣的壓縮儲存)。

線性代數之——對稱矩陣正定性

當 A A A 是對稱的時候,

斐波那契數列——從遞推到矩陣乘法

說在前面 相信大家都已經知道這個中外著名的費波納切數列了吧,關於費波那契數列有很多有趣的性質,但我們這裡不講,在這裡我們只是利用斐波那契數列來引出另一個神奇的東西,矩陣乘法,遞推在這裡是起一個對比與鋪墊的作用,(沒有對比就不知道矩陣乘法有多快)。 斐波那

第九周專案三:稀疏矩陣的三元組表示的實現應用(2)

/* Copyright (c)2015,煙臺大學計算機與控制工程學院 All rights reserved. 檔名稱:專案3-2.cbp 作 者:孫立立 完成日期:2015年12月4日 版 本 號:v1.0 問題描述:(2)採用三元組儲存稀疏矩陣,設計兩個稀疏

稀疏矩陣的三元組表示的實現應用(2)——採用三元組儲存稀疏矩陣,設計兩個稀疏矩陣相加的運算演算法

/* *Copyright (c) 2015 , 煙臺大學計算機學院 *All right resvered . *檔名稱: 稀疏矩陣.cpp *作 者: 鄭兆涵 *稀疏矩陣的三元組表示的實現及應用(2) */ 問題:稀疏矩

矩陣分解在推薦系統中的應用

       推薦系統是當下越來越熱的一個研究問題,無論在學術界還是在工業界都有很多優秀的人才參與其中。近幾年舉辦的推薦系統比賽更是一次又一次地把推薦系統的研究推向了高潮,比如幾年前的Neflix百萬大獎賽,KDD CUP 2011的音樂推薦比賽,去年的百度電影推薦競賽,

線性表再稀疏矩陣+

稀疏多項式 本來不打算對線性表進行多次闡述了。但是在這兩天的做題過程中發現了好多有關順序表的有趣的事兒。感覺突然還是很有必要再對其進行贅述一下的啦。以後的記錄都是自己的思考,而不是簡單的實現步驟

資料結構::矩陣(一)--對稱矩陣對稱矩陣的壓縮儲存

【對稱矩陣】: 1、定義:元素以對角線為對稱軸對應相等的矩陣。      設一個N*N的方陣A,A中任意元素Aij,當且僅當Aij == Aji(0 <= i <= N-1&&a

稀疏矩陣的資料結構相關演算法

1三元組順序表 資料結構: typedef struct{ int i,j; //非零元的行下標和列下標 ElemType e; }

壓縮感知(十八):常見測量矩陣及其實現

function [ Phi ] = PartHadamardMtx( M,N ) %PartHadamardMtx Summary of this function goes here % Generate part Hadamard matrix % M -- RowNumber % N