算法:稀疏矩阵

前言:在学习Google搜索技术特点时,了解到了Google创始人Larry Page和Sergey Brin利用了稀疏矩阵的计算技巧和多次迭代的方法,将亿级的网页矩阵不断简化,得出网页排名,便深入学习了一下稀疏矩阵算法并优化了自己编写的Java矩阵类

什么是稀疏矩阵?

概念:在一个n*m的矩阵中,当非0的元素远远少于为0的元素,且非0的元素分布没有规律时我们便称它为稀疏矩阵,反之则为稠密矩阵。

                       

稀疏因子δ:当稀疏因子的值<=0.05时我们则称这个矩阵为稀疏矩阵。

公式:

\delta =\frac{t}{n*m}          t为非0的元素的个数。

稀疏矩阵压缩

通常我们用二维数组存储矩阵,但是当一个矩阵为稀疏矩阵,大量的0元素存储十分浪费内存,于是我们可以将0元素压缩并将非0元素存储下来,就可以实现稀疏矩阵压缩,存储有效数据。

 1,COO压缩(Coordinate) 

 概念:这个十分简单利用三个数组,Row(行),Cloumn(列),Value(值),分别将非0数的坐标和值存储下来。

如图(别人的图)

                     

 2,CSR压缩(CompressedSparsityRow)

概念:相比COO压缩,CSR节省了更多空间,还是利用三个数组,RowOffset(行偏移),Cloumn(列),Value(值)。所谓的行偏移即某一行第一个元素在Values数组里面的起始偏移值,如1相对于Values数组起始位置偏移0,2相对于Values起始位置偏移2,以此类推。

如图(别人的图)

                    

同理还有CSC 列压缩,和CSR一样就不再赘述了。

除了以上三种矩阵压缩外还有 对角线压缩 (DIA),ELLPACK(ELL),Hybrid (HYB)等几种压缩方式,详情请见:如何高效存储稀疏矩阵?

JAVA代码

以下是本人的小框架代码,GeniusArrayList即ArrayList。

COO压缩

private GeniusMatrix CoordinateSparsityMatrix(GeniusMatrix Matrix){
        int X = Matrix.getX();
        int Y = Matrix.getY();
        int Base = X*Y;
        GeniusArrayList<GeniusArrayList<Double>> COOMatrix = new GeniusArrayList<GeniusArrayList<Double>>(3,new GeniusArrayList<Double>());
        if(Base==0){
            return null;
        }
        int nNot0 = 0;
        double Num;
        for(int i=0;i<Y;i++){
            for(int j=0;j<X;j++){
                if((Num=Matrix.get(i,j))!=0){
                    nNot0++;
                    COOMatrix.get(0).add(i*1.0);
                    COOMatrix.get(1).add(j*1.0);
                    COOMatrix.get(2).add(Num);
                }
            }
        }
// defualtSparsityFactor = 0.05;
        if((nNot0/Base)>defualtSparsityFactor){
            return null;
        }
        else{
            return new GeniusMatrix(COOMatrix);
        }
    }

 CSR和CSC压缩

/** Type=0 is compressed row
        Type=1 is compressed column **/
    public GeniusArrayList<GeniusArrayList<Double>> CompressedSparsityMatrix(int Type){
        if(Type==1||Type==0){
            return CompressedSparsityMatrix(this,Type);
        }
        return null;
    }

    private GeniusArrayList<GeniusArrayList<Double>> CompressedSparsityMatrix(GeniusMatrix Matrix,int Type){
        int X = Matrix.getX();
        int Y = Matrix.getY();
        int Base = X*Y;
        if(Base==0){
            return null;
        }
        GeniusArrayList<GeniusArrayList<Double>> COOMatrix = new GeniusArrayList<GeniusArrayList<Double>>(3,new GeniusArrayList<Double>());
        int nNot0 = 0;
        int Offset = 0;
        double Num;
        if(Type==1){
            int temp = Y;
            Y = X;
            X = temp;
        }
        for(int i=0;i<Y;i++){
            COOMatrix.get(0).add(Offset*1.0);
            int LineNot0 = 0;
            for(int j=0;j<X;j++){
                if((Num=Matrix.get(i,j))!=0){
                    nNot0++;
                    LineNot0++;
                    COOMatrix.get(1).add(i*1.0);
                    COOMatrix.get(2).add(Num);
                }
            }
            Offset+=LineNot0;
        }
        COOMatrix.get(0).add(nNot0*1.0);
        if((nNot0/Base)>defualtSparsityFactor){
            return null;
        }
        else{
            return COOMatrix;
        }
    }

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值