РНР

2016-03-15 1 views
0

Я хотел бы написать код, чтобы сделать гауссово исключение, я получил это:РНР

function gauss($A, $x) { 

    for ($i=0; $i < count($A); $i++) { 
     $A[$i][] = $x[$i]; 
    } 
    $n = count($A); 

    for ($i=0; $i < $n; $i++) { 
     $maxEl = abs($A[$i][$i]); 
     $maxRow = $i; 
     for ($k=$i+1; $k < $n; $k++) { 
      if (abs($A[$k][$i]) > $maxEl) { 
       $maxEl = abs($A[$k][$i]); 
       $maxRow = $k; 
      } 
     } 


     for ($k=$i; $k < $n+1; $k++) { 
      $tmp = $A[$maxRow][$k]; 
      $A[$maxRow][$k] = $A[$i][$k]; 
      $A[$i][$k] = $tmp; 
     } 

     for ($k=$i+1; $k < $n; $k++) { 
      $c = -$A[$k][$i]/$A[$i][$i]; 
      for ($j=$i; $j < $n+1; $j++) { 
       if ($i==$j) { 
        $A[$k][$j] = 0; 
       } else { 
        $A[$k][$j] += $c * $A[$i][$j]; 
       } 
      } 
     } 
    } 

    $x = array_fill(0, $n, 0); 
    for ($i=$n-1; $i > -1; $i--) { 
     $x[$i] = $A[$i][$n]/$A[$i][$i]; 
     for ($k=$i-1; $k > -1; $k--) { 
      $A[$k][$n] -= $A[$k][$i] * $x[$i]; 
     } 
    } 
if (!in_array(false, $x, true)){ 
if($x[0] >= 0 && $x[1] >= 0 && $x[2] >= 0){ 
return $x; 
} 
} 

} 

Все в порядке, но когда я кладу значение, как это:

$A = array(array(1,1,0),array(3,5,4),array(1,0,0)); 
$x = array(2,30,0); 



| 1 1 0 | 2 | 
| 1 0 0 | 0 | 
| 3 5 4 | 30 | 

Результат должен быть: (0,2,5), но моя функция возвращает null.

Я не знаю, что с ним не так.

+0

Я не проверил вашу Gaussian процедуры ликвидации в деталях, но я уже заметил, что вы позволяете только функцию верните вектор '$ x', если все значения' '= 0'. Разве это не условие, которое далеко? Как насчет законных решений с отрицательными значениями '$ x'? – cars10m

ответ

1

Просто попробовал мое предположение, упомянутое в моем предыдущем комментарии, и это оказалось правдой: удаление условий перед возвратом приведет к тому, что результат будет решен вашей проблемой. Попробуйте в этом little phpfiddle.

Вот исправленный код еще раз:

function gauss($A, $x) { 

    for ($i=0; $i < count($A); $i++) { 
     $A[$i][] = $x[$i]; 
    } 
    $n = count($A); 

    for ($i=0; $i < $n; $i++) { 
     $maxEl = abs($A[$i][$i]); 
     $maxRow = $i; 
     for ($k=$i+1; $k < $n; $k++) { 
      if (abs($A[$k][$i]) > $maxEl) { 
       $maxEl = abs($A[$k][$i]); 
       $maxRow = $k; 
      } 
     } 


     for ($k=$i; $k < $n+1; $k++) { 
      $tmp = $A[$maxRow][$k]; 
      $A[$maxRow][$k] = $A[$i][$k]; 
      $A[$i][$k] = $tmp; 
     } 

     for ($k=$i+1; $k < $n; $k++) { 
      $c = -$A[$k][$i]/$A[$i][$i]; 
      for ($j=$i; $j < $n+1; $j++) { 
       if ($i==$j) { 
        $A[$k][$j] = 0; 
       } else { 
        $A[$k][$j] += $c * $A[$i][$j]; 
       } 
      } 
     } 
    } 

    $x = array_fill(0, $n, 0); 
    for ($i=$n-1; $i > -1; $i--) { 
     $x[$i] = $A[$i][$n]/$A[$i][$i]; 
     for ($k=$i-1; $k > -1; $k--) { 
      $A[$k][$n] -= $A[$k][$i] * $x[$i]; 
     } 
    } 
    // be bold and return the $x vector in any case: 
    return $x; 
} 
$A = array(array(1,1,0),array(3,5,4),array(1,0,0)); 
$rhs = array(2,30,0); 
print_r($A); 
print_r($rhs); 
$x=gauss($A,$rhs); 
echo "solution vector:\n"; 
print_r($x); 

Это дает следующий результат:

Array 
(
    [0] => Array 
     (
      [0] => 1 
      [1] => 1 
      [2] => 0 
     ) 

    [1] => Array 
     (
      [0] => 3 
      [1] => 5 
      [2] => 4 
     ) 

    [2] => Array 
     (
      [0] => 1 
      [1] => 0 
      [2] => 0 
     ) 

) 
Array 
(
    [0] => 2 
    [1] => 30 
    [2] => 0 
) 
solution vector: 
Array 
(
    [0] => -5.92118946467E-16 
    [1] => 2 
    [2] => 5 
) 
+0

Я знаю это, но с этим алгоритмом что-то не так. Потому что правильный выходной массив должен быть: (0,2,5). – Pavvi

+2

Ну, это как близко к '0', как вы когда-либо получите! В числовом смысле '-5.92118946467E-16' ** **. Он «очень мал» по сравнению с «2» и «5». Если вы хотите, чтобы он выглядел лучше, вы можете попробовать «round()» результаты. – cars10m