penjadwalan-ga/app/Services/Scheduling/Data/SchedulingDataset.php

113 lines
3.2 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
namespace App\Services\Scheduling\Data;
/**
* Kontainer utama yang menampung semua data untuk satu run GA.
* Dibuat sekali oleh DatasetLoader di awal, lalu dipass ke GA.
*/
class SchedulingDataset
{
/**
* @param array<int, Guru> $guruList Map guru_id → Guru
* @param array<int, Kelas> $kelasList Map kelas_id → Kelas
* @param array<int> $ruanganRobotkuIds Daftar id ruangan Robotku
* (untuk domain pilihan ruang di kelas reguler)
* @param array<SchedulingSlot> $allSlots Semua slot valid (6 hari × 5 sesi = 30 slot)
*/
public function __construct(
public readonly array $guruList,
public readonly array $kelasList,
public readonly array $ruanganRobotkuIds,
public readonly array $allSlots,
) {
}
/**
* Ambil guru berdasarkan ID. Throw exception jika tidak ditemukan.
*/
public function getGuru(int $id): Guru
{
if (!isset($this->guruList[$id])) {
throw new \OutOfBoundsException("Guru dengan id={$id} tidak ada di dataset.");
}
return $this->guruList[$id];
}
/**
* Ambil kelas berdasarkan ID.
*/
public function getKelas(int $id): Kelas
{
if (!isset($this->kelasList[$id])) {
throw new \OutOfBoundsException("Kelas dengan id={$id} tidak ada di dataset.");
}
return $this->kelasList[$id];
}
/**
* Semua kelas reguler (kandidat untuk dioptimasi penuh oleh GA).
*
* @return array<Kelas>
*/
public function kelasReguler(): array
{
return array_values(array_filter(
$this->kelasList,
fn(Kelas $k) => !$k->isEkstrakurikuler
));
}
/**
* Semua kelas ekstrakurikuler (jadwal fix, hanya guru yang dioptimasi).
*
* @return array<Kelas>
*/
public function kelasEkstrakurikuler(): array
{
return array_values(array_filter(
$this->kelasList,
fn(Kelas $k) => $k->isEkstrakurikuler
));
}
/**
* Guru yang mampu mengajar level tertentu (berjenjang).
*
* @return array<Guru>
*/
public function guruMampuLevel(int $level): array
{
return array_values(array_filter(
$this->guruList,
fn(Guru $g) => $g->mampuMengajarLevel($level)
));
}
/**
* Total pertemuan per minggu yang harus dijadwalkan (= panjang kromosom N).
*/
public function totalPertemuan(): int
{
return array_sum(array_map(
fn(Kelas $k) => $k->frekuensiPerMinggu,
$this->kelasList
));
}
/**
* Statistik ringkas untuk keperluan diagnostik & pelaporan.
*/
public function summary(): array
{
return [
'total_guru' => count($this->guruList),
'total_kelas' => count($this->kelasList),
'kelas_reguler' => count($this->kelasReguler()),
'kelas_ekstrakurikuler' => count($this->kelasEkstrakurikuler()),
'total_ruangan_robotku' => count($this->ruanganRobotkuIds),
'total_slot' => count($this->allSlots),
'total_pertemuan_per_minggu' => $this->totalPertemuan(),
];
}
}