update k-means random bukan uniq lagi
This commit is contained in:
parent
7b20b29157
commit
ae72f2717e
|
@ -5,10 +5,11 @@
|
||||||
use App\Models\Klaster;
|
use App\Models\Klaster;
|
||||||
use App\Models\Curanmor;
|
use App\Models\Curanmor;
|
||||||
use App\Models\Kecamatan;
|
use App\Models\Kecamatan;
|
||||||
use App\Models\Detail_Curanmor;
|
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
|
use App\Models\Detail_Curanmor;
|
||||||
use App\Services\KMeansService;
|
use App\Services\KMeansService;
|
||||||
use Illuminate\Validation\Rule;
|
use Illuminate\Validation\Rule;
|
||||||
|
use Illuminate\Support\Facades\DB;
|
||||||
|
|
||||||
class CuranmorController extends Controller
|
class CuranmorController extends Controller
|
||||||
{
|
{
|
||||||
|
@ -35,13 +36,14 @@ public function create()
|
||||||
*/
|
*/
|
||||||
public function store(Request $request)
|
public function store(Request $request)
|
||||||
{
|
{
|
||||||
|
$request->validate([
|
||||||
|
'kecamatan_id' => 'required|exists:kecamatans,id',
|
||||||
|
'jumlah_curanmor' => 'required|numeric',
|
||||||
|
]);
|
||||||
try{
|
try{
|
||||||
|
|
||||||
$request->validate([
|
DB::beginTransaction();
|
||||||
'kecamatan_id' => 'required|exists:kecamatans,id',
|
|
||||||
'jumlah_curanmor' => 'required|numeric',
|
|
||||||
]);
|
|
||||||
|
|
||||||
$kecamatan_id = $request->kecamatan_id;
|
$kecamatan_id = $request->kecamatan_id;
|
||||||
$tambahan_curanmor = $request->jumlah_curanmor;
|
$tambahan_curanmor = $request->jumlah_curanmor;
|
||||||
|
|
||||||
|
@ -75,18 +77,11 @@ public function store(Request $request)
|
||||||
$serviceSSECuranmor = new KMeansService();
|
$serviceSSECuranmor = new KMeansService();
|
||||||
$serviceSSECuranmor->SSEElbowCuranmor();
|
$serviceSSECuranmor->SSEElbowCuranmor();
|
||||||
|
|
||||||
// =====CODE TAMBAH SEBELUMNYA=========
|
DB::commit();
|
||||||
// $validateData = $request->validate([
|
|
||||||
// 'kecamatan_id' =>'required|max:255|exists:kecamatans,id|unique:curanmors,kecamatan_id',
|
|
||||||
// 'jumlah_curanmor' =>'required',
|
|
||||||
// 'klaster_id' =>'required|max:255|exists:klasters,id',
|
|
||||||
|
|
||||||
// ]);
|
|
||||||
|
|
||||||
// Curanmor::create($validateData);
|
|
||||||
return redirect('/dashboard/curanmor')->with('succes', 'Berhasil Menambahkan Data Curanmor Baru');
|
return redirect('/dashboard/curanmor')->with('succes', 'Berhasil Menambahkan Data Curanmor Baru');
|
||||||
}catch (\Exception $e){
|
}catch (\Exception $e){
|
||||||
return redirect('/dashboard/curanmor')->with('error', 'Gagal Menambahkan Data Curanmor Baru');
|
DB::rollBack();
|
||||||
|
return redirect('/dashboard/curanmor')->with('error', 'Gagal Menambahkan Data Curanmor Baru '. $e->getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -103,18 +98,6 @@ public function show(Curanmor $curanmor)
|
||||||
*/
|
*/
|
||||||
public function edit($curanmor)
|
public function edit($curanmor)
|
||||||
{
|
{
|
||||||
try {
|
|
||||||
|
|
||||||
$edit = Curanmor::find($curanmor);
|
|
||||||
|
|
||||||
return view('admin.dashboardEditCuranmor', [
|
|
||||||
'curanmor' => $edit,
|
|
||||||
'kecamatans' => Kecamatan::all(),
|
|
||||||
'klasters' => Klaster::all(),
|
|
||||||
]);
|
|
||||||
} catch (\Exception $e) {
|
|
||||||
abort(404);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -122,39 +105,7 @@ public function edit($curanmor)
|
||||||
*/
|
*/
|
||||||
public function update(Request $request, Curanmor $curanmor)
|
public function update(Request $request, Curanmor $curanmor)
|
||||||
{
|
{
|
||||||
try {
|
|
||||||
|
|
||||||
// Validasi input
|
|
||||||
$request->validate([
|
|
||||||
'kecamatan_id' => [
|
|
||||||
'required',
|
|
||||||
'exists:kecamatans,id',
|
|
||||||
Rule::unique('curanmors')->ignore($curanmor->id),
|
|
||||||
],
|
|
||||||
'klaster_id' => 'required|exists:klasters,id',
|
|
||||||
'jumlah_curanmor' => 'required|numeric|min:0',
|
|
||||||
]);
|
|
||||||
|
|
||||||
// Update data
|
|
||||||
$curanmor->update([
|
|
||||||
'kecamatan_id' => $request->kecamatan_id,
|
|
||||||
'klaster_id' => $request->klaster_id,
|
|
||||||
'jumlah_curanmor' => $request->jumlah_curanmor,
|
|
||||||
]);
|
|
||||||
|
|
||||||
$service = new KMeansService();
|
|
||||||
$hasil = $service->hitungKMeansCuranmor();
|
|
||||||
|
|
||||||
// simpan hasil ke file json
|
|
||||||
file_put_contents(storage_path('app/public/hasil_kmeans_curanmor.json'), json_encode($hasil));
|
|
||||||
|
|
||||||
$serviceSSECuranmor = new KMeansService();
|
|
||||||
$serviceSSECuranmor->SSEElbowCuranmor();
|
|
||||||
|
|
||||||
return redirect('/dashboard/curanmor')->with('succes', 'Data Kecamatan Berhasil Diubah');
|
|
||||||
} catch (\Exception $e) {
|
|
||||||
return redirect('/dashboard/curanmor')->with('error', 'Data Kecamatan Gagal Diubah: ' . $e->getMessage());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -162,25 +113,6 @@ public function update(Request $request, Curanmor $curanmor)
|
||||||
*/
|
*/
|
||||||
public function destroy($curanmor)
|
public function destroy($curanmor)
|
||||||
{
|
{
|
||||||
try {
|
|
||||||
// Cari data berdasarkan ID
|
|
||||||
$hapus = Curanmor::find($curanmor);
|
|
||||||
|
|
||||||
// Pastikan data ditemukan sebelum menghapus
|
|
||||||
if (!$hapus) {
|
|
||||||
return redirect('/dashboard/curanmor')->with('error', 'Data tidak ditemukan.');
|
|
||||||
}
|
|
||||||
|
|
||||||
// Hapus data
|
|
||||||
$hapus->delete();
|
|
||||||
|
|
||||||
$serviceSSECuranmor = new KMeansService();
|
|
||||||
$serviceSSECuranmor->SSEElbowCuranmor();
|
|
||||||
|
|
||||||
return redirect('/dashboard/curanmor')->with('succes', 'Data Curanmor Berhasil Dihapus');
|
|
||||||
} catch (\Exception $e) {
|
|
||||||
return redirect('/dashboard/curanmor')->with('error', 'Terjadi kesalahan: ' . $e->getMessage());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use App\Services\KMeansService;
|
use App\Services\KMeansService;
|
||||||
use Illuminate\Validation\Rule;
|
use Illuminate\Validation\Rule;
|
||||||
|
use Illuminate\Support\Facades\DB;
|
||||||
|
|
||||||
class CurasController extends Controller
|
class CurasController extends Controller
|
||||||
{
|
{
|
||||||
|
@ -36,13 +37,14 @@ public function create()
|
||||||
*/
|
*/
|
||||||
public function store(Request $request)
|
public function store(Request $request)
|
||||||
{
|
{
|
||||||
|
$request->validate([
|
||||||
|
'kecamatan_id' => 'required|exists:kecamatans,id',
|
||||||
|
'jumlah_curas' => 'required|numeric',
|
||||||
|
]);
|
||||||
try{
|
try{
|
||||||
|
|
||||||
$request->validate([
|
DB::beginTransaction();
|
||||||
'kecamatan_id' => 'required|exists:kecamatans,id',
|
|
||||||
'jumlah_curas' => 'required|numeric',
|
|
||||||
]);
|
|
||||||
|
|
||||||
$kecamatan_id = $request->kecamatan_id;
|
$kecamatan_id = $request->kecamatan_id;
|
||||||
$tambahan_curas = $request->jumlah_curas;
|
$tambahan_curas = $request->jumlah_curas;
|
||||||
|
|
||||||
|
@ -74,16 +76,19 @@ public function store(Request $request)
|
||||||
|
|
||||||
$service = new KMeansService();
|
$service = new KMeansService();
|
||||||
$hasil = $service->hitungKMeansCuras();
|
$hasil = $service->hitungKMeansCuras();
|
||||||
|
|
||||||
// simpan hasil ke file json
|
|
||||||
file_put_contents(storage_path('app/public/hasil_kmeans_curas.json'), json_encode($hasil));
|
file_put_contents(storage_path('app/public/hasil_kmeans_curas.json'), json_encode($hasil));
|
||||||
|
|
||||||
$serviceSSECuras = new KMeansService();
|
$serviceSSECuras = new KMeansService();
|
||||||
$serviceSSECuras->SSEElbowCuras();
|
$serviceSSECuras->SSEElbowCuras();
|
||||||
|
|
||||||
|
DB::commit();
|
||||||
|
|
||||||
return redirect('/dashboard/curas')->with('succes', 'Data curas berhasil ditambahkan.');
|
return redirect('/dashboard/curas')->with('succes', 'Data curas berhasil ditambahkan.');
|
||||||
}catch (\Exception $e){
|
}catch (\Exception $e){
|
||||||
return redirect('/dashboard/curas')->with('error', 'Gagal Menambahkan Data Curas Baru');
|
|
||||||
|
DB::rollBack();
|
||||||
|
return redirect('/dashboard/curas')->with('error', 'Gagal Menambahkan Data Curas Baru'. $e->getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -100,18 +105,6 @@ public function show(Curas $curas)
|
||||||
*/
|
*/
|
||||||
public function edit($curas)
|
public function edit($curas)
|
||||||
{
|
{
|
||||||
try {
|
|
||||||
|
|
||||||
$edit = Curas::find($curas);
|
|
||||||
|
|
||||||
return view('admin.dashboardEditCuras', [
|
|
||||||
'curas' => $edit,
|
|
||||||
'kecamatans' => Kecamatan::all(),
|
|
||||||
'klasters' => Klaster::all(),
|
|
||||||
]);
|
|
||||||
} catch (\Exception $e) {
|
|
||||||
abort(404);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -119,71 +112,13 @@ public function edit($curas)
|
||||||
*/
|
*/
|
||||||
public function update(Request $request, $id)
|
public function update(Request $request, $id)
|
||||||
{
|
{
|
||||||
try {
|
|
||||||
// Cari data berdasarkan ID yang dikirim
|
|
||||||
$curas = Curas::findOrFail($id);
|
|
||||||
|
|
||||||
// Debugging untuk memastikan data ditemukan
|
|
||||||
// dd($curas->toArray()); // Jika berhasil, ini akan menampilkan data curas
|
|
||||||
|
|
||||||
// Validasi input
|
|
||||||
$request->validate([
|
|
||||||
'kecamatan_id' => [
|
|
||||||
'required',
|
|
||||||
'exists:kecamatans,id',
|
|
||||||
Rule::unique('curas')->ignore($curas->id),
|
|
||||||
],
|
|
||||||
'klaster_id' => 'required|exists:klasters,id',
|
|
||||||
'jumlah_curas' => 'required|integer|min:0',
|
|
||||||
]);
|
|
||||||
|
|
||||||
// Update data
|
|
||||||
$curas->update([
|
|
||||||
'kecamatan_id' => $request->kecamatan_id,
|
|
||||||
'klaster_id' => $request->klaster_id,
|
|
||||||
'jumlah_curas' => $request->jumlah_curas,
|
|
||||||
]);
|
|
||||||
|
|
||||||
$service = new KMeansService();
|
|
||||||
$hasil = $service->hitungKMeansCuras();
|
|
||||||
|
|
||||||
// simpan hasil ke file json
|
|
||||||
file_put_contents(storage_path('app/public/hasil_kmeans_curas.json'), json_encode($hasil));
|
|
||||||
|
|
||||||
$serviceSSECuras = new KMeansService();
|
|
||||||
$serviceSSECuras->SSEElbowCuras();
|
|
||||||
|
|
||||||
return redirect('/dashboard/curas')->with('succes', 'Data Kecamatan Berhasil Diubah');
|
|
||||||
} catch (\Exception $e) {
|
|
||||||
return redirect('/dashboard/curas')->with('error', 'Data Kecamatan Gagal Diubah: ' . $e->getMessage());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Remove the specified resource from storage.
|
* Remove the specified resource from storage.
|
||||||
*/
|
*/
|
||||||
public function destroy($curas)
|
public function destroy($curas)
|
||||||
{
|
{
|
||||||
try {
|
|
||||||
// Cari data berdasarkan ID
|
|
||||||
$hapus = Curas::find($curas);
|
|
||||||
|
|
||||||
// Pastikan data ditemukan sebelum menghapus
|
|
||||||
if (!$hapus) {
|
|
||||||
return redirect('/dashboard/curas')->with('error', 'Data tidak ditemukan.');
|
|
||||||
}
|
|
||||||
|
|
||||||
// Hapus data
|
|
||||||
$hapus->delete();
|
|
||||||
|
|
||||||
return redirect('/dashboard/curas')->with('succes', 'Data Curas Berhasil Dihapus');
|
|
||||||
} catch (\Exception $e) {
|
|
||||||
return redirect('/dashboard/curas')->with('error', 'Terjadi kesalahan: ' . $e->getMessage());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use App\Models\Detail_Curanmor;
|
use App\Models\Detail_Curanmor;
|
||||||
use App\Services\KMeansService;
|
use App\Services\KMeansService;
|
||||||
|
use Illuminate\Support\Facades\DB;
|
||||||
|
|
||||||
class DetailCuranmorController extends Controller
|
class DetailCuranmorController extends Controller
|
||||||
{
|
{
|
||||||
|
@ -65,6 +66,8 @@ public function update(Request $request, Detail_Curanmor $detail_Curanmor)
|
||||||
public function destroy($id)
|
public function destroy($id)
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
|
|
||||||
|
DB::beginTransaction();
|
||||||
$detail = Detail_Curanmor::findOrFail($id);
|
$detail = Detail_Curanmor::findOrFail($id);
|
||||||
|
|
||||||
$curanmor = Curanmor::findOrFail($detail->curanmor_id);
|
$curanmor = Curanmor::findOrFail($detail->curanmor_id);
|
||||||
|
@ -89,8 +92,12 @@ public function destroy($id)
|
||||||
$serviceSSECuranmor = new KMeansService();
|
$serviceSSECuranmor = new KMeansService();
|
||||||
$serviceSSECuranmor->SSEElbowCuranmor();
|
$serviceSSECuranmor->SSEElbowCuranmor();
|
||||||
|
|
||||||
|
DB::commit();
|
||||||
|
|
||||||
return redirect('/dashboard/detail-curanmor')->with('succes', 'Data berhasil dihapus dan curanmor diperbarui.');
|
return redirect('/dashboard/detail-curanmor')->with('succes', 'Data berhasil dihapus dan curanmor diperbarui.');
|
||||||
} catch (\Exception $e) {
|
} catch (\Exception $e) {
|
||||||
|
|
||||||
|
DB::rollback();
|
||||||
return redirect('/dashboard/detail-curanmor')->with('error', 'Terjadi kesalahan Ketika Menghapus Data : ' . $e->getMessage());
|
return redirect('/dashboard/detail-curanmor')->with('error', 'Terjadi kesalahan Ketika Menghapus Data : ' . $e->getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
use App\Models\Detail_Curas;
|
use App\Models\Detail_Curas;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use App\Services\KMeansService;
|
use App\Services\KMeansService;
|
||||||
|
use Illuminate\Support\Facades\DB;
|
||||||
|
|
||||||
class DetailCurasController extends Controller
|
class DetailCurasController extends Controller
|
||||||
{
|
{
|
||||||
|
@ -65,6 +66,9 @@ public function update(Request $request, Detail_Curas $detail_Curas)
|
||||||
public function destroy($id)
|
public function destroy($id)
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
|
|
||||||
|
DB::beginTransaction();
|
||||||
|
|
||||||
$detail = Detail_Curas::findOrFail($id);
|
$detail = Detail_Curas::findOrFail($id);
|
||||||
|
|
||||||
// Ambil curas terkait
|
// Ambil curas terkait
|
||||||
|
@ -92,8 +96,12 @@ public function destroy($id)
|
||||||
$serviceSSECuras = new KMeansService();
|
$serviceSSECuras = new KMeansService();
|
||||||
$serviceSSECuras->SSEElbowCuras();
|
$serviceSSECuras->SSEElbowCuras();
|
||||||
|
|
||||||
|
DB::commit();
|
||||||
|
|
||||||
return redirect('/dashboard/detail-curas')->with('succes', 'Data berhasil dihapus dan curas diperbarui.');
|
return redirect('/dashboard/detail-curas')->with('succes', 'Data berhasil dihapus dan curas diperbarui.');
|
||||||
} catch (\Exception $e) {
|
} catch (\Exception $e) {
|
||||||
|
|
||||||
|
DB::rollBack();
|
||||||
return redirect('/dashboard/detail-curas')->with('error', 'Terjadi kesalahan Ketika Menghapus Data : ' . $e->getMessage());
|
return redirect('/dashboard/detail-curas')->with('error', 'Terjadi kesalahan Ketika Menghapus Data : ' . $e->getMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
|
|
||||||
use App\Models\Klaster;
|
use App\Models\Klaster;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
|
use App\Services\KMeansService;
|
||||||
|
|
||||||
class KlasterController extends Controller
|
class KlasterController extends Controller
|
||||||
{
|
{
|
||||||
|
@ -34,12 +35,25 @@ public function store(Request $request)
|
||||||
'nama_klaster' =>'required|max:255|unique:klasters,nama_klaster',
|
'nama_klaster' =>'required|max:255|unique:klasters,nama_klaster',
|
||||||
'warna' =>'required|max:255',
|
'warna' =>'required|max:255',
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
|
||||||
|
$serviceKMeans = new KMeansService();
|
||||||
|
$serviceKMeans->SSEElbowCuranmor();
|
||||||
|
$serviceKMeans->SSEElbowCuras();
|
||||||
|
|
||||||
|
$serviceKMeansCuras = new KMeansService();
|
||||||
|
$hasilKMeansCuras = $serviceKMeansCuras->hitungKMeansCuras();
|
||||||
|
file_put_contents(storage_path('app/public/hasil_kmeans_curas.json'), json_encode($hasilKMeansCuras));
|
||||||
|
|
||||||
|
$serviceKmeansCuranmor = new KMeansService();
|
||||||
|
$hasilKMeansCuranmor = $serviceKmeansCuranmor->hitungKMeansCuranmor();
|
||||||
|
file_put_contents(storage_path('app/public/hasil_kmeans_curanmor.json'), json_encode($hasilKMeansCuranmor));
|
||||||
|
|
||||||
Klaster::create($validateData);
|
Klaster::create($validateData);
|
||||||
return redirect('/dashboard/klaster')->with('succes', 'Berhasil Menambahkan Klaster Baru');
|
return redirect('/dashboard/klaster')->with('succes', 'Berhasil Menambahkan Klaster Baru');
|
||||||
}catch (\Exception $e){
|
}catch (\Exception $e){
|
||||||
|
|
||||||
return redirect('/dashboard/klaster')->with('error', 'Gagal Menambahkan Klaster Baru');
|
return redirect('/dashboard/klaster')->with('error', 'Gagal Menambahkan Klaster Baru ' .$e->getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -12,27 +12,24 @@ class KMeansService
|
||||||
public function hitungKMeansCuras()
|
public function hitungKMeansCuras()
|
||||||
{
|
{
|
||||||
$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;
|
||||||
|
|
||||||
$uniqueCount = $data->unique('jumlah_curas')->count();
|
// Ambil centroid awal yang unik
|
||||||
if ($uniqueCount < $k) {
|
$minValue = $data->min('jumlah_curas');
|
||||||
throw new \Exception("Jumlah nilai unik pada 'jumlah_curas' ($uniqueCount) kurang dari jumlah klaster ($k). Pastikan data memiliki variasi yang cukup.");
|
$maxValue = $data->max('jumlah_curas');
|
||||||
|
|
||||||
|
$generated = collect();
|
||||||
|
while ($generated->count() < $k) {
|
||||||
|
$randomFloat = round(mt_rand($minValue * 100, $maxValue * 100) / 100, 2);
|
||||||
|
if (!$generated->contains($randomFloat)) {
|
||||||
|
$generated->push($randomFloat);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ambil centroid awal yang unik
|
$centroids = $generated->map(function ($value) {
|
||||||
$centroids = $data->unique('jumlah_curas') // Pastikan nilai unik
|
return ['jumlah_curas' => $value];
|
||||||
->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();
|
$centroidAwal = $centroids->toArray();
|
||||||
|
|
||||||
$iterasi = [];
|
$iterasi = [];
|
||||||
|
@ -52,7 +49,7 @@ public function hitungKMeansCuras()
|
||||||
|
|
||||||
$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];
|
||||||
$clusterNumber = (int) str_replace("C", "", $minIndex);
|
$clusterNumber = (int) str_replace("C", "", $minIndex);
|
||||||
|
|
||||||
$clustered[$clusterNumber][] = $item;
|
$clustered[$clusterNumber][] = $item;
|
||||||
|
@ -60,15 +57,12 @@ public function hitungKMeansCuras()
|
||||||
$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');
|
||||||
|
@ -79,21 +73,17 @@ public function hitungKMeansCuras()
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Final mapping centroid ke klaster_id (aman/sedang/rawan)
|
// Final mapping centroid ke klaster_id
|
||||||
$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
|
// Update ke database
|
||||||
foreach ($data as $item) {
|
foreach ($data as $item) {
|
||||||
Curas::where('id', $item->id)->update([
|
Curas::where('id', $item->id)->update([
|
||||||
|
@ -101,19 +91,23 @@ public function hitungKMeansCuras()
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Format centroid awal
|
||||||
$centroidAwalFormatted = collect($centroidAwal)->values()->map(function ($item, $index) {
|
$centroidAwalFormatted = collect($centroidAwal)->values()->map(function ($item, $index) {
|
||||||
return ['C' . ($index + 1) => $item['jumlah_curas']];
|
return ['C' . ($index + 1) => $item['jumlah_curas']];
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Format centroid akhir
|
||||||
|
$centroidAkhirFormatted = $centroids->values()->map(function ($item, $index) {
|
||||||
|
return ['C' . ($index + 1) => $item['jumlah_curas']];
|
||||||
|
});
|
||||||
|
|
||||||
return [
|
return [
|
||||||
'centroid_awal' => $centroidAwalFormatted,
|
'centroid_awal' => $centroidAwalFormatted,
|
||||||
|
'centroid_akhir' => $centroidAkhirFormatted,
|
||||||
'iterasi' => $iterasi
|
'iterasi' => $iterasi
|
||||||
];
|
];
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public function hitungKMeansCuranmor()
|
public function hitungKMeansCuranmor()
|
||||||
{
|
{
|
||||||
$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();
|
||||||
|
@ -121,23 +115,20 @@ public function hitungKMeansCuranmor()
|
||||||
$k = Klaster::count('id');
|
$k = Klaster::count('id');
|
||||||
$maxIterasi = 100;
|
$maxIterasi = 100;
|
||||||
|
|
||||||
$uniqueCount = $data->unique('jumlah_curanmor')->count();
|
$minValue = $data->min('jumlah_curanmor');
|
||||||
if ($uniqueCount < $k) {
|
$maxValue = $data->max('jumlah_curanmor');
|
||||||
throw new \Exception("Jumlah nilai unik pada 'jumlah_curanmor' ($uniqueCount) kurang dari jumlah klaster ($k). Pastikan data memiliki variasi yang cukup.");
|
|
||||||
|
$generated = collect();
|
||||||
|
while ($generated->count() < $k) {
|
||||||
|
$randomFloat = round(mt_rand($minValue * 100, $maxValue * 100) / 100, 2);
|
||||||
|
if (!$generated->contains($randomFloat)) {
|
||||||
|
$generated->push($randomFloat);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ambil centroid awal yang unik
|
$centroids = $generated->map(function ($value) {
|
||||||
$centroids = $data->unique('jumlah_curanmor') // Pastikan nilai unik
|
return ['jumlah_curanmor' => $value];
|
||||||
->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();
|
$centroidAwal = $centroids->toArray();
|
||||||
|
|
||||||
$iterasi = [];
|
$iterasi = [];
|
||||||
|
@ -224,42 +215,43 @@ public function SSEElbowCuras()
|
||||||
$maxK = 10;
|
$maxK = 10;
|
||||||
$maxIterasi = 100;
|
$maxIterasi = 100;
|
||||||
$elbowData = [];
|
$elbowData = [];
|
||||||
|
|
||||||
for ($k = 1; $k <= $maxK; $k++) {
|
// Ambil nilai minimum dan maksimum dari jumlah_curas
|
||||||
// Inisialisasi centroid awal secara acak
|
$min = $data->min('jumlah_curas');
|
||||||
$centroids = $data->unique('jumlah_curas')->shuffle()->take($k)->values()->map(function ($item) {
|
$max = $data->max('jumlah_curas');
|
||||||
return ['jumlah_curas' => $item->jumlah_curas];
|
|
||||||
|
for ($k = 2; $k <= $maxK; $k++) {
|
||||||
|
// Inisialisasi centroid awal sebagai float acak dalam rentang min-max
|
||||||
|
$centroids = collect(range(1, $k))->map(function () use ($min, $max) {
|
||||||
|
return ['jumlah_curas' => mt_rand($min * 100, $max * 100) / 100];
|
||||||
});
|
});
|
||||||
|
|
||||||
// Simpan centroid awal sebagai array angka
|
|
||||||
$centroidAwal = $centroids->pluck('jumlah_curas')->toArray();
|
$centroidAwal = $centroids->pluck('jumlah_curas')->toArray();
|
||||||
|
|
||||||
$prevAssignment = [];
|
$prevAssignment = [];
|
||||||
|
|
||||||
for ($iter = 0; $iter < $maxIterasi; $iter++) {
|
for ($iter = 0; $iter < $maxIterasi; $iter++) {
|
||||||
$clustered = [];
|
$clustered = [];
|
||||||
$currentAssignment = [];
|
$currentAssignment = [];
|
||||||
|
|
||||||
foreach ($data as $item) {
|
foreach ($data as $item) {
|
||||||
$jarak = [];
|
$jarak = [];
|
||||||
|
|
||||||
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[$idx] = $dist;
|
$jarak[$idx] = $dist;
|
||||||
}
|
}
|
||||||
|
|
||||||
$minIndex = array_keys($jarak, min($jarak))[0];
|
$minIndex = array_keys($jarak, min($jarak))[0];
|
||||||
$clustered[$minIndex][] = $item;
|
$clustered[$minIndex][] = $item;
|
||||||
$currentAssignment[$item->id] = $minIndex;
|
$currentAssignment[$item->id] = $minIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($currentAssignment === $prevAssignment) {
|
if ($currentAssignment === $prevAssignment) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
$prevAssignment = $currentAssignment;
|
$prevAssignment = $currentAssignment;
|
||||||
|
|
||||||
// Update centroid
|
|
||||||
foreach ($clustered as $key => $group) {
|
foreach ($clustered as $key => $group) {
|
||||||
$avg = collect($group)->avg('jumlah_curas');
|
$avg = collect($group)->avg('jumlah_curas');
|
||||||
$centroids = $centroids->map(function ($centroid, $idx) use ($key, $avg) {
|
$centroids = $centroids->map(function ($centroid, $idx) use ($key, $avg) {
|
||||||
|
@ -269,8 +261,8 @@ public function SSEElbowCuras()
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Hitung SSE untuk k saat ini
|
// Hitung SSE
|
||||||
$sse = 0;
|
$sse = 0;
|
||||||
foreach ($clustered as $key => $group) {
|
foreach ($clustered as $key => $group) {
|
||||||
$centroidVal = $centroids[$key]['jumlah_curas'];
|
$centroidVal = $centroids[$key]['jumlah_curas'];
|
||||||
|
@ -278,20 +270,22 @@ public function SSEElbowCuras()
|
||||||
$sse += pow($item->jumlah_curas - $centroidVal, 2);
|
$sse += pow($item->jumlah_curas - $centroidVal, 2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$elbowData[] = [
|
$elbowData[] = [
|
||||||
'k' => $k,
|
'k' => $k,
|
||||||
'sse' => $sse,
|
'sse' => $sse,
|
||||||
'centroid_awal' => $centroidAwal
|
'centroid_awal' => $centroidAwal
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Simpan ke file
|
|
||||||
|
|
||||||
file_put_contents(
|
file_put_contents(
|
||||||
storage_path('app/public/sse_elbow_curas.json'),
|
storage_path('app/public/sse_elbow_curas.json'),
|
||||||
json_encode($elbowData, JSON_PRETTY_PRINT)
|
json_encode($elbowData, JSON_PRETTY_PRINT)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public function SSEElbowCuranmor()
|
public function SSEElbowCuranmor()
|
||||||
|
@ -301,7 +295,7 @@ public function SSEElbowCuranmor()
|
||||||
$maxIterasi = 100;
|
$maxIterasi = 100;
|
||||||
$elbowData = [];
|
$elbowData = [];
|
||||||
|
|
||||||
for ($k = 1; $k <= $maxK; $k++) {
|
for ($k = 2; $k <= $maxK; $k++) {
|
||||||
// Inisialisasi centroid awal secara acak
|
// Inisialisasi centroid awal secara acak
|
||||||
$centroids = $data->unique('jumlah_curanmor')->shuffle()->take($k)->values()->map(function ($item) {
|
$centroids = $data->unique('jumlah_curanmor')->shuffle()->take($k)->values()->map(function ($item) {
|
||||||
return ['jumlah_curanmor' => $item->jumlah_curanmor];
|
return ['jumlah_curanmor' => $item->jumlah_curanmor];
|
||||||
|
|
Loading…
Reference in New Issue