182 lines
6.4 KiB
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;
|
|
}
|
|
} |