MIF_E31220044/app/Http/Controllers/PenilaianController.php

182 lines
6.4 KiB
PHP

<?php
namespace App\Http\Controllers;
use App\Models\Alternative;
use App\Models\Kriteria;
use App\Models\Penilaian;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
class PenilaianController extends Controller
{
public function index()
{
$alternatifs = Alternative::all();
$kriterias = Kriteria::all();
$penilaians = Penilaian::all();
$matriksKeputusan = [];
$normalisasi = [];
$ranking = [];
if ($penilaians->isNotEmpty()) {
// Membuat matriks keputusan
foreach ($alternatifs as $alternatif) {
foreach ($kriterias as $kriteria) {
$penilaian = $penilaians->where('alternatif_id', $alternatif->id)
->where('kriteria_id', $kriteria->id)
->first();
$nilai = $penilaian ? $penilaian->nilai : 0;
$matriksKeputusan[$alternatif->id][$kriteria->id] = $nilai;
}
}
// Cari nilai max dan min untuk setiap kriteria
$maxMin = [];
foreach ($kriterias as $kriteria) {
$nilai_kriteria = collect($matriksKeputusan)->map(function ($row) use ($kriteria) {
return $row[$kriteria->id];
})->filter(function ($nilai) {
return $nilai > 0; // Hanya ambil nilai yang lebih dari 0
});
$maxMin[$kriteria->id] = [
'max' => $nilai_kriteria->max() ?: 1,
'min' => $nilai_kriteria->min() ?: 1
];
}
// Normalisasi
foreach ($alternatifs as $alternatif) {
foreach ($kriterias as $kriteria) {
$nilai = $matriksKeputusan[$alternatif->id][$kriteria->id];
if ($nilai > 0) {
if ($kriteria->tipe === 'benefit') {
// Untuk kriteria benefit: nilai/nilai_max
$normalisasi[$alternatif->id][$kriteria->id] =
$nilai / $maxMin[$kriteria->id]['max'];
} else {
// Untuk kriteria cost: nilai_min/nilai
$normalisasi[$alternatif->id][$kriteria->id] =
$maxMin[$kriteria->id]['min'] / $nilai;
}
} else {
$normalisasi[$alternatif->id][$kriteria->id] = 0;
}
}
}
// Hitung ranking
foreach ($alternatifs as $alternatif) {
$total = 0;
foreach ($kriterias as $kriteria) {
$normal = $normalisasi[$alternatif->id][$kriteria->id];
$bobot = $kriteria->bobot;
$total += ($normal * $bobot);
}
$ranking[$alternatif->id] = round($total, 4);
}
arsort($ranking);
// Simpan hasil
DB::statement('ALTER TABLE hasil_penilaian MODIFY COLUMN nilai_akhir DECIMAL(10,4)');
DB::table('hasil_penilaian')->truncate();
foreach ($ranking as $alternatif_id => $nilai_akhir) {
DB::table('hasil_penilaian')->insert([
'alternatif_id' => $alternatif_id,
'nilai_akhir' => $nilai_akhir,
'created_at' => now(),
'updated_at' => now(),
]);
}
}
return view('admin.penilaian.index', compact(
'alternatifs', 'kriterias', 'penilaians',
'matriksKeputusan', 'normalisasi', 'ranking'
));
}
public function store(Request $request)
{
$request->validate([
'alternatif_id' => 'required|exists:alternatives,id',
'n' => 'required|numeric',
'p' => 'required|numeric',
'k' => 'required|numeric',
'harga' => 'required|numeric',
]);
$kriteriasByName = Kriteria::all()->keyBy('nama');
// Sesuaikan dengan nama di database
$nilaiInput = [
$kriteriasByName->get('Kandungan Nitrogen (N)')->id ?? null => $request->n,
$kriteriasByName->get('Kandungan Fosfor (F)')->id ?? null => $request->p,
$kriteriasByName->get('Kandungan Kalium (k)')->id ?? null => $request->k,
$kriteriasByName->get('Harga')->id ?? null => $request->harga,
];
foreach ($nilaiInput as $kriteria_id => $nilai_val) {
if (!empty($kriteria_id) && is_numeric($kriteria_id)) {
Penilaian::updateOrCreate(
[
'alternatif_id' => $request->alternatif_id,
'kriteria_id' => (int)$kriteria_id
],
['nilai' => $nilai_val]
);
}
}
return redirect()->route('penilaian.index')->with('success', 'Penilaian berhasil disimpan');
}
public function destroy()
{
Penilaian::truncate();
return redirect()->route('penilaian.hasil')->with('success', 'Semua hasil penilaian berhasil dihapus');
}
public function deleteAll()
{
Penilaian::truncate();
return redirect()->route('admin.penilaian.index')->with('success', 'Semua penilaian berhasil dihapus.');
}
public function calculateSAW($alternatifs, $kriterias)
{
$normalized = [];
$scores = [];
foreach ($kriterias as $kriteria) {
$key = $kriteria->nama;
$max = $alternatifs->max($key) ?: 1;
$min = $alternatifs->min($key) ?: 1;
foreach ($alternatifs as $alternatif) {
$value = $alternatif->{$key} ?? 0;
$normalized[$alternatif->id][$kriteria->id] =
$kriteria->tipe === 'benefit'
? ($max > 0 ? $value / $max : 0)
: ($value > 0 ? $min / $value : 0);
}
}
foreach ($normalized as $alternatif_id => $values) {
$score = 0;
foreach ($kriterias as $kriteria) {
$bobot = $kriteria->bobot ?? 0.25;
$score += $values[$kriteria->id] * $bobot;
}
$scores[$alternatif_id] = round($score, 4);
}
return $scores;
}
}