主要思路 利用行列式性质(某一行倍数+到另一行的值 不变)
1.寻找第i列主元,并将其所在的行交换到当前处理行位置上
疑问: 为啥获取最大列的主元 百度百科说 为了算法稳定性
function FindMain(&$arr,$line)
{
$t = $line;
for ($i = $line;$i<count($arr);$i++) {
if (abs($arr[$i][$line]) > abs($arr[$t][$line])) {
$t = $i;
}
}
if ($t != $line) {
$arrTmp = $arr[$line];
$arr[$line] = $arr[$t];
$arr[$t] = $arrTmp;
}
}
2.将主元所在的行的各个系数除以主元,当前主元为1
疑问 :为啥将主元化为1 为了方便计算 系数为1 不需要在做除法运算
function DivMain(&$arr,$line) {
for ($i = count($arr);$i>=$line;$i--) {
$arr[$line][$i] /= $arr[$line][$line];
}
}
3.进行第i列消元
function Del(&$arr,$line) {
$k = 0;
for ($i = $line+1; $i < count($arr); $i++,$k++) {
$firstV = 0;
for ($l = $line;$l<count($arr[$i]);$l++) {
if ($firstV == 0) {
$firstV = 0-($arr[$i][$l]);
}
$arr[$i][$l] = $arr[$i][$l]+ $arr[$line][$l]*$firstV;
}
}
}
4.调用测试
$arr = [
[2,1,1,7],
[4,5,-1,11],
[1,-2,1,0],
];
$N = count($arr);
for ($i = 0; $i < $N; $i++) {
if ($i<$N-1) {
$mainElement = FindMain($arr,0);
}
DivMain($arr,$i);
if ($i<$N-1) {
Del($arr,$i);
}
}
5回代计算
for ($i = $N-2; $i >= 0; $i--) {
for ($j = $N - 1; $j > $i; $j--) {
$arr[$i][$N] -= $arr[$i][$j] * $arr[$j][$N];
}
}
6.输出结果
for ($i = 0; $i < $N; $i++) {
echo $arr[$i][$N].PHP_EOL;
}
over