From 7b68598ee9b0e47de5d5e8c78557d02bb32951e5 Mon Sep 17 00:00:00 2001 From: daffarahman11 Date: Sun, 6 Apr 2025 21:42:32 +0700 Subject: [PATCH] Update Fitur Clustering K-Means --- .../Controllers/curasKmeansController.php | 82 +++++++++++++++++++ routes/web.php | 2 + 2 files changed, 84 insertions(+) create mode 100644 app/Http/Controllers/curasKmeansController.php diff --git a/app/Http/Controllers/curasKmeansController.php b/app/Http/Controllers/curasKmeansController.php new file mode 100644 index 0000000..5192ee2 --- /dev/null +++ b/app/Http/Controllers/curasKmeansController.php @@ -0,0 +1,82 @@ +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 + ]; + + + // 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 + ]); + + } + + return response()->json($iterasi); + } +} diff --git a/routes/web.php b/routes/web.php index b9f45e7..88a1b28 100644 --- a/routes/web.php +++ b/routes/web.php @@ -4,6 +4,7 @@ use App\Http\Controllers\CurasController; use App\Http\Controllers\KlasterController; use App\Http\Controllers\CuranmorController; +use App\Http\Controllers\curasKmeansController; use App\Http\Controllers\KecamatanController; Route::get('/', function () { @@ -27,3 +28,4 @@ Route::resource('/curas', CurasController::class); 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']);