<?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 "||";
}
}
}
?>
|