Update Service Kmeans dan Kmeans Controller

This commit is contained in:
daffarahman11 2025-05-01 13:05:37 +07:00
parent 967b012cf1
commit 5dd6f4a297
10 changed files with 628 additions and 230 deletions

View File

@ -10,115 +10,136 @@
class KmeansController extends Controller class KmeansController extends Controller
{ {
public function KMeansCuras() public function KMeansCuras()
{ {
$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 = Klaster::count('id');
$maxIterasi = 100;
$k = Klaster::count('id'); $uniqueCount = $data->unique('jumlah_curas')->count();
$maxIterasi = 100; if ($uniqueCount < $k) {
throw new \Exception("Jumlah nilai unik pada 'jumlah_curas' ($uniqueCount) kurang dari jumlah klaster ($k). Pastikan data memiliki variasi yang cukup.");
}
// Simpan centroid awal ke variabel terpisah // Ambil centroid awal yang unik
$uniqueJumlahCuras = $data->pluck('jumlah_curas')->unique()->shuffle()->take($k)->values(); // Gunakan centroid tetap
$initialCentroids = $uniqueJumlahCuras->map(function ($jumlah) { $centroidValues = [0, 1, 3];
return ['jumlah_curas' => $jumlah]; $centroids = collect($centroidValues)->map(function ($val) {
}); return ['jumlah_curas' => $val];
});
// Simpan centroid awal sebelum iterasi
$centroidAwal = $centroids->toArray();
// Salin untuk digunakan dalam proses iterasi $iterasi = [];
$centroids = $initialCentroids->map(function ($item) { $prevAssignment = [];
return $item;
});
$iterasi = []; for ($i = 0; $i < $maxIterasi; $i++) {
$prevAssignment = []; $clustered = [];
$currentAssignment = [];
for ($i = 0; $i < $maxIterasi; $i++) { foreach ($data as $item) {
$clustered = []; $jarak = [];
$currentAssignment = [];
foreach ($data as $item) { foreach ($centroids as $idx => $centroid) {
$jarak = []; $dist = abs($item->jumlah_curas - $centroid['jumlah_curas']);
$jarak["C" . ($idx + 1)] = $dist;
}
foreach ($centroids as $idx => $centroid) { $iterasi[$i][] = array_merge(['kecamatan_id' => $item->kecamatan_id], $jarak);
$dist = abs($item->jumlah_curas - $centroid['jumlah_curas']);
$jarak["jarakC" . ($idx + 1)] = $dist; $minIndex = array_keys($jarak, min($jarak))[0]; // e.g. "jarakC2"
$clusterNumber = (int) str_replace("C", "", $minIndex);
$clustered[$clusterNumber][] = $item;
$item->temp_klaster = $clusterNumber;
$currentAssignment[$item->id] = $clusterNumber;
} }
$iterasi[$i][] = array_merge(['kecamatan_id' => $item->kecamatan_id], $jarak); // ✨ Cek konvergensi: jika assignment sekarang == sebelumnya, break
if ($currentAssignment === $prevAssignment) {
break;
}
$minIndex = array_keys($jarak, min($jarak))[0]; // e.g. "jarakC2" $prevAssignment = $currentAssignment;
$clusterNumber = (int) str_replace("jarakC", "", $minIndex);
$clustered[$clusterNumber][] = $item;
$item->temp_klaster = $clusterNumber;
$currentAssignment[$item->id] = $clusterNumber; // 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;
});
}
} }
if ($currentAssignment === $prevAssignment) {
break; // 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 = [];
foreach ($finalCentroids as $i => $centroid) {
// Klaster ID mulai dari 1 (asumsi klaster di DB bernomor 1, 2, 3, ...)
$centroidToKlaster[$centroid['index']] = $i + 1;
} }
$prevAssignment = $currentAssignment;
// Update centroid berdasarkan rata-rata // Update ke database
foreach ($clustered as $key => $group) { foreach ($data as $item) {
$avg = collect($group)->avg('jumlah_curas'); Curas::where('id', $item->id)->update([
$centroids = $centroids->map(function ($item, $index) use ($key, $avg) { 'klaster_id' => $centroidToKlaster[$item->temp_klaster],
return $index === ($key - 1) ]);
? ['jumlah_curas' => $avg]
: $item;
});
} }
$centroidAwalFormatted = collect($centroidAwal)->values()->map(function ($item, $index) {
return ['C' . ($index + 1) => $item['jumlah_curas']];
});
$hasil = [
'centroid_awal' => $centroidAwalFormatted,
'iterasi' => $iterasi
];
file_put_contents(
storage_path('app/public/hasil_kmeans_curas.json'),
json_encode($hasil, JSON_PRETTY_PRINT)
);
return redirect('/dashboard/TampilHitungCuras');
} }
// Final mapping centroid ke klaster_id
$finalCentroids = $centroids->map(function ($item, $index) {
return ['index' => $index + 1, 'jumlah_curas' => $item['jumlah_curas']];
})->sortBy('jumlah_curas')->values();
$centroidToKlaster = [];
foreach ($finalCentroids as $i => $centroid) {
$centroidToKlaster[$centroid['index']] = $i + 1;
}
foreach ($data as $item) {
Curas::where('id', $item->id)->update([
'klaster_id' => $centroidToKlaster[$item->temp_klaster],
]);
}
// Simpan hasil iterasi dan centroid awal ke session
session([
'hasil_iterasi' => $iterasi,
'centroid_awal' => $initialCentroids
]);
// Format ulang centroid awal dengan label 'Centroid 1', dst.
$formattedInitialCentroids = [];
foreach ($initialCentroids as $i => $centroid) {
$formattedInitialCentroids['Centroid ' . ($i + 1)] = $centroid['jumlah_curas'];
}
return response()->json([
'centroid_awal' => $formattedInitialCentroids,
'hasil_iterasi' => $iterasi,
]);
}
public function KMeansCuranmor() public function KMeansCuranmor()
{ {
$data = Curanmor::select('id', 'kecamatan_id', 'klaster_id', 'jumlah_curanmor')->orderBy('jumlah_curanmor', 'asc')->get(); $data = Curanmor::select('id', 'kecamatan_id', 'klaster_id', 'jumlah_curanmor')->orderBy('jumlah_curanmor', 'asc')->get();
$maxIterasi = 100;
$hasilElbow = [];
for ($k = 1; $k <= 10; $k++) { $k = Klaster::count('id');
// Ambil centroid awal secara acak $maxIterasi = 100;
$centroids = $data->random($k)->values()->map(function ($item) {
return ['jumlah_curanmor' => $item->jumlah_curanmor]; $uniqueCount = $data->unique('jumlah_curanmor')->count();
if ($uniqueCount < $k) {
throw new \Exception("Jumlah nilai unik pada 'jumlah_curanmor' ($uniqueCount) kurang dari jumlah klaster ($k). Pastikan data memiliki variasi yang cukup.");
}
$centroidValues = [10, 20, 30];
$centroids = collect($centroidValues)->map(function ($val) {
return ['jumlah_curanmor' => $val];
}); });
// Simpan centroid awal sebelum iterasi
$centroidAwal = $centroids->toArray();
$iterasi = [];
$prevAssignment = []; $prevAssignment = [];
for ($i = 0; $i < $maxIterasi; $i++) { for ($i = 0; $i < $maxIterasi; $i++) {
@ -130,105 +151,77 @@ public function KMeansCuranmor()
foreach ($centroids as $idx => $centroid) { foreach ($centroids as $idx => $centroid) {
$dist = abs($item->jumlah_curanmor - $centroid['jumlah_curanmor']); $dist = abs($item->jumlah_curanmor - $centroid['jumlah_curanmor']);
$jarak[$idx] = $dist; $jarak["C" . ($idx + 1)] = $dist;
} }
$minIndex = array_keys($jarak, min($jarak))[0]; $iterasi[$i][] = array_merge(['kecamatan_id' => $item->kecamatan_id], $jarak);
$clustered[$minIndex][] = $item;
$currentAssignment[$item->id] = $minIndex; $minIndex = array_keys($jarak, min($jarak))[0]; // e.g. "jarakC2"
$item->temp_klaster = $minIndex; $clusterNumber = (int) str_replace("C", "", $minIndex);
$clustered[$clusterNumber][] = $item;
$item->temp_klaster = $clusterNumber;
$currentAssignment[$item->id] = $clusterNumber;
}
// ✨ Cek konvergensi: jika assignment sekarang == sebelumnya, break
if ($currentAssignment === $prevAssignment) {
break;
} }
if ($currentAssignment === $prevAssignment) break;
$prevAssignment = $currentAssignment; $prevAssignment = $currentAssignment;
// Update centroid berdasarkan rata-rata
foreach ($clustered as $key => $group) { foreach ($clustered as $key => $group) {
$avg = collect($group)->avg('jumlah_curanmor'); $avg = collect($group)->avg('jumlah_curanmor');
$centroids[$key] = ['jumlah_curanmor' => $avg]; $centroids = $centroids->map(function ($item, $index) use ($key, $avg) {
return $index === ($key - 1)
? ['jumlah_curanmor' => $avg]
: $item;
});
} }
} }
// Hitung SSE (Sum of Squared Errors)
$sse = 0; // Final mapping centroid ke klaster_id (aman/sedang/rawan)
$finalCentroids = $centroids->map(function ($item, $index) {
return ['index' => $index + 1, 'jumlah_curanmor' => $item['jumlah_curanmor']];
})->sortBy('jumlah_curanmor')->values();
$centroidToKlaster = [];
foreach ($finalCentroids as $i => $centroid) {
// Klaster ID mulai dari 1 (asumsi klaster di DB bernomor 1, 2, 3, ...)
$centroidToKlaster[$centroid['index']] = $i + 1;
}
// Update ke database
foreach ($data as $item) { foreach ($data as $item) {
$centroidVal = $centroids[$item->temp_klaster]['jumlah_curanmor']; Curanmor::where('id', $item->id)->update([
$sse += pow($item->jumlah_curanmor - $centroidVal, 2); 'klaster_id' => $centroidToKlaster[$item->temp_klaster],
]);
} }
$hasilElbow[] = ['k' => $k, 'sse' => $sse];
$centroidAwalFormatted = collect($centroidAwal)->values()->map(function ($item, $index) {
return ['C' . ($index + 1) => $item['jumlah_curanmor']];
});
$hasil = [
'centroid_awal' => $centroidAwalFormatted,
'iterasi' => $iterasi
];
file_put_contents(
storage_path('app/public/hasil_kmeans_curanmor.json'),
json_encode($hasil, JSON_PRETTY_PRINT)
);
return redirect('/dashboard/TampilHitungCuranmor');
} }
// Simpan hasil Elbow Method ke file
file_put_contents(storage_path('app/public/hasil_elbow_curanmor.json'), json_encode($hasilElbow, JSON_PRETTY_PRINT));
// ===================== //
// === Hitung k akhir === //
// ===================== //
$k = Klaster::count(); // misalnya 3
$centroids = $data->random($k)->values()->map(function ($item) {
return ['jumlah_curanmor' => $item->jumlah_curanmor];
});
$iterasi = [];
$prevAssignment = [];
for ($i = 0; $i < $maxIterasi; $i++) {
$clustered = [];
$currentAssignment = [];
foreach ($data as $item) {
$jarak = [];
foreach ($centroids as $idx => $centroid) {
$dist = abs($item->jumlah_curanmor - $centroid['jumlah_curanmor']);
$jarak["jarakC" . ($idx + 1)] = $dist;
}
$iterasi[$i][] = array_merge(['kecamatan_id' => $item->kecamatan_id], $jarak);
$minIndex = array_keys($jarak, min($jarak))[0];
$clusterNumber = (int) str_replace("jarakC", "", $minIndex);
$clustered[$clusterNumber][] = $item;
$item->temp_klaster = $clusterNumber;
$currentAssignment[$item->id] = $clusterNumber;
}
if ($currentAssignment === $prevAssignment) {
break;
}
$prevAssignment = $currentAssignment;
foreach ($clustered as $key => $group) {
$avg = collect($group)->avg('jumlah_curanmor');
$centroids = $centroids->map(function ($item, $index) use ($key, $avg) {
return $index === ($key - 1)
? ['jumlah_curanmor' => $avg]
: $item;
});
}
}
$finalCentroids = $centroids->map(function ($item, $index) {
return ['index' => $index + 1, 'jumlah_curanmor' => $item['jumlah_curanmor']];
})->sortBy('jumlah_curanmor')->values();
$centroidToKlaster = [];
foreach ($finalCentroids as $i => $centroid) {
$centroidToKlaster[$centroid['index']] = $i + 1;
}
foreach ($data as $item) {
Curanmor::where('id', $item->id)->update([
'klaster_id' => $centroidToKlaster[$item->temp_klaster],
]);
}
session(['hasil_iterasi' => $iterasi]);
return $iterasi;
}
} }

View File

@ -0,0 +1,41 @@
<?php
namespace App\Http\Controllers;
use App\Models\Kecamatan;
use Illuminate\Http\Request;
class TampilHitunganController extends Controller
{
public function TampilHitungCuras()
{
$file = storage_path('app/public/hasil_kmeans_curas.json');
if (!file_exists($file)) {
return abort(404, 'File hasil KMeans tidak ditemukan.');
}
$data = json_decode(file_get_contents($file), true);
// Ambil nama kecamatan berdasarkan ID
$kecamatan = Kecamatan::pluck('nama_kecamatan', 'id')->toArray();
return view('admin.HitungKmeans.HitunganCuras', compact('data', 'kecamatan'));
}
public function TampilHitungCuranmor()
{
$file = storage_path('app/public/hasil_kmeans_curanmor.json');
if (!file_exists($file)) {
return abort(404, 'File hasil KMeans tidak ditemukan.');
}
$data = json_decode(file_get_contents($file), true);
// Ambil nama kecamatan berdasarkan ID
$kecamatan = Kecamatan::pluck('nama_kecamatan', 'id')->toArray();
return view('admin.HitungKmeans.HitunganCuranmor', compact('data', 'kecamatan'));
}
}

View File

@ -1,17 +0,0 @@
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class hasilIterasiController extends Controller
{
public function iterasiCuras()
{
$iterasi = session('hasil_iterasi');
dd($iterasi);
// Kirim ke view atau proses lainnya
return view('admin.dashboarditerasiCuras', compact('iterasi'));
}
}

View File

@ -15,11 +15,25 @@ public function hitungKMeansCuras()
$k = Klaster::count('id'); $k = Klaster::count('id');
$maxIterasi = 100; $maxIterasi = 100;
$centroids = $data->random($k)->values()->map(function ($item) {
return [ $uniqueCount = $data->unique('jumlah_curas')->count();
'jumlah_curas' => $item->jumlah_curas, if ($uniqueCount < $k) {
]; throw new \Exception("Jumlah nilai unik pada 'jumlah_curas' ($uniqueCount) kurang dari jumlah klaster ($k). Pastikan data memiliki variasi yang cukup.");
}); }
// Ambil centroid awal yang unik
$centroids = $data->unique('jumlah_curas') // Pastikan nilai unik
->shuffle() // Acak
->take($k) // Ambil k data
->values()
->map(function ($item) {
return [
'jumlah_curas' => $item->jumlah_curas,
];
});
// Simpan centroid awal sebelum iterasi
$centroidAwal = $centroids->toArray();
$iterasi = []; $iterasi = [];
$prevAssignment = []; $prevAssignment = [];
@ -33,13 +47,13 @@ public function hitungKMeansCuras()
foreach ($centroids as $idx => $centroid) { foreach ($centroids as $idx => $centroid) {
$dist = abs($item->jumlah_curas - $centroid['jumlah_curas']); $dist = abs($item->jumlah_curas - $centroid['jumlah_curas']);
$jarak["jarakC" . ($idx + 1)] = $dist; $jarak["C" . ($idx + 1)] = $dist;
} }
$iterasi[$i][] = array_merge(['kecamatan_id' => $item->kecamatan_id], $jarak); $iterasi[$i][] = array_merge(['kecamatan_id' => $item->kecamatan_id], $jarak);
$minIndex = array_keys($jarak, min($jarak))[0]; // e.g. "jarakC2" $minIndex = array_keys($jarak, min($jarak))[0]; // e.g. "jarakC2"
$clusterNumber = (int) str_replace("jarakC", "", $minIndex); $clusterNumber = (int) str_replace("C", "", $minIndex);
$clustered[$clusterNumber][] = $item; $clustered[$clusterNumber][] = $item;
$item->temp_klaster = $clusterNumber; $item->temp_klaster = $clusterNumber;
@ -88,7 +102,15 @@ public function hitungKMeansCuras()
} }
return $iterasi; $centroidAwalFormatted = collect($centroidAwal)->values()->map(function ($item, $index) {
return ['C' . ($index + 1) => $item['jumlah_curas']];
});
return [
'centroid_awal' => $centroidAwalFormatted,
'iterasi' => $iterasi
];
} }
@ -98,11 +120,25 @@ public function hitungKMeansCuranmor()
$k = Klaster::count('id'); $k = Klaster::count('id');
$maxIterasi = 100; $maxIterasi = 100;
$centroids = $data->random($k)->values()->map(function ($item) {
return [ $uniqueCount = $data->unique('jumlah_curanmor')->count();
'jumlah_curanmor' => $item->jumlah_curanmor, if ($uniqueCount < $k) {
]; throw new \Exception("Jumlah nilai unik pada 'jumlah_curanmor' ($uniqueCount) kurang dari jumlah klaster ($k). Pastikan data memiliki variasi yang cukup.");
}); }
// Ambil centroid awal yang unik
$centroids = $data->unique('jumlah_curanmor') // Pastikan nilai unik
->shuffle() // Acak
->take($k) // Ambil k data
->values()
->map(function ($item) {
return [
'jumlah_curanmor' => $item->jumlah_curanmor,
];
});
// Simpan centroid awal sebelum iterasi
$centroidAwal = $centroids->toArray();
$iterasi = []; $iterasi = [];
$prevAssignment = []; $prevAssignment = [];
@ -116,13 +152,13 @@ public function hitungKMeansCuranmor()
foreach ($centroids as $idx => $centroid) { foreach ($centroids as $idx => $centroid) {
$dist = abs($item->jumlah_curanmor - $centroid['jumlah_curanmor']); $dist = abs($item->jumlah_curanmor - $centroid['jumlah_curanmor']);
$jarak["jarakC" . ($idx + 1)] = $dist; $jarak["C" . ($idx + 1)] = $dist;
} }
$iterasi[$i][] = array_merge(['kecamatan_id' => $item->kecamatan_id], $jarak); $iterasi[$i][] = array_merge(['kecamatan_id' => $item->kecamatan_id], $jarak);
$minIndex = array_keys($jarak, min($jarak))[0]; // e.g. "jarakC2" $minIndex = array_keys($jarak, min($jarak))[0]; // e.g. "jarakC2"
$clusterNumber = (int) str_replace("jarakC", "", $minIndex); $clusterNumber = (int) str_replace("C", "", $minIndex);
$clustered[$clusterNumber][] = $item; $clustered[$clusterNumber][] = $item;
$item->temp_klaster = $clusterNumber; $item->temp_klaster = $clusterNumber;
@ -170,8 +206,162 @@ public function hitungKMeansCuranmor()
]); ]);
} }
session(['hasil_iterasi' => $iterasi]);
return $iterasi; $centroidAwalFormatted = collect($centroidAwal)->values()->map(function ($item, $index) {
return ['C' . ($index + 1) => $item['jumlah_curanmor']];
});
return [
'centroid_awal' => $centroidAwalFormatted,
'iterasi' => $iterasi
];
} }
public function SSEElbowCuras()
{
$data = Curas::select('id', 'jumlah_curas')->get();
$maxK = 10;
$maxIterasi = 100;
$elbowData = [];
for ($k = 1; $k <= $maxK; $k++) {
// Inisialisasi centroid awal secara acak
$centroids = $data->unique('jumlah_curas')->shuffle()->take($k)->values()->map(function ($item) {
return ['jumlah_curas' => $item->jumlah_curas];
});
$prevAssignment = [];
for ($iter = 0; $iter < $maxIterasi; $iter++) {
$clustered = [];
$currentAssignment = [];
foreach ($data as $item) {
$jarak = [];
foreach ($centroids as $idx => $centroid) {
$dist = abs($item->jumlah_curas - $centroid['jumlah_curas']);
$jarak[$idx] = $dist;
}
$minIndex = array_keys($jarak, min($jarak))[0];
$clustered[$minIndex][] = $item;
$currentAssignment[$item->id] = $minIndex;
}
if ($currentAssignment === $prevAssignment) {
break;
}
$prevAssignment = $currentAssignment;
// Update centroid
foreach ($clustered as $key => $group) {
$avg = collect($group)->avg('jumlah_curas');
$centroids = $centroids->map(function ($centroid, $idx) use ($key, $avg) {
return $idx == $key
? ['jumlah_curas' => $avg]
: $centroid;
});
}
}
// Hitung SSE untuk k saat ini
$sse = 0;
foreach ($clustered as $key => $group) {
$centroidVal = $centroids[$key]['jumlah_curas'];
foreach ($group as $item) {
$sse += pow($item->jumlah_curas - $centroidVal, 2);
}
}
$elbowData[] = [
'k' => $k,
'sse' => $sse
];
}
// Simpan ke file
file_put_contents(
storage_path('app/public/sse_elbow_curas.json'),
json_encode($elbowData, JSON_PRETTY_PRINT)
);
}
public function SSEElbowCuranmor()
{
$data = Curanmor::select('id', 'jumlah_curanmor')->get();
$maxK = 10;
$maxIterasi = 100;
$elbowData = [];
for ($k = 1; $k <= $maxK; $k++) {
srand(time());
// Inisialisasi centroid awal secara acak
$centroids = $data->unique('jumlah_curanmor')->shuffle()->take($k)->values()->map(function ($item) {
return ['jumlah_curanmor' => $item->jumlah_curanmor];
});
$prevAssignment = [];
for ($iter = 0; $iter < $maxIterasi; $iter++) {
$clustered = [];
$currentAssignment = [];
foreach ($data as $item) {
$jarak = [];
foreach ($centroids as $idx => $centroid) {
$dist = abs($item->jumlah_curanmor - $centroid['jumlah_curanmor']);
$jarak[$idx] = $dist;
}
$minIndex = array_keys($jarak, min($jarak))[0];
$clustered[$minIndex][] = $item;
$currentAssignment[$item->id] = $minIndex;
}
if ($currentAssignment === $prevAssignment) {
break;
}
$prevAssignment = $currentAssignment;
// Update centroid
foreach ($clustered as $key => $group) {
$avg = collect($group)->avg('jumlah_curanmor');
$centroids = $centroids->map(function ($centroid, $idx) use ($key, $avg) {
return $idx == $key
? ['jumlah_curanmor' => $avg]
: $centroid;
});
}
}
// Hitung SSE untuk k saat ini
$sse = 0;
foreach ($clustered as $key => $group) {
$centroidVal = $centroids[$key]['jumlah_curanmor'];
foreach ($group as $item) {
$sse += pow($item->jumlah_curanmor - $centroidVal, 2);
}
}
$elbowData[] = [
'k' => $k,
'sse' => $sse
];
}
// Simpan ke file
file_put_contents(
storage_path('app/public/sse_elbow_curanmor.json'),
json_encode($elbowData, JSON_PRETTY_PRINT)
);
}
} }

View File

@ -25,6 +25,12 @@ public function run(): void
CuranmorSeeder::class, CuranmorSeeder::class,
]); ]);
$serviceKMeansCuras = new KMeansService();
$hasilKMeansCuras = $serviceKMeansCuras->SSEElbowCuras();
$serviceKMeansCuras = new KMeansService();
$hasilKMeansCuras = $serviceKMeansCuras->SSEElbowCuranmor();
$serviceKMeansCuras = new KMeansService(); $serviceKMeansCuras = new KMeansService();
$hasilKMeansCuras = $serviceKMeansCuras->hitungKMeansCuras(); $hasilKMeansCuras = $serviceKMeansCuras->hitungKMeansCuras();
file_put_contents(storage_path('app/public/hasil_kmeans_curas.json'), json_encode($hasilKMeansCuras)); file_put_contents(storage_path('app/public/hasil_kmeans_curas.json'), json_encode($hasilKMeansCuras));

View File

@ -18,14 +18,14 @@ public function run(): void
'warna'=> '#00FF00', 'warna'=> '#00FF00',
]); ]);
Klaster::create([ Klaster::create([
'nama_klaster'=> 'Sedang', 'nama_klaster'=> 'Sedang',
'warna'=> '#FFFF00', 'warna'=> '#FFFF00',
]); ]);
Klaster::create([ Klaster::create([
'nama_klaster'=> 'Rawan', 'nama_klaster'=> 'Rawan',
'warna'=> '#FF0000', 'warna'=> '#FF0000',
]); ]);
} }
} }

View File

@ -0,0 +1,91 @@
<x-layoutAdmin>
<div class="content-page">
<div class="container-fluid">
<div class="row">
<div class="col-lg-12">
<div class="d-flex flex-wrap align-items-center justify-content-between mb-4">
<div>
<h4 class="mb-3">Detail Perhitungan Curanmor</h4>
<p class="mb-0">Berikut merupakan detail perhitungan jarak antar setiap data terhadap setiap centroid pada masing masing iterasi. </p>
</div>
</div>
@if (session()->has('succes'))
<div class="alert alert-success" role="alert">
{{ session('succes') }}
</div>
@endif
@if (session()->has('error'))
<div class="alert alert-danger" role="alert">
{{ session('error') }}
</div>
@endif
</div>
<div class="col-lg-12">
<h5>Nilai Centroid Awal</h5>
<table class="data-table table mb-0 tbl-server-info">
<thead class="bg-white text-uppercase">
<tr class="ligth ligth-data">
@foreach ($data['centroid_awal'] as $centroid)
<th class="text-center">{{ array_key_first($centroid) }}</th>
@endforeach
</tr>
</thead>
<tbody class="ligth-body">
<tr>
@foreach ($data['centroid_awal'] as $centroid)
<td class="text-center">{{ array_values($centroid)[0] }}</td>
@endforeach
</tr>
</tbody>
</table>
</div>
<div class="col-lg-12">
<br><br><br>
@foreach ($data['iterasi'] as $index => $iterasi)
<h5>Iterasi ke-{{ $index + 1 }}</h5>
<div class="table-responsive rounded mb-3">
<table class="data-table table mb-0 tbl-server-info">
<thead class="bg-white text-uppercase">
<tr class="ligth ligth-data">
<th>Nama Kecamatan</th>
@foreach (array_keys($iterasi[0]) as $key)
@if ($key !== 'kecamatan_id')
<th class="text-center">{{ $key }}</th>
@endif
@endforeach
<th>Hasil</th>
</tr>
</thead>
<tbody class="ligth-body">
@foreach ($iterasi as $row)
@php
$minKey = null;
$minVal = INF;
foreach ($row as $key => $val) {
if (strpos($key, 'C') === 0 && $val < $minVal) {
$minVal = $val;
$minKey = $key;
}
}
@endphp
<tr>
<td class="text-left">{{ $kecamatan[$row['kecamatan_id']] ?? 'Tidak Diketahui' }}</td>
@foreach ($row as $key => $val)
@if ($key !== 'kecamatan_id')
<td class="text-center">{{ $val }}</td>
@endif
@endforeach
<td><strong>{{ strtoupper($minKey) }}</strong></td>
</tr>
@endforeach
</tbody>
</table>
</div>
@endforeach
</div>
</div>
<!-- Page end -->
</div>
</div>
</x-layoutAdmin>

View File

@ -0,0 +1,91 @@
<x-layoutAdmin>
<div class="content-page">
<div class="container-fluid">
<div class="row">
<div class="col-lg-12">
<div class="d-flex flex-wrap align-items-center justify-content-between mb-4">
<div>
<h4 class="mb-3">Detail Perhitungan Curas</h4>
<p class="mb-0">Berikut merupakan detail perhitungan jarak antar setiap data terhadap setiap centroid pada masing masing iterasi. </p>
</div>
</div>
@if (session()->has('succes'))
<div class="alert alert-success" role="alert">
{{ session('succes') }}
</div>
@endif
@if (session()->has('error'))
<div class="alert alert-danger" role="alert">
{{ session('error') }}
</div>
@endif
</div>
<div class="col-lg-12">
<h5>Nilai Centroid Awal</h5>
<table class="data-table table mb-0 tbl-server-info">
<thead class="bg-white text-uppercase">
<tr class="ligth ligth-data">
@foreach ($data['centroid_awal'] as $centroid)
<th class="text-center">{{ array_key_first($centroid) }}</th>
@endforeach
</tr>
</thead>
<tbody class="ligth-body">
<tr>
@foreach ($data['centroid_awal'] as $centroid)
<td class="text-center">{{ array_values($centroid)[0] }}</td>
@endforeach
</tr>
</tbody>
</table>
</div>
<div class="col-lg-12">
<br><br><br>
@foreach ($data['iterasi'] as $index => $iterasi)
<h5>Iterasi ke-{{ $index + 1 }}</h5>
<div class="table-responsive rounded mb-3">
<table class="data-table table mb-0 tbl-server-info">
<thead class="bg-white text-uppercase">
<tr class="ligth ligth-data">
<th>Nama Kecamatan</th>
@foreach (array_keys($iterasi[0]) as $key)
@if ($key !== 'kecamatan_id')
<th class="text-center">{{ $key }}</th>
@endif
@endforeach
<th>Hasil</th>
</tr>
</thead>
<tbody class="ligth-body">
@foreach ($iterasi as $row)
@php
$minKey = null;
$minVal = INF;
foreach ($row as $key => $val) {
if (strpos($key, 'C') === 0 && $val < $minVal) {
$minVal = $val;
$minKey = $key;
}
}
@endphp
<tr>
<td class="text-left">{{ $kecamatan[$row['kecamatan_id']] ?? 'Tidak Diketahui' }}</td>
@foreach ($row as $key => $val)
@if ($key !== 'kecamatan_id')
<td class="text-center">{{ $val }}</td>
@endif
@endforeach
<td><strong>{{ strtoupper($minKey) }}</strong></td>
</tr>
@endforeach
</tbody>
</table>
</div>
@endforeach
</div>
</div>
<!-- Page end -->
</div>
</div>
</x-layoutAdmin>

View File

@ -1,6 +1,7 @@
<x-layoutAdmin> <x-layoutAdmin>
<div class="content-page"> <div class="content-page">
<div class="container-fluid add-form-list"> <div class="container-fluid add-form-
">
<div class="row"> <div class="row">
<div class="col-sm-12"> <div class="col-sm-12">
<div class="card"> <div class="card">

View File

@ -10,20 +10,32 @@
use App\Http\Controllers\dashboardController; use App\Http\Controllers\dashboardController;
use App\Http\Controllers\KecamatanController; use App\Http\Controllers\KecamatanController;
use App\Http\Controllers\DetailCurasController; use App\Http\Controllers\DetailCurasController;
use App\Http\Controllers\hasilIterasiController;
use App\Http\Controllers\DetailCuranmorController; use App\Http\Controllers\DetailCuranmorController;
use App\Http\Controllers\TampilHitunganController;
// Route Landing
Route::get('/', [LandingController::class, 'index']); Route::get('/', [LandingController::class, 'index']);
Route::resource('/dashboard/detail-curas', DetailCurasController::class)->middleware('auth');
Route::resource('/dashboard/detail-curanmor', DetailCuranmorController::class)->middleware('auth');
Route::get('/blank', function () { Route::get('/blank', function () {
return view('admin.dashboardBlank'); return view('admin.dashboardBlank');
}); });
// Route Auth
Route::post('/login', [loginController::class, 'authenticate']);
Route::post('/logout', [loginController::class, 'logout']);
Route::get('/login', [loginController::class, 'index'])->name('login');
// Route Fitur Utama Controller
Route::get('/dashboard', [dashboardController::class, 'index'])->middleware('auth');
Route::get('/dashboard/TampilHitungCuras', [TampilHitunganController::class, 'TampilHitungCuras'])->middleware('auth');
Route::get('/dashboard/TampilHitungCuranmor', [TampilHitunganController::class, 'TampilHitungCuranmor'])->middleware('auth');
Route::resource('/dashboard/kecamatan', KecamatanController::class) ->parameters(['data-kecamatan' => 'kecamatan'])->middleware('auth');
Route::resource('/dashboard/klaster', KlasterController::class) ->parameters(['data-klaster' => 'klaster'])->middleware('auth');
Route::resource('/dashboard/curas', CurasController::class)->middleware('auth');
Route::resource('/dashboard/curanmor', CuranmorController::class) ->parameters(['data-curanmor' => 'curanmor'])->middleware('auth');
Route::resource('/dashboard/detail-curas', DetailCurasController::class)->middleware('auth');
Route::resource('/dashboard/detail-curanmor', DetailCuranmorController::class)->middleware('auth');
// Route Fitur Tampil Map Admin
Route::get('/dashboard/mapcuras', function () { Route::get('/dashboard/mapcuras', function () {
return view('admin.dashboardMapCuras'); return view('admin.dashboardMapCuras');
})->middleware('auth'); })->middleware('auth');
@ -31,16 +43,6 @@
return view('admin.dashboardMapCuranmor'); return view('admin.dashboardMapCuranmor');
})->middleware('auth'); })->middleware('auth');
Route::get('/dashboard', [dashboardController::class, 'index'])->middleware('auth'); // Route K-Means Centroid Tetap
Route::get('/login', [loginController::class, 'index'])->name('login');
Route::post('/login', [loginController::class, 'authenticate']);
Route::post('/logout', [loginController::class, 'logout']);
Route::resource('/dashboard/kecamatan', KecamatanController::class) ->parameters(['data-kecamatan' => 'kecamatan'])->middleware('auth');
Route::resource('/dashboard/curas', CurasController::class)->middleware('auth');
Route::resource('/dashboard/curanmor', CuranmorController::class) ->parameters(['data-curanmor' => 'curanmor'])->middleware('auth');
Route::resource('/dashboard/klaster', KlasterController::class) ->parameters(['data-klaster' => 'klaster'])->middleware('auth');
Route::get('/dashboard/iterasiCuras', [hasilIterasiController::class, 'iterasiCuras'])->middleware('auth');
Route::get('/kmeans-curas', [KmeansController::class, 'KMeansCuras']); Route::get('/kmeans-curas', [KmeansController::class, 'KMeansCuras']);
Route::get('/kmeans-curanmor', [KmeansController::class, 'KMeansCuranmor']); Route::get('/kmeans-curanmor', [KmeansController::class, 'KMeansCuranmor']);