PHP Classes

File: ism_matrix.php

Recommend this page to a friend!
  Classes of sgcha   ISM Matrix   ism_matrix.php   Download  
File: ism_matrix.php
Role: Class source
Content type: text/plain
Description: Class
Class: ISM Matrix
Handle Interpretive Structure Modeling matrices
Author: By
Last change: ism
Date: 11 years ago
Size: 42,965 bytes
 

Contents

Class file image Download
<?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 "||"; } } } ?>