php代码

<?php

/*************************************************************************************************/* 本程序是专门用来处理解释结构模型ISM中相关的矩阵运算,主要概念有如
* 算子:
* 单位矩阵:
* 可达矩阵:
* 可达步骤以及对应的矩阵:
* λ 截距:
* 先行集合:
* 可达集合:
* 骨架矩阵:
* 要素抽取获得缩减矩阵:
*/
class ism_mat
{
	//全局变
	var $array_number = array(); //以数组形式表达矩阵
	var $element = 1;            //布尔矩阵中的要素 默认为1,表示1*1的矩阵
	var $numColumns = 0;         //矩阵列的数目 这个是冗余的参数本矩阵就是等于要素的
	var $numRows = 0;            //矩阵行的
	var $element_name= array();            // 要素的名称
	/***********************************************************************
	 *构造 ism_matrix 的类型
	 * 参数类型 ( 二维数组,整型) (array(1=>array(1,2,2,3,)2=>array(4,6,5,7)),6)
	 * 对值大于1的强制转换成模糊数字型
	 *  new ism_mat(6) 类似的给出一个6*6的矩阵
	 ***********************************************************************/
	function ism_mat()
	{
		$nArgs = func_num_args();
		if ($nArgs == 0)
		{
			$array_number=array();
			$this->element = 3;
			$this->numRows = 3; //行    从   获得第二
			$this->numColumns = 3;//列  从   第二个参数获
		}
		if ($nArgs == 1 )
		{
			if(is_array(func_get_arg(0)))
			{
				$array_number = func_get_arg(0);
			}
			else
			{
				if(is_int(func_get_arg(0)))
				{
					$this->element = func_get_arg(0);
				}
				$array_number=array();
			}
		}
		if($nArgs == 2) //如果是2
		{
			$array_number = func_get_arg(0);
			$this->element = func_get_arg(1);  //要素  从第二个参数获
			$this->numRows = func_get_arg(1); //行    从   获得第二
			$this->numColumns = func_get_arg(1);//列  从   第二个参数获
		}
		if($nArgs > 2) //如果是3
		{
			$array_number = func_get_arg(0);
			$this->element = func_get_arg(1);  //要素  从第二个参数获
			$this->numRows = func_get_arg(1); //行    从   获得第二
			$this->numColumns = func_get_arg(1);//列  从   第二个参数获
			$this->element_name=func_get_arg(2);//要素的名称
		}
		$numberColumns = 0; //
		$numberRows = 0;    //
		if(empty($array_number) == false) //数组内容不为空
		{
			foreach($array_number as $i => $rows) //检查
			{
				foreach($rows as $j => $number) //如果值为0则移除
				{
					if($number != 0 && abs($number)<=1 )
					{
						$this->array_number[$i][$j] = $number;
					}
					if ($number != 0 && abs($number)>1)
					{
						$this->array_number[$i][$j] = 1;
					}
					if($j >= $numberColumns)
					{
						$numberColumns = $j;
					}
				}
				if($i >=$numberRows)
				{
					$numberRows = $i;
				}
			}
			//php的数组下标定义为0开始,加1符合数学上的习惯
			$numberRows++;
			$numberColumns++;
		}
		$name_count=count($this->element_name);
		$maxlen=max($numberRows , $this->numRows,$numberColumns ,$this->numColumns,$this->element,$name_count);
		$this->numRows = $maxlen;
		$this->numColumns = $maxlen;
		$this->element = $maxlen;
		if($name_count <=$maxlen)
		{
			$i=0;
			$name=$this->element_name;
			//print_r($name);
			unset($this->element_name);
			foreach($name as $v)
			{
				$this->element_name[$i]=$v;
				$i++;
			}

			for ($i=$name_count;$i<$maxlen;$i++)
			{
				$this->element_name[$i]=$i.'号';
			}
		}
	}


	/***************************************************************
	 * ISM矩阵变换
	 * 输入新的名字数组$arrayname(name1…… name_n )
	 * 这个名字数组必须与原来的 ism对象中的 一样,顺序
	 *  根据新的排列,返回一个新的 ism矩阵
	 **************************************************************/
	function transform_by_name($new_name_array)
	{
		$old_name_array=$this->element_name;
		$numb=$this->array_number;
		$result = array_diff($old_name_array, $new_name_array);
		$e=$this->element;
		if(empty($result)== true && $this->element==count($new_name_array))
		{
			//检查输入的名字列表是

			$get_name_old_num=array();
			for($k=0;$k<$e;$k++)
			{
				//获得名称原来的序号
				$get_name_old_num[$k] = array_search($new_name_array[$k], $old_name_array);
			}
			for($i=0;$i<$e;$i++)
			{
				for($j=0;$j<$e;$j++)
				{
					$old_x=$get_name_old_num[$i];
					$old_y=$get_name_old_num[$j];
					if(empty($numb[$old_x][$old_y]) == false)
					{
						$new_array_number[$i][$j]=1;
					}
					else
					{
						unset($new_array_number[$i][$j]);
					}
				}
			}
		}
		else
		{
			echo" 输入的名字跟原来变换的不同,所有的名字要相同!";
		}
		$new_mat=new ism_mat($new_array_number,$e,$new_name_array);
		return $new_mat ;
	}


	/***************************************************************
	 *元素互换,获得一个新的矩阵
	 *  0 7   表示第1个与 第8个交换
	 **************************************************************/
	function exchange_e_by_num($num_1, $num_2)
	{
		$e=$this->element;
		$new_mat=new ism_mat($this->array_number,$e,$this->element_name);
		if($num_1<$e and $num_2<$e and $num_1!=$num_2)
		{
			for($i=0;$i<$e;$i++)
			{
				if($i!=$num_1 and $i!=$num_2)
				{
					$new_mat->array_number[$num_2][$i]=$this->array_number[$num_1][$i];
					$new_mat->array_number[$i][$num_2]=$this->array_number[$i][$num_1];
					$new_mat->array_number[$num_1][$i]=$this->array_number[$num_2][$i];
					$new_mat->array_number[$i][$num_1]=$this->array_number[$i][$num_2];
				}
				else
				{
					$new_mat->array_number[$num_2][$num_1]=$this->array_number[$num_1][$num_2];
					$new_mat->array_number[$num_2][$num_2]=$this->array_number[$num_1][$num_1];
					$new_mat->array_number[$num_1][$num_1]=$this->array_number[$num_2][$num_2];
					$new_mat->array_number[$num_1][$num_2]=$this->array_number[$num_2][$num_1];
				}
			}
			$new_mat->element_name[$num_2]=$this->element_name[$num_1];
			$new_mat->element_name[$num_1]=$this->element_name[$num_2];
		}

		return $new_mat ;
	}

	/***************************************************************
	 * 通过元素名称交换,获得 ism中的布尔矩阵的值,返回矩阵中所有的
	 **************************************************************/
	function exchange_e_by_name($name_1, $name_2)
	{
		$e=$this->element;
		$num_1 = array_search($name_1, $this->element_name);
		$num_2 = array_search($name_2, $this->element_name);
		//print_r($num_2);
		if( $num_1>=0 and $num_2>=0 )
		{
			$new_mat=$this->exchange_e_by_num($num_1,$num_2);
			//print_r($new_mat);
		}
		else
		{
			echo "输入的要换的要素名称有错误,滴点眼药水,看看。为了不影响您计算,返回原来的矩阵";
			//$new_mat=$this;
			//$new_mat=new ism_mat($this->array_number,$this->element,$this->element_name);
		}

		return $new_mat ;
	}
	/***************************************************************
	 * 获得 ism中的布尔矩阵的值,返回矩阵中所有的
	 **************************************************************/
	function get_data()
	{
		for($i = 0; $i < $this->element; $i++)
		{
			for($j = 0; $j < $this->element; $j++)
			{
				if(empty($this->array_number[$i][$j]) == false)
				{
					$the_numbers[$i][$j] = $this->array_number[$i][$j];
					$the_numbers[$i][$j]>=1 ? 1: $the_numbers[$i][$j];
					$the_numbers[$i][$j]<=0.0001? 0: $the_numbers[$i][$j];
					$the_numbers[$i][$j]=='' ? 0:$the_numbers[$i][$j];
				}
				else
				{
					$the_numbers[$i][$j] = 0;
				}
			}
		}
		return $the_numbers;
	}

	/***************************************************************
	 * 得到相乘矩阵 即原始矩阵+单位矩阵
	 **************************************************************/
	function b()
	{
		for($i = 0; $i < $this->element; $i++)
		{
			for($j = 0; $j < $this->element; $j++)
			{
				if(empty($this->array_number[$i][$j]) == false )
				{
					$the_numbers[$i][$j] = $this->array_number[$i][$j];
					$the_numbers[$i][$j]>=1?1:$the_numbers[$i][$j];
					$the_numbers[$i][$j]<=0?0:$the_numbers[$i][$j];

				}
				else
				{
					$the_numbers[$i][$j] = 0;
				}

			}
		}
		for($i = 0; $i < $this->element; $i++)
		{
			$the_numbers[$i][$i]=1;
		}
		$the_b_mat=new ism_mat($the_numbers,$this->element,$this->element_name);
		return $the_b_mat;
	}


	/**************************************************************************
	 * 返回某个矩阵坐标的值  即对应行与列元素的值,注意下标
	 *************************************************************************/
	function get_value($i, $j)
	{
		$the_value = 0;
		if($i-1 < $this->get_num_rows() and $j-1 < $this->get_num_columns())
		{
			if(empty($this->array_number[$i-1][$j-1]) == false)
			{
				$the_value = $this->number[$i-1][$j-1];
			}
		}
		else
		{
			echo "<br><br>\n\n\n  搞错了注意参数,超过了ism矩阵中的要素的值的范围 !\n\n\n\<br><br>";
		}
		return $the_value;
	}

	/**************************************************************************
	 * 返回ism_矩阵的求解可达矩阵,过程中所有的矩阵
	 * 返回矩阵格式对象
	 * 格式为  array(1=>ism_mat(data1),
	 				2=>ism_mat(data2),……)
	 *************************************************************************/
	function get_r_mat_step_data()
	{
		$i=1;
		$i_mat= $this->i();
		$b=$this->plus($i_mat);
		$r_mat_step_data[1]=$b;
		while ($i < 50 and $r_mat_step_data[$i]!=$r_mat_step_data[$i-1])
		{
			$r_mat_step_data[$i+1]=$r_mat_step_data[$i]->muti($b);
			$i++;
		}
		return $r_mat_step_data;
	}

	/**************************************************************************
	 * 返回可达矩阵
	 * 矩阵
	 *************************************************************************/
	function r_mat()
	{
		$r_step=$this->get_r_mat_step_data();
		$the_last=$r_step[count($r_step)-1];
		$the_reached_matrix =new ism_mat ($the_last->array_number,$the_last->element,$the_last->element_name);
		return $the_reached_matrix;
	}

	/**************************************************************************
	 * 返回层次分解模型的各个步骤,超级傻逼的一个过程!!!此过程为结果优先
	 * 返回 一个数组
	 * 格式为  array(1=>array( 可达矩阵(), 可达矩阵转置, 上面两个的交集, lev_e=),
	 *               2=>array( 可达矩阵(), 可达矩阵转置, 上面两个的交集, lev_e=),
	 *                                              )
	 *
	 *************************************************************************/
	function get_r_f_level_data()
	{
		if($this->is_r_mat($this)==true)
		{
			$reached_matrix=$this;
		}
		else
		{
			$reached_matrix=$this->r_mat();//可达矩阵
		}
		$reached_transpose_matrix = $reached_matrix->transpose();//可达矩阵的转置矩阵
		$reached_meet_matrix = $reached_matrix->meet($reached_transpose_matrix);//交集矩阵
		$array_e_zero =array();
		//$the_mat_level_data[1]= array(r_mat=>$reached_matrix,t_mat=>$reached_transpose_matrix,m_mat=>$reached_meet_matrix,lev=>$level_element);
		//print_r($the_mat_level_data[1]);
		$j=1;

		do
		{
			$array_e_zero=array();
			for ($len=0;$len<$reached_matrix->element;$len++)
			{
				$a_line    = $reached_matrix->array_number[$len];
				$meet_line = $reached_meet_matrix->array_number[$len];
				if($a_line==$meet_line and empty($a_line)==false)
				{
					$array_e_zero[$len]=$len;
				}
			}

			if (empty($array_e_zero)==false)
			{
				$the_mat_level_data[$j][r_mat]=$reached_matrix;
				$the_mat_level_data[$j][t_mat]=$reached_transpose_matrix;
				$the_mat_level_data[$j][m_mat]=$reached_meet_matrix;
				$the_mat_level_data[$j][lev]=$array_e_zero;
				$reached_matrix = $reached_matrix->set_e_zero($array_e_zero);
				$reached_transpose_matrix = $reached_transpose_matrix->set_e_zero($array_e_zero);
				$reached_meet_matrix=$reached_meet_matrix->set_e_zero($array_e_zero);
			}
			$j++;
		}
		while( empty($array_e_zero)==false and $j <= $reached_matrix->element);
		return $the_mat_level_data;
	}

	/**************************************************************************
	 * 返回层次分解模型的各个步骤,的一个过程!!!此过程为原因优先g_frist_
	 * 返回 一个数组
	 * 格式为  array(1=>array( 可达矩阵(), 可达矩阵转置, 上面两个的交集, lev_e=),
	 *               2=>array( 可达矩阵(), 可达矩阵转置, 上面两个的交集, lev_e=),
	 *                                              )
	 *************************************************************************/
	function get_g_f_level_data()
	{
		if($this->is_r_mat($this)==true)
		{
			$reached_matrix=$this;

		}
		else
		{
			$reached_matrix=$this->r_mat();//可达矩阵
		}
		$reached_transpose_matrix = $reached_matrix->transpose();//可达矩阵的转置矩阵
		$reached_meet_matrix = $reached_matrix->meet($reached_transpose_matrix);//交集矩阵
		$array_e_zero =array();
		//$the_mat_level_data[1]= array(r_mat=>$reached_matrix,t_mat=>$reached_transpose_matrix,m_mat=>$reached_meet_matrix,lev=>$level_element);
		//print_r($the_mat_level_data[1]);
		$j=1;

		do
		{
			$array_e_zero=array();
			for ($len=0;$len<$reached_matrix->element;$len++)
			{
				$a_line    = $reached_transpose_matrix->array_number[$len];//就这个地方
				$meet_line = $reached_meet_matrix->array_number[$len];
				if($a_line==$meet_line and empty($a_line)==false)
				{
					$array_e_zero[$len]=$len;
				}
			}

			if (empty($array_e_zero)==false)
			{
				$the_mat_level_data[$j][r_mat]=$reached_matrix;
				$the_mat_level_data[$j][t_mat]=$reached_transpose_matrix;
				$the_mat_level_data[$j][m_mat]=$reached_meet_matrix;
				$the_mat_level_data[$j][lev]=$array_e_zero;
				$reached_matrix = $reached_matrix->set_e_zero($array_e_zero);
				$reached_transpose_matrix = $reached_transpose_matrix->set_e_zero($array_e_zero);
				$reached_meet_matrix=$reached_meet_matrix->set_e_zero($array_e_zero);
			}
			$j++;
		}
		while( empty($array_e_zero)==false and $j <= $reached_matrix->element);
		return $the_mat_level_data;
	}

	/**************************************************************************
	 * 返回ism的区域划分,也就是,系统个数,各个系统有什么要素组成
	 * 返回二维数组,
	 *************************************************************************/
	function get_group()
	{
		$arraygroup=array();
		$bmatrix= $this->b();
		$transpose=$this->transpose();
		$u=$bmatrix->plus($transpose);
		$g=$u->r_mat();
		$data=$g->get_data();
		for ($k=0;$k<count($data);$k++)
		{
			$is_in=false;
			for($j=0;$j<$k;$j++)
			{
				if($data[$j]==$data[$k])
				{
					$is_in=true;
				}
			}
			if($is_in==false)
			{
				$arraydata[$k]=$data[$k];
			}
		}
		$i=0;
		foreach($arraydata as $v1)
		{
			$j=0;
			foreach($v1 as $key=>$v)
			{
				if($v==1)
				{
					$arraygroup[$i][$j]=$key;
				}
				$j++;
			}
			$i++;
		}
		return $arraygroup;
	}

	/*****************************************************************************
	*  获得矩阵内最大的独立系统
	*  返回其中的
	***************************************************************************/
	function get_max_group_mat ()
	{
		$arraygroup=$this->get_group();
		$size=array();
		foreach($arraygroup as $k=>$v)
		{
			$size[$k]=count($v);
		}
		$max_group_size=max($size);
		$max_group_size_index=array_search($max_group_size, $size);
		$max_group=$arraygroup[$max_group_size_index];
		$the_tmp_mat= $this;
		$the_max_group_mat=$the_tmp_mat->group_mat_by_num ($max_group);
		$the_max_group_mat= new ism_mat($the_max_group_mat->array_number,$the_max_group_mat->element,$the_max_group_mat->element_name);
		return $the_max_group_mat;
	}



	/*****************************************************************************
	*  输入一个数组
	*  或者输入一组 数字的系列。 如 0、1、2、3、4、没有检查重复度,请调用的时候自动检测
	*   矩阵是下标以 0开始的
	* 返回 矩阵,要素是里面对应的要素的
	*   给出一个新的矩阵, 要素为输入的里面的要素
	***************************************************************************/
	function group_mat_by_num ()
	{
		$nArgs = func_num_args();
//				print_r($nArgs);
		if ($nArgs == 0)
		{
			echo "没有输入的要素";
		}
		if ($nArgs == 1 )
		{
			if(is_array(func_get_arg(0)))
			{
				$array_num = func_get_arg(0);
			}
			elseif(is_int(func_get_arg(0)))
			{
				$array_num[0] =func_get_arg(0);
			}
			else
			{
				echo"输入要素的格式错误";
			}
		}
		if ( $nArgs >1 )
		{
			for($i=0;$i<$nArgs;$i++)
			{
				$array_num[$i]=func_get_arg($i);
			}
		}

		//对输入的要素的名称排序
		sort($array_num);
		for ($i=0; $i<count($array_num);$i++)
		{
			$element_name[$i]= $this->element_name[$array_num[$i]];
		}
//				print_r($element_name);
//				echo '<br>';
//				print_r($array_num);
		$the_new_group_mat=new ism_mat(array(),count($array_num),$element_name);
		$the_new_e= count($array_num);
		for ($x=0; $x<$the_new_e;$x++)
		{
			$old_x=$array_num[$x];
			for ($y=0; $y<$the_new_e;$y++)
			{
				$old_y=$array_num[$y];
				$the_new_group_mat->array_number[$x][$y]=$this->array_number[$old_x][$old_y];
			}
		}
		$the_new_group_mat=new ism_mat($the_new_group_mat->array_number,count($array_num),$element_name);
		return 	$the_new_group_mat;

	}

	/**************************************************************************
	 * 返回ism的区域划分,也就是,系统个数,各个系统有什么要素组成
	 * 返回二维数组,
	 * 数组由,要素名称组成
	 *************************************************************************/

	function get_group_e_name()
	{
		$arraygroup=array();
		$bmatrix= $this->b();
		$transpose=$this->transpose();
		$u=$bmatrix->plus($transpose);
		$g=$u->r_mat();
		$data=$g->get_data();
		for ($k=0;$k<count($data);$k++)
		{
			$is_in=false;
			for($j=0;$j<$k;$j++)
			{
				if($data[$j]==$data[$k])
				{
					$is_in=true;
				}
			}
			if($is_in==false)
			{
				$arraydata[$k]=$data[$k];
			}
		}
		$i=0;
		foreach($arraydata as $v1)
		{
			$j=0;
			foreach($v1 as $key=>$v)
			{
				if($v==1)
				{
					$arraygroup[$i][$j]=$key;
				}
				$j++;
			}
			$i++;
		}
		foreach($arraygroup as $i=>$group)
		{
			foreach($group as $j=>$num)
			{
				$arraygroup_name[$i][$j]=$this->element_name[$num];
			}
		}
		return $arraygroup_name;
	}

	/*****************************************************************************
	 *  输入的是一个数组,数组中每个值是整数 为要素素的序号
	 *
	 * 这个东西小心使用,比如删除 array(0,0,0,0,0,0,0,0,0,0)表示一直删除第一个要素
	 *意义
	 **************************************************************************/
	function del_e_by_some_num ($array_element_num)
	{
		$the_deduce=$this;
		foreach($array_element_num as $v)
		{
			$the_deduce=$the_deduce->del_e_by_num($v);
		}
		return $the_deduce;
	}

	/*****************************************************************************
	 *  输入的是一个元素,值是整数 为要素的序号
	 *   矩阵是下标以 0开始的
	 * 返回 矩阵,对应的行与列删除,其它值,对应的左移,与右移动,
	 *  矩阵变小
	 ***************************************************************************/
	function del_e_by_num ($element_num)
	{
		$e=$this->element;
		$element_name=$this->element_name;
		$new_element=$e-1;
		$new_element_name=array();
		$new_array_number=array();
		if(0<=$element_num and $element_num<$e)
		{
			for ($i=0;$i<$element_num;$i++)
			{
				$new_element_name[$i]=$element_name[$i];
			}
			for ($i=$element_num;$i<$e-1;$i++)
			{
				$new_element_name[$i]=$element_name[$i+1];
			}

			for ($i=0;$i<$e-1;$i++)
			{
				for ($j=0;$j<$e-1;$j++)
				{
					if( $i<$element_num and $j<$element_num)
					{
						$new_array_number[$i][$j]=$this->array_number[$i][$j];
					}
					elseif( $i<$element_num and $j>=$element_num)
					{
						$new_array_number[$i][$j]=$this->array_number[$i][$j+1];
					}
					elseif( $i>=$element_num and $j<$element_num)
					{
						$new_array_number[$i][$j]=$this->array_number[$i+1][$j];
					}
					elseif( $i>=$element_num and $j>=$element_num)
					{
						$new_array_number[$i][$j]=$this->array_number[$i+1][$j+1];
					}
				}
			}
			$the_new_deduce_mat=new ism_mat($new_array_number,$new_element,$new_element_name);
		}
		else
		{
			echo "<br><br>\n\n\n搞错了参数,回去面壁下,认真检查!要删除的要素的值, 的参数请注意!\n\n\n\<br><br>";
		}
		//$set_e_zero_mat = new ism_mat($this->array_number,$e );
		return 	$the_new_deduce_mat;

	}

	/*****************************************************************************
	 *  输入元素的名称,值是整数 为要素的序号
	 *   矩阵是下标以 0开始的
	 * 返回 矩阵,对应的行与列删除,其它值,对应的左移,与右移动,
	 *  矩阵变小
	 ***************************************************************************/
	function del_e_by_name ($name)
	{
		$element_num=array_search($name,$this->element_name);
		$the_new_deduce_mat=$this->del_e_by_num($element_num);
		return 	$the_new_deduce_mat;

	}

	 /*****************************************************************************
	 *  输入元素的名称,值是整数 为要素的序号
	 *   矩阵是下标以 0开始的
	 * 返回 矩阵,对应的行与列删除,其它值,对应的左移,与右移动,
	 *  矩阵变小
	 ***************************************************************************/
	function del_e_by_array_name ($arrayname)
	{
		$the_new_deduce_mat=$this;
		foreach($arrayname as $name)
		{
			$the_new_deduce_mat=$the_new_deduce_mat->del_e_by_name($name);
		}
		return 	$the_new_deduce_mat;

	}

	 /*****************************************************************************
	 *  输入一个数组
	 *  或者输入一组 数字的系列。 如 0、1、2、3、4、没有检查重复度,请调用的时候自动检测
	 *   矩阵是下标以 0开始的
	 * 返回 矩阵,对应的行与列删除,其它值,对应的左移,与右移动,
	 *  矩阵变小
	 ***************************************************************************/
	function del_e_by_array_num ()
	{
		$nArgs = func_num_args();
//				print_r($nArgs);
		if ($nArgs == 0)
		{
			echo "没有要删除的要素";
		}
		if ($nArgs == 1 )
		{
			if(is_array(func_get_arg(0)))
			{
				$array_num = func_get_arg(0);
			}
			elseif(is_int(func_get_arg(0)))
			{
				$array_num[0] =func_get_arg(0);
			}
			else
			{
				echo"输入要素的格式错误";
			}
		}
		if ( $nArgs >1 )
		{
			for($i=0;$i<$nArgs;$i++)
			{
				$array_num[$i]=func_get_arg($i);
			}
		}

		$the_new_deduce_mat=$this;
//				print_r($array_num);
		foreach($array_num as $num)
		{
			$arrayname[$num]=$the_new_deduce_mat->element_name[$num];

		}
		$the_new_deduce_mat=$the_new_deduce_mat->del_e_by_array_name($arrayname);
		return 	$the_new_deduce_mat;

	}
	/*****************************************************************************
	 *  输入的是一个数组,这里暂时不做严格边界处理,每个数组必须整
	 *   矩阵是下标以 0开始的
	 * 返回 矩阵,对应的行与列清零的矩阵
	 ***************************************************************************/
	function deduce_e_by_ring ($array_element_num)
	{
		$e=$this->element;
		$element_name=$this->element_name;
		$size=count($array_element_num);
		if($size<$e)
		{
			$new_e=$e-$size+1;
		}
		$min_num=min($array_element_num);
		$set_e_zero_mat = new ism_mat($this->array_number,$e ,$this->element_name);
		foreach($array_element_num as $i)
		{
			$the_group_name=$set_e_zero_mat->element_name[$i].'+'.$the_group_name;
		}
		$set_e_zero_mat->element_name[$min_num]=$the_group_name;
		if( 0<=min($array_element_num) and max($array_element_num)<$this->element )
		{
			foreach( $array_element_num as $the_num)
			{
				for($i=0;$i<$e;$i++)
				{
					if ($i==$min_num)
					{
						for ($j=0;$j<$e;$j++)
						{
							if ($set_e_zero_mat->array_number[$the_num][$j]==1 )
							{
								$set_e_zero_mat->array_number[$min_num][$j]=1;

							}
							if ( $set_e_zero_mat->array_number[$j][$the_num]==1)
							{
								$set_e_zero_mat->array_number[$j][$min_num]=1;
							}
						}
					}
				}
			}
			$the_new_mat=new ism_mat($set_e_zero_mat->array_number,$set_e_zero_mat->element,$set_e_zero_mat->element_name);
			foreach($array_element_num as $k=>$num)
			{
				if($num==$min_num)
				{
					unset($array_element_num[$k]);
				}
			}
			$the_new_mat=$the_new_mat->del_e_by_array_num($array_element_num);
		}
		else
		{
			echo "<br><br>\n\n\n搞错了参数,回去面壁下,认真检查!$array_element_num 的参数请注意!\n\n\n\<br><br>";
		}
		$the_new_mat=new ism_mat($the_new_mat->array_number,$the_new_mat->element,$the_new_mat->element_name);
		return $the_new_mat;
	}

	/**************************************************************************************
	 *  输入的是一个数组,数组里面为环路 用元素的名称标识,这里没有做严格的重复检查等等,调用的时候请注意
	 *   矩阵是下标以 0开始的
	 * 返回 矩阵,对应的行与列清零的矩阵
	 ***************************************************************************/

	function deduce_e_by_ring_name ($array_ring_name)
	{
		$array_ring_num=array();
		foreach($array_ring_name as $key=>$name)
		{
			$array_ring_num[$key]=array_search($name,$this->element_name);
		}
		$the_new_mat=$this->deduce_e_by_ring($array_ring_num);
		return $the_new_mat;

	}
	/**************************************************************************
	 * 返回ism的强连通子集,系统中构成环路的个数以及对应的组成
	 * 本处用的是一个经典的Tarjan算法 http://www.byvoid.com/blog/scc-tarjan/
	 * Robert Tarjan 的官方网站 http://www.cs.princeton.edu/~ret/
	 * 返回二维数组,
	 *************************************************************************/
	function get_ring_use_Tarjan()
	{

	}

	/**************************************************************************
	 * 返回ism的强连通子集,系统中构成环路的个数以及对应的组成
	 * 返回二维数组,
	 *************************************************************************/
	function get_ring()
	{
		$arrayring=array();
		$m=$this->r_mat(); //获得可达矩阵
		$m_t=$m->transpose(); //可达矩阵的转置矩阵
		$u=$m->meet($m_t); //可达矩阵 与  可达矩阵的转置矩阵  的 交集 矩阵
		$data=$u->get_data();
		for ($k=0;$k<count($data);$k++)
		{
			$is_in=false;
			for($j=0;$j<$k;$j++)
			{
				if($data[$j]==$data[$k])
				{
					$is_in=true;
				}
			}
			if($is_in==false)
			{
				$arraydata[$k]=$data[$k];
			}
		}
		$i=0;
		foreach($arraydata as $v1)
		{
			$j=0;
			foreach($v1 as $key=>$v)
			{
				if($v==1)
				{
					$arraytmp[$i][$j]=$key;
				}
				$j++;
			}
			if(count($arraytmp[$i])>1)
			{
				$arrayring[$i]=$arraytmp[$i];
			}
			$i++;
		}
		return $arrayring;
	}

	/**************************************************************************
	 * 返回ism的强连通子集,系统中构成环路的个数以及对应的要素名称
	 * 返回二维数组,
	 *************************************************************************/
	function get_ring_e_name()
	{
		$arrayring_e_name=array();
		$arrayring_e_number=$this->get_ring();
		foreach($arrayring_e_number as $k=>$array_name_index)
		{
			foreach($array_name_index as $j=>$num)
			{
				$arrayring_e_name[$k][$j]=$this->element_name[$num];
			}
		}
		return $arrayring_e_name;
	}
	/*****************************************************************************
	 * 给矩阵某一行某一列 的关系 赋值  $value 绝对值小于等于1,以后用来拓展的
	 ***************************************************************************/
	function set_value($i, $j, $value)
	{
		if($i-1 < $this->get_num_rows() and $j-1 < $this->get_num_columns())
		{
			if($value != 0 and abs($value)<=1)
			{
				$this->array_number[$i-1][$j-1] = $value;
			}
			elseif(abs($value)>1)
			{
				$this->array_number[$i-1][$j-1] = 1;
			}
			else
			{
				unset($this->array_number[$i-1][$j-1]);
			}
		}
		else
		{
			echo "<br><br>\n\n\n搞错了参数,回去面壁下,认真检查!set_value 的参数请注意!\n\n\n\<br><br>";
		}
	}

	/*****************************************************************************
	 * 清除某个要素,但是不减少矩阵的大小,注意此过程只是把对应的行与列清零
	 * 输入的是一个数组,这里暂时不做严格边界处理,每个数组必须整
	 *   矩阵是下标以 0开始的
	 * 返回 矩阵,对应的行与列清零的矩阵
	 ***************************************************************************/
	function set_e_zero ($array_element_num)
	{
		$e=$this->element;
		$set_e_zero_mat = new ism_mat($this->array_number,$e ,$this->element_name);
		if( 0<=min($array_element_num) and max($array_element_num)<$this->element )
		{
			foreach( $array_element_num as $the_num)
			{
				for($i=0;$i<$e;$i++)
				{
					unset($set_e_zero_mat->array_number[$the_num][$i]);
					unset($set_e_zero_mat->array_number[$i][$the_num]);
				}
			}
		}
		else
		{
			echo "<br><br>\n\n\n搞错了参数,回去面壁下,认真检查!$array_element_num 的参数请注意!\n\n\n\<br><br>";
		}
		return $set_e_zero_mat;
	}

	/*************************************************************************
	*随机填充根据矩阵要素的个数按比例填充,大于1的元素
	**********************************************************************/
	function rand_mat( $rate )
	{
		$random_numbers = array();
		$e = $this->element;
		if($rate==null || $rate<0)
		{
			$rate=2;
		}
		$totalnum=$rate * $e;
		for ($i=0; $i<$totalnum; $i++)
		{
			$x = mt_rand(0,$e-1);
			$y = mt_rand(0,$e-1);
			$random_numbers[$x][$y] = 1; //此处专门用来修改的,比如更改成模糊矩阵的方
		}
		$the_random_matrix = new ism_mat($random_numbers, $e,$this->element_name);
		return $the_random_matrix;
	}
	/*******************************************
	* 满阵 , 布尔矩阵中所有的值都为 1
	*******************************************/
	function ones()
	{
		$array_fill = array();
		$e= $this->element;
		for($i = 0; $i < $e; $i++)
		{
			for($j = 0; $j < $e; $j++)
			{
				$array_fill[$i][$j] = 1;
			}
		}
		$a_matrix_fill_ones = new ism_mat($array_fill,$e,$this->element_name);
		return $a_matrix_fill_ones;
	}


	/*****************************************************
	* 我日个去,查了下单位矩阵居然是叫 identity matrix.
	* 矩阵中对角线的全部为1,其它的全部为0
	*****************************************************/
	function i()
	{
		$e = $this->element;
		for($i = 0; $i < $e; $i++)
		{
			$id_numbers[$i][$i] = 1;
		}
		$the_identity_matrix = new ism_mat($id_numbers, $e,$this->element_name);
		return $the_identity_matrix;
	}

	/***************************************************
	* 计算转置矩阵  A_ij 变成 A_ji
	* A' is $A->transpose() 转置矩阵
	*****************************************************/
	function transpose()
	{
		foreach($this->array_number as $i => $row)
		{
			foreach($row as $j => $number)
			{
				$the_transpose_data[$j][$i] = $number;
			}
		}
		$the_transpose = new ism_mat($the_transpose_data, $this->element,$this->element_name);
		return $the_transpose;
	}


	/************************************************************************
	 * 布尔矩阵相乘没有运用到具体的算子 采用的是大于1就等于1的截 的方
	 * A x B is $A->muti($B) 乘运算⊙(product
	 *如果对某个k,有 a_ik =1且b_kj =1,1≤k≤element

	 ************************************************************************/
	function muti($some_mat)
	{
		$easier = $some_mat->transpose();
		if($this->get_num_columns() == $some_mat->get_num_rows() and $this->get_num_rows() == $some_mat->get_num_columns())
		{
			foreach($this->array_number as $i => $row)
			{
				foreach($easier->array_number as $j => $column)
				{
					$total = 0;
					foreach($row as $k => $number)
					{
						if(empty($column[$k]) == false)
						{
							$total += $number * $column[$k];

						}
					}
					$the_product_data[$i][$j] = $total;
					if ($the_product_data[$i][$j]>1)
					{
						$the_product_data[$i][$j]=1;
					}
				}
			}
			$the_product = new ism_mat($the_product_data,$this->get_num_columns(),$this->element_name);
		}
		else
		{
			echo "\n\n\n 貌似出错了,请检查参数 \n\n\n";
		}
		return $the_product;
	}

	/************************************************************************
	 * 布尔矩阵交集没有运用到具体的算子 采用的是大于1就等于1的截 的方
	 * A x B is $A->meet($B)
	 *如果对某个k,有 a_ij =1且b_ij =1, c_ij =1  否则为0

	 ************************************************************************/
	function meet($some_mat)
	{
		$e=$this->element;
		if($this->get_num_columns() == $some_mat->get_num_rows() and $this->get_num_rows() == $some_mat->get_num_columns())
		{
			for($i=0; $i<$e;$i++)
			{
				for($j=0; $j<$e;$j++)
				{
					if(empty($this->array_number[$i][$j]) == false)
					{
						if(empty($some_mat->array_number[$i][$j]) == false)
						{
							if($this->array_number[$i][$j]==1 and $some_mat->array_number[$i][$j]==1)
							{
								$the_data[$i][$j]=1;
							}
						}
					}
					else
					{
						if(empty($some_mat->array_number[$i][$j]) == false)
						{
							$the_data[$i][$j]=0;
						}
					}
				}
			}
			$the_meet_mat = new ism_mat($the_data,$e,$this->element_name);
		}
		else
		{
			echo "\n\n\n 貌似出错了,请检查参数 \n\n\n";
		}
		return $the_meet_mat;
	}


	/***********************************************
	 * 矩阵大小检查,检查矩阵的行与列,是
	 ************************************************/
	function size_eq($some_mat)
	{
		$return = false;
		if ($some_mat->get_num_rows() == $this->get_num_rows() and $some_mat->get_num_columns() == $this->get_num_columns())
		{
			$return = true;
		}
		return $return;
	}

	/**************************************************
	 * 检查是否为可达矩阵 自身相乘 不变认为是可达矩阵
	 ************************************************/
	function is_r_mat($some_mat)
	{
		$return = false;
		$check =$some_mat->muti($some_mat);
		if (  $check == $some_mat)
		{
			$return = true;
		}
		return $return;
	}

	/*************************************************
	* 一个常数乘以矩阵  A * n = $A->s_times($n)
	*没有什么鸟用,一个中间
	************************************/
	function s_times($value)
	{
		$the_mat = new ism_mat($this->array_number, $this->element,$this->element_name);
		foreach($this->array_number as $i => $column)
		{
			foreach($column as $j => $number)
			{
				$the_mat->array_number[$i][$j] *= $value;
			}
		}
		return $the_mat;
	}

	/**************************************************************
	*矩阵与矩阵相减  A - B is $A->minus($B) 注意前提条
	****************************************************************/
	function minus($some_mat)
	{
		$substract = new ism_mat(array(), $this->element,$this->element_name);
		if($this->size_eq($some_mat))
		{
			for($i = 0; $i < $this->get_num_rows(); $i++)
			{
				for($j = 0; $j < $this->get_num_columns(); $j++)
				{
					if(empty($this->array_number[$i][$j]) == false)
					{
						if(empty($some_mat->array_number[$i][$j]) == false)
						{
							$substract->array_number[$i][$j] = $this->array_number[$i][$j] - $some_mat->array_number[$i][$j];
							if ($substract->array_number[$i][$j] >1)
							{
								$substract->array_number[$i][$j]=1;
							}
							if ($substract->array_number[$i][$j] <0)
							{
								$substract->array_number[$i][$j]=0;
							}
						}
						else
						{
							$substract->array_number[$i][$j] = $this->array_number[$i][$j];
							if ($substract->array_number[$i][$j] >1)
							{
								$substract->array_number[$i][$j]=1;
							}
							if ($substract->array_number[$i][$j] <0)
							{
								$substract->array_number[$i][$j]=0;
							}
						}
					}
					else
					{
						if(empty($some_mat->array_number[$i][$j]) == false)
						{
							$substract->array_number[$i][$j] = -1*$some_mat->array_number[$i][$j];
							if ($substract->array_number[$i][$j] >1)
							{
								$substract->array_number[$i][$j]=1;
							}
							if ($substract->array_number[$i][$j] <0)
							{
								$substract->array_number[$i][$j]=0;
							}
						}
					}
				}
			}
		}
		else
		{
			echo "\n\n\n 维度不同,矩阵无法相减 \n\n\n";
		}
		return $substract;
	}


	/*********************************************************************
	 * 布尔矩阵相加  A + B 对应的函数是 $A->plus($B) 注意两个的大小要相
	 **********************************************************************/
	function plus($some_mat)
	{
		$add = new ism_mat($this->array_number, $this->get_num_rows(),$this->element_name);
		if($this->size_eq($some_mat))
		{
			$some_mat = $some_mat->s_times(-1);
			$add = $this->minus($some_mat);
		}
		else
		{
			echo "\n\n\n 大小不同,或者其它错误 \n\n\n";
		}
		return $add;
	}

	/*********************************************************************
	 * 获得骨架矩阵 S
	 *  对于可达矩阵(缩减矩阵) R   I表示单位矩阵
	 *  S=R-(R-I)(R-I)
	 **********************************************************************/
	function s_mat()
	{
		$R=$this->r_mat();
		$I=$R->i();
		$tmp=$R->minus($I);
		$tmp2=$tmp->muti($tmp);
		$s_mat=$R->minus($tmp2);
		return $s_mat;
	}
	/**********************************************************
	* 获得行的
	***********************************************************/
	function get_num_rows()
	{
		return $this->numRows;
	}

	/**********************************************************
	* 获得列的
	***********************************************************/

	function get_num_columns()
	{
		return $this->numColumns;
	}

	/******************************************************************
	* 显示矩阵内容以0 1的方式显示
	*
	********************************************************************/
	function echo_mat()
	{
		$numb = $this->array_number;
		echo '<table  border="1" bgColor="#EEEE00">'."\n";
		echo '<tr><td></td>';
		for($i=0;$i<$this->element;$i++)
		{
			echo '<td>'.$this->element_name[$i].'</td>';
		}
		echo '</tr>'."\r\n";
		for($i = 0; $i < $this->get_num_rows();$i++)
		{
			//echo '<tr>';
			echo '<tr><td>'.$this->element_name[$i].'</td>';
			for($j = 0; $j < $this->get_num_columns(); $j++)
			{
				if(empty($numb[$i][$j]) == false)
				{
					echo "<td><font color=red>".$numb[$i][$j]."</font></td>";
				}
				else
				{
					echo "<td>  </td>";
				}
			}
			echo "</tr>\n";
		}
		echo "</table>\n";
	}

	/******************************************************************
	* 显示矩阵内容 以 要素的名称方式显示兼容非方阵的显示
	*
	********************************************************************/
	function echo_e()
	{
		$numb = $this->array_number;
		echo '<table  border="1" bgColor="#EEEE00">'."\n";
		for($i = 0; $i < $this->get_num_rows();$i++)
		{
			if(empty($numb[$i])==false)
			{
				echo '<tr><td>'.$this->element_name[$i].'</td><td>';
				for($j = 0; $j < $this->get_num_columns(); $j++)
				{
					if(empty($numb[$i][$j]) == false)
					{

						echo "<font color=red>".$this->element_name[$j]."、</font>";
					}
					else
					{
						echo "";
					}
				}
				echo "</td></tr>\n";
			}
		}
		echo "</table>\n";
	}

	/******************************************************************
	* 用图形方式显示
	* 返回的是  一列 ||(6:g)- (>[1,5,7,11]) () 这
	********************************************************************/
	function show_graphy()
	{
		$numb = $this->array_number;
		for($i = 0; $i <$this->element;$i++)
		{
			echo "(".$i.':'.$this->element_name[$i].")";
			if(empty($numb[$i]) == false)
			{
				$x=1;//判断一行中可达数目的标尺
				echo '- (>[';
				for($j=0;$j<$this->element;$j++)
				{
					if( empty($this->array_number[$i][$j])==false and count($numb[$i])>$x)
					{
						echo $j;
						echo',';
						$x++;
					}
					elseif( empty($this->array_number[$i][$j])==false and count($numb[$i])==$x)
					{
						echo $j;
					}
				}
				echo ']) ';
			}
			echo '()';
			echo "\r\n";
			echo "||";
		}
	}

	/******************************************************************
	* 用图形方式显示
	* 返回的是  一列 ||(6:g)- (>[1,5,7,11])  这
	********************************************************************/
	function show_rand_pos_graphy()
	{
		$numb = $this->array_number;
		for($i = 0; $i <$this->element;$i++)
		{
			$null_num=mt_rand(0,5);
			for($n=0;$n<$null_num;$n++)
			{
				echo "()";
			}
			if(empty($numb[$i]) == false)
			{
				$x=1;//判断一行中可达数目的标尺
				echo "(".$i.':'.$this->element_name[$i]."";
				echo '>[';
				for($j=0;$j<$this->element;$j++)
				{
					if( empty($this->array_number[$i][$j])==false and count($numb[$i])>$x)
					{
						echo $j;
						echo',';
						$x++;
					}
					elseif( empty($this->array_number[$i][$j])==false and count($numb[$i])==$x)
					{
						echo $j;
					}
				}
				echo ']) ';
			}
			else
			{
				echo "(".$i.':'.$this->element_name[$i].")";
			}
			echo '()';
			echo "\r\n";
			echo "||";
		}
	}
}
?>
登录后复制
08-30 07:36