Update Service Kmeans dan Kmeans Controller
This commit is contained in:
parent
967b012cf1
commit
5dd6f4a297
|
@ -10,25 +10,27 @@
|
||||||
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');
|
$k = Klaster::count('id');
|
||||||
$maxIterasi = 100;
|
$maxIterasi = 100;
|
||||||
|
|
||||||
// Simpan centroid awal ke variabel terpisah
|
$uniqueCount = $data->unique('jumlah_curas')->count();
|
||||||
$uniqueJumlahCuras = $data->pluck('jumlah_curas')->unique()->shuffle()->take($k)->values();
|
if ($uniqueCount < $k) {
|
||||||
|
throw new \Exception("Jumlah nilai unik pada 'jumlah_curas' ($uniqueCount) kurang dari jumlah klaster ($k). Pastikan data memiliki variasi yang cukup.");
|
||||||
|
}
|
||||||
|
|
||||||
$initialCentroids = $uniqueJumlahCuras->map(function ($jumlah) {
|
// Ambil centroid awal yang unik
|
||||||
return ['jumlah_curas' => $jumlah];
|
// Gunakan centroid tetap
|
||||||
|
|
||||||
|
$centroidValues = [0, 1, 3];
|
||||||
|
$centroids = collect($centroidValues)->map(function ($val) {
|
||||||
|
return ['jumlah_curas' => $val];
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Simpan centroid awal sebelum iterasi
|
||||||
// Salin untuk digunakan dalam proses iterasi
|
$centroidAwal = $centroids->toArray();
|
||||||
$centroids = $initialCentroids->map(function ($item) {
|
|
||||||
return $item;
|
|
||||||
});
|
|
||||||
|
|
||||||
$iterasi = [];
|
$iterasi = [];
|
||||||
$prevAssignment = [];
|
$prevAssignment = [];
|
||||||
|
@ -42,25 +44,28 @@ public function KMeansCuras()
|
||||||
|
|
||||||
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;
|
||||||
$currentAssignment[$item->id] = $clusterNumber;
|
$currentAssignment[$item->id] = $clusterNumber;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ✨ Cek konvergensi: jika assignment sekarang == sebelumnya, break
|
||||||
if ($currentAssignment === $prevAssignment) {
|
if ($currentAssignment === $prevAssignment) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
$prevAssignment = $currentAssignment;
|
$prevAssignment = $currentAssignment;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Update centroid berdasarkan rata-rata
|
// Update centroid berdasarkan rata-rata
|
||||||
foreach ($clustered as $key => $group) {
|
foreach ($clustered as $key => $group) {
|
||||||
$avg = collect($group)->avg('jumlah_curas');
|
$avg = collect($group)->avg('jumlah_curas');
|
||||||
|
@ -72,103 +77,67 @@ public function KMeansCuras()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Final mapping centroid ke klaster_id
|
|
||||||
|
// Final mapping centroid ke klaster_id (aman/sedang/rawan)
|
||||||
$finalCentroids = $centroids->map(function ($item, $index) {
|
$finalCentroids = $centroids->map(function ($item, $index) {
|
||||||
return ['index' => $index + 1, 'jumlah_curas' => $item['jumlah_curas']];
|
return ['index' => $index + 1, 'jumlah_curas' => $item['jumlah_curas']];
|
||||||
})->sortBy('jumlah_curas')->values();
|
})->sortBy('jumlah_curas')->values();
|
||||||
|
|
||||||
$centroidToKlaster = [];
|
$centroidToKlaster = [];
|
||||||
|
|
||||||
foreach ($finalCentroids as $i => $centroid) {
|
foreach ($finalCentroids as $i => $centroid) {
|
||||||
|
// Klaster ID mulai dari 1 (asumsi klaster di DB bernomor 1, 2, 3, ...)
|
||||||
$centroidToKlaster[$centroid['index']] = $i + 1;
|
$centroidToKlaster[$centroid['index']] = $i + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Update ke database
|
||||||
foreach ($data as $item) {
|
foreach ($data as $item) {
|
||||||
Curas::where('id', $item->id)->update([
|
Curas::where('id', $item->id)->update([
|
||||||
'klaster_id' => $centroidToKlaster[$item->temp_klaster],
|
'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.
|
$centroidAwalFormatted = collect($centroidAwal)->values()->map(function ($item, $index) {
|
||||||
$formattedInitialCentroids = [];
|
return ['C' . ($index + 1) => $item['jumlah_curas']];
|
||||||
foreach ($initialCentroids as $i => $centroid) {
|
});
|
||||||
$formattedInitialCentroids['Centroid ' . ($i + 1)] = $centroid['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');
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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();
|
||||||
|
|
||||||
|
$k = Klaster::count('id');
|
||||||
$maxIterasi = 100;
|
$maxIterasi = 100;
|
||||||
$hasilElbow = [];
|
|
||||||
|
|
||||||
for ($k = 1; $k <= 10; $k++) {
|
$uniqueCount = $data->unique('jumlah_curanmor')->count();
|
||||||
// Ambil centroid awal secara acak
|
if ($uniqueCount < $k) {
|
||||||
$centroids = $data->random($k)->values()->map(function ($item) {
|
throw new \Exception("Jumlah nilai unik pada 'jumlah_curanmor' ($uniqueCount) kurang dari jumlah klaster ($k). Pastikan data memiliki variasi yang cukup.");
|
||||||
return ['jumlah_curanmor' => $item->jumlah_curanmor];
|
}
|
||||||
|
|
||||||
|
$centroidValues = [10, 20, 30];
|
||||||
|
$centroids = collect($centroidValues)->map(function ($val) {
|
||||||
|
return ['jumlah_curanmor' => $val];
|
||||||
});
|
});
|
||||||
|
|
||||||
$prevAssignment = [];
|
// Simpan centroid awal sebelum iterasi
|
||||||
|
$centroidAwal = $centroids->toArray();
|
||||||
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[$idx] = $dist;
|
|
||||||
}
|
|
||||||
|
|
||||||
$minIndex = array_keys($jarak, min($jarak))[0];
|
|
||||||
$clustered[$minIndex][] = $item;
|
|
||||||
$currentAssignment[$item->id] = $minIndex;
|
|
||||||
$item->temp_klaster = $minIndex;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($currentAssignment === $prevAssignment) break;
|
|
||||||
$prevAssignment = $currentAssignment;
|
|
||||||
|
|
||||||
foreach ($clustered as $key => $group) {
|
|
||||||
$avg = collect($group)->avg('jumlah_curanmor');
|
|
||||||
$centroids[$key] = ['jumlah_curanmor' => $avg];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Hitung SSE (Sum of Squared Errors)
|
|
||||||
$sse = 0;
|
|
||||||
foreach ($data as $item) {
|
|
||||||
$centroidVal = $centroids[$item->temp_klaster]['jumlah_curanmor'];
|
|
||||||
$sse += pow($item->jumlah_curanmor - $centroidVal, 2);
|
|
||||||
}
|
|
||||||
|
|
||||||
$hasilElbow[] = ['k' => $k, 'sse' => $sse];
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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 = [];
|
$iterasi = [];
|
||||||
$prevAssignment = [];
|
$prevAssignment = [];
|
||||||
|
@ -182,25 +151,29 @@ 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["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];
|
$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;
|
||||||
$currentAssignment[$item->id] = $clusterNumber;
|
$currentAssignment[$item->id] = $clusterNumber;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ✨ Cek konvergensi: jika assignment sekarang == sebelumnya, break
|
||||||
if ($currentAssignment === $prevAssignment) {
|
if ($currentAssignment === $prevAssignment) {
|
||||||
break;
|
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 = $centroids->map(function ($item, $index) use ($key, $avg) {
|
$centroids = $centroids->map(function ($item, $index) use ($key, $avg) {
|
||||||
|
@ -211,6 +184,8 @@ public function KMeansCuranmor()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Final mapping centroid ke klaster_id (aman/sedang/rawan)
|
||||||
$finalCentroids = $centroids->map(function ($item, $index) {
|
$finalCentroids = $centroids->map(function ($item, $index) {
|
||||||
return ['index' => $index + 1, 'jumlah_curanmor' => $item['jumlah_curanmor']];
|
return ['index' => $index + 1, 'jumlah_curanmor' => $item['jumlah_curanmor']];
|
||||||
})->sortBy('jumlah_curanmor')->values();
|
})->sortBy('jumlah_curanmor')->values();
|
||||||
|
@ -218,17 +193,35 @@ public function KMeansCuranmor()
|
||||||
$centroidToKlaster = [];
|
$centroidToKlaster = [];
|
||||||
|
|
||||||
foreach ($finalCentroids as $i => $centroid) {
|
foreach ($finalCentroids as $i => $centroid) {
|
||||||
|
// Klaster ID mulai dari 1 (asumsi klaster di DB bernomor 1, 2, 3, ...)
|
||||||
$centroidToKlaster[$centroid['index']] = $i + 1;
|
$centroidToKlaster[$centroid['index']] = $i + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Update ke database
|
||||||
foreach ($data as $item) {
|
foreach ($data as $item) {
|
||||||
Curanmor::where('id', $item->id)->update([
|
Curanmor::where('id', $item->id)->update([
|
||||||
'klaster_id' => $centroidToKlaster[$item->temp_klaster],
|
'klaster_id' => $centroidToKlaster[$item->temp_klaster],
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
session(['hasil_iterasi' => $iterasi]);
|
|
||||||
return $iterasi;
|
$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');
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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'));
|
||||||
|
}
|
||||||
|
}
|
|
@ -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'));
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -15,12 +15,26 @@ public function hitungKMeansCuras()
|
||||||
|
|
||||||
$k = Klaster::count('id');
|
$k = Klaster::count('id');
|
||||||
$maxIterasi = 100;
|
$maxIterasi = 100;
|
||||||
$centroids = $data->random($k)->values()->map(function ($item) {
|
|
||||||
|
$uniqueCount = $data->unique('jumlah_curas')->count();
|
||||||
|
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 [
|
return [
|
||||||
'jumlah_curas' => $item->jumlah_curas,
|
'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,12 +120,26 @@ public function hitungKMeansCuranmor()
|
||||||
|
|
||||||
$k = Klaster::count('id');
|
$k = Klaster::count('id');
|
||||||
$maxIterasi = 100;
|
$maxIterasi = 100;
|
||||||
$centroids = $data->random($k)->values()->map(function ($item) {
|
|
||||||
|
$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.");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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 [
|
return [
|
||||||
'jumlah_curanmor' => $item->jumlah_curanmor,
|
'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)
|
||||||
|
);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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));
|
||||||
|
|
|
@ -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>
|
|
@ -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>
|
|
@ -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">
|
||||||
|
|
|
@ -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']);
|
||||||
|
|
Loading…
Reference in New Issue