94 lines
3.2 KiB
PHP
94 lines
3.2 KiB
PHP
<?php
|
|
|
|
namespace App\Services;
|
|
|
|
class TopsisService
|
|
{
|
|
/**
|
|
* Menghitung nilai TOPSIS
|
|
*
|
|
* @param array $data Matriks data [alternatif][kriteria]
|
|
* @param array $bobot Bobot setiap kriteria (total harus 1)
|
|
* @param array $jenis Jenis kriteria ['cost', 'benefit']
|
|
* @return array Nilai preferensi setiap alternatif
|
|
*/
|
|
public static function hitung($data, $bobot, $jenis)
|
|
{
|
|
$m = count($data); // jumlah alternatif
|
|
$n = count($data[0]); // jumlah kriteria
|
|
|
|
// ==========================================
|
|
// LANGKAH 1: Normalisasi Euclidean
|
|
// ==========================================
|
|
$norm = [];
|
|
for ($j = 0; $j < $n; $j++) {
|
|
$sumSquares = 0;
|
|
for ($i = 0; $i < $m; $i++) {
|
|
$value = is_numeric($data[$i][$j]) ? (float) $data[$i][$j] : 0.0;
|
|
$sumSquares += pow($value, 2);
|
|
}
|
|
$sqrt = sqrt($sumSquares);
|
|
|
|
for ($i = 0; $i < $m; $i++) {
|
|
$value = is_numeric($data[$i][$j]) ? (float) $data[$i][$j] : 0.0;
|
|
$norm[$i][$j] = ($sqrt > 0) ? ($value / $sqrt) : 0.0;
|
|
}
|
|
}
|
|
|
|
// ==========================================
|
|
// LANGKAH 2: Normalisasi Terbobot (Weighted Normalized)
|
|
// ==========================================
|
|
$weighted = [];
|
|
for ($i = 0; $i < $m; $i++) {
|
|
for ($j = 0; $j < $n; $j++) {
|
|
$weighted[$i][$j] = $norm[$i][$j] * $bobot[$j];
|
|
}
|
|
}
|
|
|
|
// ==========================================
|
|
// LANGKAH 3: Solusi Ideal Positif (A+) dan Negatif (A-)
|
|
// ==========================================
|
|
$idealPos = [];
|
|
$idealNeg = [];
|
|
|
|
for ($j = 0; $j < $n; $j++) {
|
|
$col = array_column($weighted, $j);
|
|
if ($jenis[$j] == 'benefit') {
|
|
$idealPos[$j] = max($col); // benefit: cari nilai maksimum
|
|
$idealNeg[$j] = min($col); // benefit: cari nilai minimum
|
|
} else { // cost
|
|
$idealPos[$j] = min($col); // cost: cari nilai minimum
|
|
$idealNeg[$j] = max($col); // cost: cari nilai maksimum
|
|
}
|
|
}
|
|
|
|
// ==========================================
|
|
// LANGKAH 4: Jarak ke Solusi Ideal
|
|
// ==========================================
|
|
$dPlus = [];
|
|
$dMinus = [];
|
|
|
|
for ($i = 0; $i < $m; $i++) {
|
|
$dp = 0;
|
|
$dm = 0;
|
|
for ($j = 0; $j < $n; $j++) {
|
|
$dp += pow($weighted[$i][$j] - $idealPos[$j], 2);
|
|
$dm += pow($weighted[$i][$j] - $idealNeg[$j], 2);
|
|
}
|
|
$dPlus[$i] = sqrt($dp);
|
|
$dMinus[$i] = sqrt($dm);
|
|
}
|
|
|
|
// ==========================================
|
|
// LANGKAH 5: Nilai Preferensi (Kedekatan Relatif)
|
|
// ==========================================
|
|
$preferences = [];
|
|
for ($i = 0; $i < $m; $i++) {
|
|
$denominator = $dPlus[$i] + $dMinus[$i];
|
|
$preferences[$i] = ($denominator > 0) ? ($dMinus[$i] / $denominator) : 0.0;
|
|
}
|
|
|
|
return $preferences;
|
|
}
|
|
}
|