MIF_E31231430/app/Services/TopsisService.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;
}
}