Bagian 5 dari seri
Perhitungan Nilai Akhir dan Ranking AHP Laravel
Diterbitkan 18 September 2026
Rumus Nilai Akhir
Nilai akhir setiap alternatif dihitung dari:
Nilai Akhir =
Σ (Bobot Kriteria × Bobot Alternatif pada Kriteria)
Halaman hasil menggunakan GET untuk menampilkan data. Proses perhitungan menggunakan POST karena mengubah nilai_akhir dan ranking di database.
Buat Controller
php artisan make:controller HasilController
app/Http/Controllers/HasilController.php:
<?php
namespace App\Http\Controllers;
use App\Models\Alternatif;
use App\Models\Kriteria;
use App\Models\PerbandinganAlternatif;
use App\Models\PerbandinganKriteria;
use App\Services\AhpService;
use Illuminate\Support\Facades\DB;
class HasilController extends Controller
{
public function index()
{
$ranking = Alternatif::orderByRaw(
'ranking IS NULL, ranking ASC'
)
->orderBy('kode')
->get();
return view('hasil.index', compact('ranking'));
}
public function calculate(AhpService $ahp)
{
$kriteria = Kriteria::orderBy('kode')->get();
$alternatif = Alternatif::orderBy('kode')->get();
if ($kriteria->count() < 2 || $alternatif->count() < 2) {
return redirect()
->route('hasil.index')
->withErrors(
'Minimal diperlukan dua kriteria dan dua alternatif.'
);
}
$kriteriaIds = $kriteria->pluck('id')->all();
$alternatifIds = $alternatif->pluck('id')->all();
$expectedKriteria =
$kriteria->count() * ($kriteria->count() - 1) / 2;
if (PerbandinganKriteria::count() !== $expectedKriteria) {
return redirect()
->route('hasil.index')
->withErrors(
'Perbandingan kriteria belum lengkap.'
);
}
$recordsKriteria = PerbandinganKriteria::all();
$matrixKriteria = $ahp->matrix(
$kriteriaIds,
$recordsKriteria,
'kriteria_1_id',
'kriteria_2_id'
);
$hasilKriteria = $ahp->priority(
$matrixKriteria,
$kriteriaIds
);
$konsistensiKriteria = $ahp->consistency(
$matrixKriteria,
$hasilKriteria['weights'],
$kriteriaIds
);
if ($konsistensiKriteria['cr'] > 0.1) {
return redirect()
->route('hasil.index')
->withErrors(
'Perbandingan kriteria belum konsisten.'
);
}
$expectedAlternatif =
$alternatif->count() * ($alternatif->count() - 1) / 2;
$bobotAlternatif = [];
foreach ($kriteria as $itemKriteria) {
$records = PerbandinganAlternatif::where(
'kriteria_id',
$itemKriteria->id
)->get();
if ($records->count() !== $expectedAlternatif) {
return redirect()
->route('hasil.index')
->withErrors(
"Perbandingan alternatif pada {$itemKriteria->kode} belum lengkap."
);
}
$matrix = $ahp->matrix(
$alternatifIds,
$records,
'alternatif_1_id',
'alternatif_2_id'
);
$hasil = $ahp->priority(
$matrix,
$alternatifIds
);
$konsistensi = $ahp->consistency(
$matrix,
$hasil['weights'],
$alternatifIds
);
if ($konsistensi['cr'] > 0.1) {
return redirect()
->route('hasil.index')
->withErrors(
"Perbandingan alternatif pada {$itemKriteria->kode} belum konsisten."
);
}
$bobotAlternatif[$itemKriteria->id] =
$hasil['weights'];
}
$nilaiAkhir = [];
foreach ($alternatifIds as $alternatifId) {
$nilaiAkhir[$alternatifId] = 0;
foreach ($kriteriaIds as $kriteriaId) {
$nilaiAkhir[$alternatifId] +=
$hasilKriteria['weights'][$kriteriaId]
* $bobotAlternatif[$kriteriaId][$alternatifId];
}
}
arsort($nilaiAkhir);
DB::transaction(function () use ($nilaiAkhir) {
$posisi = 0;
$ranking = 0;
$nilaiSebelumnya = null;
$epsilon = 0.00000001;
foreach ($nilaiAkhir as $alternatifId => $nilai) {
$posisi++;
if (
$nilaiSebelumnya === null
|| abs($nilai - $nilaiSebelumnya) > $epsilon
) {
$ranking = $posisi;
}
Alternatif::whereKey($alternatifId)->update([
'nilai_akhir' => $nilai,
'ranking' => $ranking,
]);
$nilaiSebelumnya = $nilai;
}
});
return redirect()
->route('hasil.index')
->with(
'success',
'Perhitungan AHP dan ranking berhasil dilakukan.'
);
}
}
Jika dua alternatif memiliki nilai akhir yang sama, keduanya memperoleh ranking yang sama.
Contoh:
A1 = 0.40000000 → Ranking 1
A2 = 0.40000000 → Ranking 1
A3 = 0.20000000 → Ranking 3
Route
Tambahkan pada grup auth:
use App\Http\Controllers\HasilController;
Route::get(
'/hasil',
[HasilController::class, 'index']
)->name('hasil.index');
Route::post(
'/hasil/hitung',
[HasilController::class, 'calculate']
)->name('hasil.calculate');
View Ranking
Buat resources/views/hasil/index.blade.php:
@extends('layouts.app')
@section('title', 'Hasil AHP')
@section('content')
<div class="d-flex justify-content-between align-items-center mb-3">
<h1 class="h4 mb-0">
Hasil Ranking AHP
</h1>
<form
method="POST"
action="{{ route('hasil.calculate') }}">
@csrf
<button class="btn btn-primary">
Hitung Ranking
</button>
</form>
</div>
<div class="card border-0 shadow-sm">
<div class="card-body">
<div class="table-responsive">
<table class="table table-bordered table-striped align-middle">
<thead>
<tr>
<th width="100">Ranking</th>
<th>Kode</th>
<th>Alternatif</th>
<th>Nilai Akhir</th>
</tr>
</thead>
<tbody>
@forelse($ranking as $item)
<tr>
<td>
@if($item->ranking)
<span class="badge text-bg-primary">
{{ $item->ranking }}
</span>
@else
-
@endif
</td>
<td>{{ $item->kode }}</td>
<td>{{ $item->nama }}</td>
<td>
@if($item->nilai_akhir !== null)
{{ number_format(
$item->nilai_akhir,
8
) }}
@else
Belum dihitung
@endif
</td>
</tr>
@empty
<tr>
<td colspan="4" class="text-center">
Belum ada alternatif.
</td>
</tr>
@endforelse
</tbody>
</table>
</div>
</div>
</div>
@endsection
Tambahkan Menu Hasil
Pada navbar:
<a class="nav-link text-white" href="{{ route('hasil.index') }}">
Hasil Ranking
</a>
Cara Kerja
Saat halaman hasil dibuka:
GET /hasil
aplikasi hanya menampilkan data.
Saat tombol Hitung Ranking ditekan:
POST /hasil/hitung
aplikasi akan:
- memastikan jumlah kriteria dan alternatif cukup;
- memastikan seluruh pasangan perbandingan lengkap;
- menghitung bobot kriteria;
- memeriksa CR kriteria;
- menghitung bobot alternatif pada setiap kriteria;
- memeriksa CR setiap matriks alternatif;
- menghitung nilai akhir;
- menentukan ranking;
- menyimpan
nilai_akhirdanranking.

Pengujian Akhir
Pastikan:
- Login dan logout berjalan.
- CRUD kriteria berjalan.
- CRUD alternatif berjalan.
- Pasangan baru otomatis dibuat dengan nilai
1. - CR kriteria ≤ 0,1.
- CR alternatif pada setiap kriteria ≤ 0,1.
- Membuka halaman hasil tidak langsung mengubah database.
- Perhitungan dilakukan setelah tombol Hitung Ranking ditekan.
- Nilai akhir tersimpan.
- Ranking diurutkan dari nilai terbesar.
- Nilai akhir yang sama menghasilkan ranking yang sama.
Selesai
Aplikasi AHP Laravel sudah memiliki alur lengkap mulai dari data master, matriks perbandingan, pengujian konsistensi, sampai ranking akhir.
Kembali ke Tutorial AHP Laravel





Komentar
Tulis Komentar