对角矩阵压缩算法

对于一个存在着多个0,且其具有一定的规律的矩阵,该如何将其压缩存储,以节省空间呢?
下面笔者就将带你探索矩阵的压缩算法。

首先,我们需要一个特殊的,具有规律的矩阵,笔者以老师上课给的题目为例。

从图中我们可以发现,这是一个较为特殊的矩阵。首先,以对角线为划分,我们可以发现在对角线右边都有2个数字,且直到倒数第三还有两位数字,但是倒数第二行和倒数第一行分别只有1和0。

由上述规律,我们可以开始构造这个矩阵的模型。我们令其为nxn阶矩阵,设从第一行到第(n-d)行的对角线右边的非零数字的个数为d,对角线左边的非零个数是从0到(d-1);第(n-d-1)行至第n行的对角线右边的非零数字的个数从(d-1)到0,对角线左边的非零个数是d。

我们初步的压缩思路是将该矩阵中的非零元素按行先序的顺序放置到一个一维数组s[]中,从去除零元素的存储空间来达成存储空间的节省,从而实现矩阵的压缩。

所以,我们需要先得知矩阵的非零元素的个数,从而可以得知存放非零元素的一维数组s[]所需的大小。

我们在上面构造模型的时候就讲过该矩阵的规律,所以我们将利用此规律来计算矩阵中非零元素的个数。首先,我们可以发现对角线左边与对角线右边有着相似的规律,比如大部分的行在对角线的左右两侧都有d个非零元素。于是,我们可以先将没有满足条件的行在其前后用数来补全,以满足条件。
如下图所示:

该图就是将第一行第二行,倒数第一行倒数第二行的前后用数补全,使其在对角线的左右两侧都有d个非零元素。

这样操作过后我们就可以计算得出每行共有(2d+1)个非零元素,且总共有n行,故整个矩阵共有(2d+1)n个非零元素。但是因为有一部分的非零元素是我们为了计算方便而补全的,故我们需要去除掉这些人为补全的数。这些数我们观察可以发现,每侧都是补了d到1个数,所以每侧补了(d+1)d/2个非零元素,但是因为对角线两边都补了,所以共补了(d+1)d个数。

于是,我们可以计算得出,矩阵原本的非零元素个数为(2d+1)n-d(d+1)。于是,我们可以知道一维数组s[]的大小,其最小也应有(2d+1)n-d(d+1)个存储空间。

我们现在已经知道了数组s[]的大小和矩阵非零元素的个数,该如何将矩阵的非零元素按行先序对应到数组中呢,这是我们接下来要解决的问题。

首先,比较简单的是可以利用循环算法,遍历矩阵,遇到非零元素就将其放入数组s[]中,以实现矩阵与数组的对应。但是我们可以发现,这样虽然很简单,但是时间复杂度是n^2,非常耗时,显然不是最优解。我们应该利用该矩阵的特殊性质,找到s[]与矩阵的真正的对应公式,这样才会比较方便与快捷,也才能真正实现对角矩阵的压缩。

由于笔者数学较弱,故虽然计算了很久,但是仍然无法算出具有普遍代表性的对应公式,只有较为粗糙且有限制条件的对应公式,下图即为笔者算出的矩阵A与数组S的对应公式:

所以,以上就是笔者的对角矩阵压缩算法,目前由于笔者的能力等问题,只有理论而缺乏代码展示,且公式也不是很具有代表性,如果有高人可以为我指点迷津笔者感激不尽。

posted @ 2020-10-23 01:41  gustavek  阅读(516)  评论(0)    收藏  举报