(十四)矩陣類與對稱矩陣的壓縮算法

矩陣類

矩陣是工程設計中經常使用的數學工具。
矩陣的運算主要有矩陣加、矩陣減、矩陣乘、矩陣轉置、矩陣求逆等。
矩陣用兩維數組處理最爲方便。
二維數組存儲結構。 

設計矩陣類
import java.util.Random;


public class MyMatrix {
   
	int[][] matrix ;//矩陣數組
	Random random =new Random() ;//隨機數對象
	
	//默認的構造方法,生成3*3的矩陣
	public MyMatrix()
	{
		matrix = new int[3][3];
		//初始矩陣
		for(int i=0;i<matrix.length;i++)
		{
			for(int j=0;j<matrix[i].length;j++)
			{
				matrix[i][j]=random.nextInt(100);
			}
		}
	}
	
	//生成方陣的構造方法
	public MyMatrix(int n)
	{
	    matrix = new int[n][n];
	    //初始矩陣
		for(int i=0;i<matrix.length;i++)
		{
			for(int j=0;j<matrix[i].length;j++)
			{
				matrix[i][j]=random.nextInt(100);
			}
		}
	}
	
	//生成一個m*n的矩陣。
	public MyMatrix(int m,int n)
	{
		matrix = new int[m][n];
		//初始矩陣
		for(int i=0;i<matrix.length;i++)
		{
			for(int j=0;j<matrix[i].length;j++)
			{
				matrix[i][j]=random.nextInt(100);
			}
		}
	}
	
	//根據已知二維數組,生成矩陣
	public MyMatrix(int[][] matrix)
	{
		this.matrix = matrix;
	}
	
	//返回矩陣數組
	public int[][] getMatrix()
	{
		return this.matrix;
	}
	
	//打印矩陣
	public void print()
	{
		for(int i=0;i<matrix.length;i++)
		{
			for(int j=0;j<matrix[i].length;j++)
			{
				System.out.print(matrix[i][j]+" ");
			}
			System.out.println();
		} 	
	}
	
	//轉置矩陣
	public MyMatrix transport()
	{
	    //行變列
		int m = matrix[0].length;
		//列變行
		int n = matrix.length;
		
		MyMatrix transMatrix = new MyMatrix(m,n);
		//初始化
		for(int i=0;i<transMatrix.matrix.length;i++)
		{
			for(int j=0;j<transMatrix.matrix[i].length;j++)
			{
				transMatrix.matrix[i][j] = matrix[j][i];
			}
		}
		return transMatrix;
	}
	
	//判斷矩陣是否是上三角矩陣
	public boolean isUpTriangle()
	{
	   for(int i=1;i<matrix.length;i++)
	   {
		   for(int j=0;j<i;j++)
		   {
			   if(matrix[i][j]!=0)
			   {
				   return false;
			   }
		   }
	   }
	   return true;
	}
	
	//判斷是否是下三角矩陣
    public boolean isDownTriangle()
    {
    	for(int i=0;i<matrix.length;i++)
    	{
    		for(int j=matrix[i].length-1;j>i;j--)
    		{
    		   if(matrix[i][j]!=0)
  			   {
  				   return false;
  			   }
    		}
    	}
    	return true;
    }
    
    //判斷是否是對稱矩陣
    public boolean isSynmetry()
    {
       for(int i=1;i<matrix.length;i++)
  	   {
  		  for(int j=0;j<matrix[i].length;j++)
  		  {
  			  if(matrix[i][j]!=matrix[j][i])
  			  {
  				  return false;
  			  }
  		  }
  	   }
  	   return true;
    }
    
    //矩陣求和
    public void add(MyMatrix b)
    {
       int m = b.matrix.length;
       int n = b.matrix[0].length;
       if(m!=matrix.length||n!=matrix[0].length)
       {
    	   System.out.println("矩陣類型不相同,無法相加!");
       }
       else
       {
    	   for(int i=0;i<matrix.length;i++)
   		   {
   			 for(int j=0;j<matrix[i].length;j++)
   			 {
   				matrix[i][j]+=b.matrix[i][j];
   			 }
   			 
   		   } 	 
       }
    }
}

public class TestMyMatrix {

	public static void main(String[] args) {
		
		MyMatrix m1 = new MyMatrix();
		MyMatrix m2 = new MyMatrix(4);
		System.out.println("m1矩陣:");
		m1.print();
		System.out.println("m2矩陣:");
		m2.print();
		
		MyMatrix m3 = m2.transport();
		System.out.println("m2轉置後:");
		m3.print();
		
		System.out.println(m3.isDownTriangle());
		MyMatrix m4 = new MyMatrix(
		   new int[][]{
			   {1,0,0,0},
			   {2,3,0,0},
			   {4,5,6,0},
			   {7,8,9,10}
		   }		
		);
		System.out.println(m4.isDownTriangle());
		
		MyMatrix m5 = new MyMatrix(
				   new int[][]{
					   {1,2,4,7},
					   {2,3,5,8},
					   {4,5,6,9},
					   {7,8,9,10}
				   }		
				);
		
		System.out.println(m5.isSynmetry());
		m4.add(m5);
		m4.print();
	}

}

特殊矩陣
特殊矩陣是指這樣一類矩陣,其中有許多值相同的元素或有許多零元素,且值相同的元素或零元素的分佈有一定規律。一般採用二維數組來存儲矩陣元素。但是,對於特殊矩陣,可以通過找出矩陣中所有值相同元素的數學映射公式,只存儲相同元素的一個副本,從而達到壓縮存儲數據量的目的。
特殊矩陣的壓縮存儲
只存儲相同矩陣元素的一個副本。此種壓縮存儲方法是:找出特殊矩陣數據元素的分佈規律,只存儲相同矩陣元素的一個副本。
n階對稱矩陣的壓縮存儲對應關係

  aij=aji   1<=i<=n,1<=j<=n

 元素個數m = n*(n+1)/2

打印對稱矩陣第i行,第j列的元素,與一維數組的下標關係爲:

         i*(i-1)/2+j-1  當i>=j

 k=

         j*(j-1)/2+i-1  當i<j

採用不等長的二維數組
Java語言支持不等長的二維數組,對於n階對稱矩陣,也可以通過只申請存儲下三角(或上三角)矩陣元素所需的二維數組,來達到壓縮存儲的目的。
不等長的二維數組結構

//對稱矩陣類
public class SynmeMatrix {
  
	double [] a;//矩陣元素
	int n; //矩陣的階數;
	int m; //一維數組的個數
	
	public SynmeMatrix(int n)
	{
		//需要保持的元素個數是m=n*(n-1)/2 ;
		m = n*(n+1)/2 ;
		a = new double[m];
		this.n = n;
	}
	//通過一個二維數組來初始化
	public void evaluate(double[][] b)
	{
	  	int k=0;
	  	for(int i=0;i<n;i++)
	  	{
	  		for(int j=0;j<n;j++)
	  		{
	  		   if(i>=j)	
	  		   {
	  		      //System.out.println("a["+k+"]="+b[i][j]);
	  			  a[k++]=b[i][j]; //只保存下三角元素
	  		   }
	  		}
	  	}
		
	}
	
	//通過一個一維數組來初始化,那麼這個一維數組就是對稱矩陣元素的副本
	public void evaluate(double[] b)
	{
		for(int k=0;k<m;k++)
		{
			a[k]= b[k];
		}
	}
	
	//對稱矩陣相加
	public SynmeMatrix add(SynmeMatrix b)
	{
	   SynmeMatrix t = new SynmeMatrix(n);
	   int k;
	   for(int i=1;i<=n;i++)
	   {
		   for(int j=1;j<=n;j++)
		   {
			   if(i>=j)
			   {
				   k= i*(i-1)/2+j-1;
			   }
			   else
			   {
				   k= j*(j-1)/2+i-1;
			   }
			   t.a[k] = a[k]+b.a[k];
		   }
	   }
	   return t;
	}
	
	//打印對稱矩陣
	public void print()
	{
		   int k;
		   for(int i=1;i<=n;i++)
		   {
			   for(int j=1;j<=n;j++)
			   {
				   if(i>=j)
				   {
					   k= i*(i-1)/2+j-1;
				   }
				   else
				   {
					   k= j*(j-1)/2+i-1;
				   }
				   System.out.print(" "+a[k]);
			   }
			   System.out.println();
		   }
	}
}

public class TestSynmeMatrix {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
        
		SynmeMatrix m1 = new SynmeMatrix(3);
		SynmeMatrix m2 = new SynmeMatrix(3);
		SynmeMatrix m3;
		
		double[][] a ={{1,0,0},{2,3,0},{4,5,6}};
		double[] b = {1,2,3,4,5,6};
		
		m1.evaluate(a);
		m2.evaluate(b);
		
		System.out.println("m1對稱矩陣:");
		m1.print();
		System.out.println("m2對稱矩陣:");
		m2.print();
		
		m3=m1.add(m2);
		System.out.println("m3對稱矩陣:");
	    m3.print();
	    
	}

}



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章