From d9daf8f05421f7938ed80c5a6414b16e878644c5 Mon Sep 17 00:00:00 2001 From: daffarahman11 Date: Mon, 7 Apr 2025 18:04:29 +0700 Subject: [PATCH] Tampilan Halaman Hasil Perhitungan Iterasi Curas --- .../Controllers/curasKmeansController.php | 130 +++++++++--------- .../Controllers/hasilIterasiController.php | 17 +++ database/seeders/KecamatanSeeder.php | 2 +- .../Admin/dashboardIterasiCuras.blade.php | 70 ++++++++++ routes/web.php | 2 + 5 files changed, 158 insertions(+), 63 deletions(-) create mode 100644 app/Http/Controllers/hasilIterasiController.php create mode 100644 resources/views/Admin/dashboardIterasiCuras.blade.php diff --git a/app/Http/Controllers/curasKmeansController.php b/app/Http/Controllers/curasKmeansController.php index 5192ee2..67ce47d 100644 --- a/app/Http/Controllers/curasKmeansController.php +++ b/app/Http/Controllers/curasKmeansController.php @@ -9,74 +9,80 @@ class curasKmeansController extends Controller { public function hitungKMeans() { - $data = Curas::select('id', 'kecamatan_id', 'klaster_id', 'jumlah_curas')->orderBy('jumlah_curas', 'asc')->get(); + $data = Curas::select('id', 'kecamatan_id', 'klaster_id', 'jumlah_curas')->orderBy('jumlah_curas', 'asc')->get(); - $k = 3; - $maxIterasi = 100; - $centroids = $data->random($k)->values()->map(function ($item) { - return [ - 'jumlah_curas' => $item->jumlah_curas, - ]; - }); - - $iterasi = []; - - for ($i = 0; $i < $maxIterasi; $i++) { - $clustered = []; - - foreach ($data as $item) { - $jarak = []; - - foreach ($centroids as $idx => $centroid) { - $dist = abs($item->jumlah_curas - $centroid['jumlah_curas']); - $jarak["jarakC" . ($idx + 1)] = $dist; - } - - // Simpan jarak ke array iterasi - $iterasi[$i][] = array_merge(['kecamatan_id' => $item->kecamatan_id], $jarak); - - // Tentukan klaster berdasarkan jarak terpendek - $minIndex = array_keys($jarak, min($jarak))[0]; // e.g. "jarakC2" - $clusterNumber = (int) str_replace("jarakC", "", $minIndex); - - $clustered[$clusterNumber][] = $item; - $item->temp_klaster = $clusterNumber; // Simpan klaster sementara - } - - // Update centroid berdasarkan rata-rata - foreach ($clustered as $key => $group) { - $avg = collect($group)->avg('jumlah_curas'); - $centroids = $centroids->map(function ($item, $index) use ($key, $avg) { - if ($index === ($key - 1)) { - return ['jumlah_curas' => $avg]; - } - return $item; - }); - } - - } - - // 1. Ambil centroid terakhir dan urutkan dari kecil ke besar - $finalCentroids = $centroids->map(function ($item, $index) { - return ['index' => $index + 1, 'jumlah_curas' => $item['jumlah_curas']]; - })->sortBy('jumlah_curas')->values(); - - // 2. Mapping: urutan jumlah_curas kecil = aman (id 1), sedang (id 2), besar = rawan (id 3) - $centroidToKlaster = [ - $finalCentroids[0]['index'] => 1, // aman - $finalCentroids[1]['index'] => 2, // sedang - $finalCentroids[2]['index'] => 3, // rawan + $k = 3; + $maxIterasi = 100; + $centroids = $data->random($k)->values()->map(function ($item) { + return [ + 'jumlah_curas' => $item->jumlah_curas, ]; + }); + $iterasi = []; + $prevAssignment = []; + + for ($i = 0; $i < $maxIterasi; $i++) { + $clustered = []; + $currentAssignment = []; - // Update klaster_id di database foreach ($data as $item) { - Curas::where('id', $item->id)->update([ - 'klaster_id' => $centroidToKlaster[$item->temp_klaster] // ← mapped ke klaster DB - ]); - + $jarak = []; + + foreach ($centroids as $idx => $centroid) { + $dist = abs($item->jumlah_curas - $centroid['jumlah_curas']); + $jarak["jarakC" . ($idx + 1)] = $dist; + } + + $iterasi[$i][] = array_merge(['kecamatan_id' => $item->kecamatan_id], $jarak); + + $minIndex = array_keys($jarak, min($jarak))[0]; // e.g. "jarakC2" + $clusterNumber = (int) str_replace("jarakC", "", $minIndex); + + $clustered[$clusterNumber][] = $item; + $item->temp_klaster = $clusterNumber; + $currentAssignment[$item->id] = $clusterNumber; } - return response()->json($iterasi); + // ✨ Cek konvergensi: jika assignment sekarang == sebelumnya, break + if ($currentAssignment === $prevAssignment) { + break; + } + + $prevAssignment = $currentAssignment; + + // Update centroid berdasarkan rata-rata + foreach ($clustered as $key => $group) { + $avg = collect($group)->avg('jumlah_curas'); + $centroids = $centroids->map(function ($item, $index) use ($key, $avg) { + return $index === ($key - 1) + ? ['jumlah_curas' => $avg] + : $item; + }); + } } + + // Final mapping centroid ke klaster_id (aman/sedang/rawan) + $finalCentroids = $centroids->map(function ($item, $index) { + return ['index' => $index + 1, 'jumlah_curas' => $item['jumlah_curas']]; + })->sortBy('jumlah_curas')->values(); + + $centroidToKlaster = [ + $finalCentroids[0]['index'] => 1, // aman + $finalCentroids[1]['index'] => 2, // sedang + $finalCentroids[2]['index'] => 3, // rawan + ]; + + // Update ke database + foreach ($data as $item) { + Curas::where('id', $item->id)->update([ + 'klaster_id' => $centroidToKlaster[$item->temp_klaster], + ]); + } + + session(['hasil_iterasi' => $iterasi]); + + return response()->json($iterasi); + } + } diff --git a/app/Http/Controllers/hasilIterasiController.php b/app/Http/Controllers/hasilIterasiController.php new file mode 100644 index 0000000..4962157 --- /dev/null +++ b/app/Http/Controllers/hasilIterasiController.php @@ -0,0 +1,17 @@ + 'Krenjengan', + 'nama_kecamatan'=> 'Krejengan', ]); Kecamatan::create([ diff --git a/resources/views/Admin/dashboardIterasiCuras.blade.php b/resources/views/Admin/dashboardIterasiCuras.blade.php new file mode 100644 index 0000000..51e6126 --- /dev/null +++ b/resources/views/Admin/dashboardIterasiCuras.blade.php @@ -0,0 +1,70 @@ + +
+
+
+
+
+
+

Iterasi K-Means Untuk Kasus Curas

+

Sales enables you to effectively control sales KPIs and monitor them in one central
+ place while helping teams to reach sales goals.

+
+ Tambah Kasus Curas +
+ @if (session()->has('succes')) + + @endif + @if (session()->has('error')) + + @endif +
+
+ @foreach ($iterasi as $i => $baris) +

Iterasi {{ $i + 1 }}

+
+ + + + + + + + + + + + @foreach ($baris as $row) + + + + + + + + + + + @endforeach +
+
+ + +
+
NoNama KecamatanJarak Ke Centroid 1Jarak Ke Centroid 2Jarak Ke Centroid 3
+
+ + +
+
{{ $loop->iteration }}{{ $row['kecamatan_id'] }}{{ $row['jarakC1'] }}{{ $row['jarakC2'] }}{{ $row['jarakC3'] }}
+
+ @endforeach +
+
+ +
+
+
\ No newline at end of file diff --git a/routes/web.php b/routes/web.php index 88a1b28..f78ab61 100644 --- a/routes/web.php +++ b/routes/web.php @@ -5,6 +5,7 @@ use App\Http\Controllers\KlasterController; use App\Http\Controllers\CuranmorController; use App\Http\Controllers\curasKmeansController; +use App\Http\Controllers\hasilIterasiController; use App\Http\Controllers\KecamatanController; Route::get('/', function () { @@ -29,3 +30,4 @@ Route::resource('/curanmor', CuranmorController::class) ->parameters(['data-curanmor' => 'curanmor']); Route::resource('/klaster', KlasterController::class) ->parameters(['data-klaster' => 'klaster']); Route::get('/hitung-kmeans', [curasKmeansController::class, 'hitungKMeans']); +Route::get('/iterasiCuras', [hasilIterasiController::class, 'iterasiCuras']);