码迷,mamicode.com
首页 > 其他好文 > 详细

学习日志---矩阵表示及特殊矩阵压缩

时间:2015-08-27 11:20:35      阅读:254      评论:0      收藏:0      [点我收藏+]

标签:java算法

矩阵类:二维数组实现!!

每一行看成一个一维数组,在放入几个集合里面即可;

用到random类,可以生产随机数,括号里是最大值;

矩阵类:
public class MyMatrix {
   
	int[][] matrix ;//矩阵数组
	Random random =new Random() ;//随机数对象
	
	//默认的构造方法,生成3*3的矩阵
	public MyMatrix()
	{
	        //默认是3*3矩阵
		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++)
  	   {
  	          //这里可以j<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];
   			 }
   			 
   		   } 	 
       }
    }
}


对称矩阵的压缩算法:

把下三角或者上三角存在一维数组中;

把二维数组中的数据三角式的一行一行的存在一维数组中,取出时,对应n*n循环,找出一维数组中的位置对应数据存在二维数组中,即为二维数组。

//对称矩阵类压缩
public class SynmeMatrix {
  
        //a用来存储矩阵的副本
	double [] a;//矩阵元素
	int n; //矩阵的阶数;
	int m; //一维数组的个数
	
	public SynmeMatrix(int n)
	{
		//需要保持的元素个数是m=n*(n+1)/2 ;
		//这里要注意m的大小
		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]);
                              //把b中的数据存到a这个副本中
                              //因为是对称阵,三角式的一行一行的存里面,这样起到节省空间的作用
	  			  a[k++]=b[i][j]; //只保存下三角元素
	  		   }
	  		}
	  	}
		
	}
	
	//通过一个一维数组来初始化,那么这个一维数组就是对称矩阵元素的副本
        //b为副本,传进来,因此与a相等
	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++)
		   {
                           //k是指副本中的位置,根据i和j找到对应该位置的值,两个synmeMatrix相同,因此具有的规则一样
			   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();
		   }
	}
}

稀疏矩阵压缩算法:

只存储数据的位置和元素,用三元组存储;

三元组的存储结构可以用一维数组或者链表结构;

这里用到了前面的MyVector集合存储非零数据信息;

下面是用数组的结构建立的系数矩阵;

//三元组类,非零元素的信息,行、列、数据
//每个节点都是一个数据点
public class Three {

	public int row;
	public int col;
	public double value;

	public Three(int r,int c,double v)
	{
		this.row = r;
		this.col = c;
		this.value = v;
	}
	
	public Three()
	{
		this(0,0,0.0);
	}
	
}

//稀疏矩阵类
//需要行和列,以及非零元素个数和位置即可
public class SpaMatrix {
   
	int rows; //行数
	int cols; //列数
	int dNum;//非零元素个数
	//v是存非零元素的集合,v中的顺序不重要,因为都是相互独立的
    MyVector v;
    
    SpaMatrix(int max)
    {
    	rows = cols = dNum=0;
    	v = new MyVector(max);
    }
    
    //根据用户传来的三元组数组,来初始化矩阵
    public void evaluate(int r,int c,int d,Three[] item)throws Exception
    {
    	this.rows = r;
    	this.cols = c;
    	this.dNum = d;
    	for(int i=0;i<d;i++)
    	{
    		v.add(i, item[i]);
    	}
    }
    
    //稀疏矩阵的转置
    public SpaMatrix transport()throws Exception
    {
        //稀疏矩阵只需要非零元素的位置和数据,因此构建时传入v的大小即可;
    	SpaMatrix a = new SpaMatrix(v.size());
    	a.rows = this.cols;
    	a.cols = this.rows;
    	a.dNum = this.dNum;
    	
    	for(int i=0;i<dNum;i++)
    	{
    		Three t = (Three)v.get(i);
    	    a.v.add(i, new Three(t.col,t.row,t.value));
    	}
    	return a;
    }
    
    //打印稀疏矩阵的方法
    public void print() throws Exception
    {
    	System.out.println("矩阵的行数:"+this.rows);
    	System.out.println("矩阵的列数:"+this.cols);
    	System.out.println("非零元素个数:"+this.dNum);
    	
    	System.out.println("矩阵三元组为:");
    	for(int i=0;i<dNum;i++)
    	{
    	   System.out.println("a<"+((Three)v.get(i)).row+","+((Three)v.get(i)).col+">="+((Three)v.get(i)).value);	
    	}
    }
}


也可用链表结构实现:

技术分享图片不清楚,文字说明:每个节点都存位置信息,数据信息和下一个节点位置,这种方法不是很好。


数组与链式结构相结合:

技术分享

图片不清楚,文字说明:这种方法比较好的地方就是很清晰,数组记录行,后面的链表记录该行内列的信息,依次连接。



学习日志---矩阵表示及特殊矩阵压缩

标签:java算法

原文地址:http://wukong0716.blog.51cto.com/10442773/1688710

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!