Bagian 3 dari seri

Perbandingan Kriteria dan Perhitungan Bobot AHP Laravel

Diterbitkan 18 September 2026

Buat Service AHP

Buat folder:

app/Services

Lalu buat file:

app/Services/AhpService.php

Isi app/Services/AhpService.php:

<?php

namespace App\Services;

class AhpService
{
    public function matrix(array $ids, $records, string $left, string $right): array
    {
        $matrix = [];

        foreach ($ids as $i) {
            foreach ($ids as $j) {
                if ($i === $j) {
                    $matrix[$i][$j] = 1.0;
                    continue;
                }

                $direct = $records->first(
                    fn ($row) => $row->{$left} == $i && $row->{$right} == $j
                );

                if ($direct) {
                    $matrix[$i][$j] = (float) $direct->nilai;
                    continue;
                }

                $reverse = $records->first(
                    fn ($row) => $row->{$left} == $j && $row->{$right} == $i
                );

                $matrix[$i][$j] = $reverse
                    ? 1 / (float) $reverse->nilai
                    : 1.0;
            }
        }

        return $matrix;
    }

    public function priority(array $matrix, array $ids): array
    {
        $columnTotals = [];

        foreach ($ids as $j) {
            $columnTotals[$j] = array_sum(
                array_map(fn ($i) => $matrix[$i][$j], $ids)
            );
        }

        $normalized = [];
        $weights = [];

        foreach ($ids as $i) {
            foreach ($ids as $j) {
                $normalized[$i][$j] =
                    $matrix[$i][$j] / $columnTotals[$j];
            }

            $weights[$i] =
                array_sum($normalized[$i]) / count($ids);
        }

        return compact('columnTotals', 'normalized', 'weights');
    }

    public function consistency(array $matrix, array $weights, array $ids): array
    {
        $n = count($ids);

        if ($n < 3) {
            return [
                'lambdaMax' => $n,
                'ci' => 0,
                'ri' => 0,
                'cr' => 0,
            ];
        }

        $weightedSum = [];

        foreach ($ids as $i) {
            $weightedSum[$i] = 0;

            foreach ($ids as $j) {
                $weightedSum[$i] += $matrix[$i][$j] * $weights[$j];
            }
        }

        $lambda = [];

        foreach ($ids as $i) {
            $lambda[$i] = $weightedSum[$i] / $weights[$i];
        }

        $lambdaMax = array_sum($lambda) / $n;
        $ci = ($lambdaMax - $n) / ($n - 1);

        $riTable = [
            1 => 0.00,
            2 => 0.00,
            3 => 0.58,
            4 => 0.90,
            5 => 1.12,
            6 => 1.24,
            7 => 1.32,
            8 => 1.41,
            9 => 1.45,
            10 => 1.49,
        ];

        $ri = $riTable[$n] ?? 1.49;
        $cr = $ri > 0 ? $ci / $ri : 0;

        return compact('lambdaMax', 'ci', 'ri', 'cr');
    }
}

Buat Controller

php artisan make:controller PerbandinganKriteriaController

app/Http/Controllers/PerbandinganKriteriaController.php:

<?php

namespace App\Http\Controllers;

use App\Models\Kriteria;
use App\Models\PerbandinganKriteria;
use App\Services\AhpService;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Validation\Rule;

class PerbandinganKriteriaController extends Controller
{
    private array $skalaAhp = [
        0.111111,
        0.125,
        0.142857,
        0.166667,
        0.2,
        0.25,
        0.333333,
        0.5,
        1,
        2,
        3,
        4,
        5,
        6,
        7,
        8,
        9,
    ];

    public function index(AhpService $ahp)
    {
        $kriteria = Kriteria::orderBy('kode')->get();
        $records = PerbandinganKriteria::all();
        $ids = $kriteria->pluck('id')->all();

        $matrix = $ids
            ? $ahp->matrix($ids, $records, 'kriteria_1_id', 'kriteria_2_id')
            : [];

        $hasil = count($ids) >= 2
            ? $ahp->priority($matrix, $ids)
            : null;

        $konsistensi = $hasil
            ? $ahp->consistency($matrix, $hasil['weights'], $ids)
            : null;

        return view('perbandingan-kriteria.index', compact(
            'kriteria',
            'matrix',
            'hasil',
            'konsistensi'
        ));
    }

    public function store(Request $request)
    {
        $kriteria = Kriteria::orderBy('kode')->get();
        $ids = $kriteria->pluck('id')->all();

        $request->validate([
            'nilai' => ['required', 'array'],
            'nilai.*.*' => [
                'required',
                'numeric',
                Rule::in($this->skalaAhp),
            ],
        ]);

        DB::transaction(function () use ($request, $ids) {
            PerbandinganKriteria::query()->delete();

            for ($i = 0; $i < count($ids); $i++) {
                for ($j = $i + 1; $j < count($ids); $j++) {
                    $a = $ids[$i];
                    $b = $ids[$j];

                    PerbandinganKriteria::create([
                        'kriteria_1_id' => $a,
                        'kriteria_2_id' => $b,
                        'nilai' => (float) $request->input("nilai.$a.$b"),
                    ]);
                }
            }
        });

        return redirect()
            ->route('perbandingan-kriteria.index')
            ->with('success', 'Perbandingan kriteria berhasil disimpan.');
    }
}

Route

Tambahkan pada grup auth:

use App\Http\Controllers\PerbandinganKriteriaController;

Route::get(
    '/perbandingan-kriteria',
    [PerbandinganKriteriaController::class, 'index']
)->name('perbandingan-kriteria.index');

Route::post(
    '/perbandingan-kriteria',
    [PerbandinganKriteriaController::class, 'store']
)->name('perbandingan-kriteria.store');

Tambahkan Menu Perbandingan Kriteria

Buka resources/views/layouts/app.blade.php, lalu tambahkan menu berikut pada navbar:

<a class="nav-link text-white" href="{{ route('kriteria.index') }}">
    Kriteria
</a>

<a class="nav-link text-white" href="{{ route('alternatif.index') }}">
    Alternatif
</a>

<a class="nav-link text-white" href="{{ route('perbandingan-kriteria.index') }}">
    Perbandingan Kriteria
</a>

View Matriks Kriteria

Buat resources/views/perbandingan-kriteria/index.blade.php:

@extends('layouts.app')

@section('title', 'Perbandingan Kriteria')

@section('content')
<h1 class="h4 mb-3">Perbandingan Kriteria</h1>

<div class="alert alert-info">
    Pilih nilai berdasarkan skala perbandingan AHP.
</div>

@php
    $skalaAhp = [
        '0.111111' => '1/9',
        '0.125' => '1/8',
        '0.142857' => '1/7',
        '0.166667' => '1/6',
        '0.2' => '1/5',
        '0.25' => '1/4',
        '0.333333' => '1/3',
        '0.5' => '1/2',
        '1' => '1',
        '2' => '2',
        '3' => '3',
        '4' => '4',
        '5' => '5',
        '6' => '6',
        '7' => '7',
        '8' => '8',
        '9' => '9',
    ];
@endphp

<form method="POST" action="{{ route('perbandingan-kriteria.store') }}">
    @csrf

    <div class="card border-0 shadow-sm mb-4">
        <div class="card-body table-responsive">
            <table class="table table-bordered text-center align-middle">
                <thead>
                    <tr>
                        <th>Kriteria</th>
                        @foreach($kriteria as $kolom)
                            <th>{{ $kolom->kode }}</th>
                        @endforeach
                    </tr>
                </thead>
                <tbody>
                    @foreach($kriteria as $i => $baris)
                        <tr>
                            <th>{{ $baris->kode }}</th>

                            @foreach($kriteria as $j => $kolom)
                                <td>
                                    @if($i === $j)
                                        1
                                    @elseif($i < $j)
                                        @php
                                            $nilaiAktif = old(
                                                "nilai.{$baris->id}.{$kolom->id}",
                                                $matrix[$baris->id][$kolom->id] ?? 1
                                            );
                                        @endphp

                                        <select
                                            name="nilai[{{ $baris->id }}][{{ $kolom->id }}]"
                                            class="form-select"
                                            required>
                                            @foreach($skalaAhp as $value => $label)
                                                <option
                                                    value="{{ $value }}"
                                                    @selected(abs((float) $nilaiAktif - (float) $value) < 0.000001)>
                                                    {{ $label }}
                                                </option>
                                            @endforeach
                                        </select>
                                    @else
                                        {{ number_format(
                                            $matrix[$baris->id][$kolom->id] ?? 1,
                                            4
                                        ) }}
                                    @endif
                                </td>
                            @endforeach
                        </tr>
                    @endforeach
                </tbody>
            </table>

            <button class="btn btn-primary">Simpan dan Hitung</button>
        </div>
    </div>
</form>

@if($hasil)
<div class="card border-0 shadow-sm mb-4">
    <div class="card-body">
        <h2 class="h5">Bobot Prioritas</h2>

        <table class="table table-bordered">
            <thead>
                <tr>
                    <th>Kriteria</th>
                    <th>Bobot</th>
                </tr>
            </thead>
            <tbody>
                @foreach($kriteria as $item)
                    <tr>
                        <td>{{ $item->kode }} - {{ $item->nama }}</td>
                        <td>{{ number_format($hasil['weights'][$item->id], 6) }}</td>
                    </tr>
                @endforeach
            </tbody>
        </table>

        <p>Lambda Maksimum:
            <strong>{{ number_format($konsistensi['lambdaMax'], 6) }}</strong>
        </p>

        <p>CI:
            <strong>{{ number_format($konsistensi['ci'], 6) }}</strong>
        </p>

        <p>CR:
            <strong>{{ number_format($konsistensi['cr'], 6) }}</strong>
        </p>

        @if($konsistensi['cr'] <= 0.1)
            <div class="alert alert-success mb-0">
                Matriks konsisten (CR ≤ 0,1).
            </div>
        @else
            <div class="alert alert-danger mb-0">
                Matriks belum konsisten. Perbaiki nilai perbandingan.
            </div>
        @endif
    </div>
</div>
@endif
@endsection
Tutorial AHP Laravel Perbandingan Kriteria

Checkpoint

Pastikan:

  • Nilai diagonal selalu 1.
  • Input menggunakan dropdown skala AHP.
  • Nilai seperti 1/3 dapat dipilih langsung.
  • Nilai di bawah diagonal otomatis merupakan kebalikan.
  • Bobot kriteria berjumlah mendekati 1.
  • CR ditampilkan.
  • Matriks diterima jika CR ≤ 0,1.

Lanjut: Perbandingan Alternatif pada Setiap Kriteria