From 34c1c586e0ecf8ce084c876ae4c0379e33744a2d Mon Sep 17 00:00:00 2001 From: "Prayoga K. I." Date: Sun, 5 Jul 2026 18:29:13 +0700 Subject: [PATCH] update --- app/Services/ForwardChainingService.php | 339 ++++++++++++------------ 1 file changed, 163 insertions(+), 176 deletions(-) diff --git a/app/Services/ForwardChainingService.php b/app/Services/ForwardChainingService.php index d07e73a..339a4df 100644 --- a/app/Services/ForwardChainingService.php +++ b/app/Services/ForwardChainingService.php @@ -10,16 +10,16 @@ class ForwardChainingService * Data rules untuk forward chaining */ private $rules = [ - ['id' => 1, 'penyakit_id' => 1, 'kode' => 'R1', 'gejala_ids' => [11, 17, 5, 6]], - ['id' => 2, 'penyakit_id' => 2, 'kode' => 'R2', 'gejala_ids' => [12, 5, 6]], - ['id' => 3, 'penyakit_id' => 3, 'kode' => 'R3', 'gejala_ids' => [10, 5, 6]], - ['id' => 4, 'penyakit_id' => 4, 'kode' => 'R4', 'gejala_ids' => [11, 22, 5]], - ['id' => 5, 'penyakit_id' => 5, 'kode' => 'R5', 'gejala_ids' => [1, 9, 13, 21]], - ['id' => 6, 'penyakit_id' => 6, 'kode' => 'R6', 'gejala_ids' => [22, 5, 8]], - ['id' => 7, 'penyakit_id' => 7, 'kode' => 'R7', 'gejala_ids' => [14, 23, 19]], - ['id' => 8, 'penyakit_id' => 8, 'kode' => 'R8', 'gejala_ids' => [8, 23, 19]], - ['id' => 9, 'penyakit_id' => 9, 'kode' => 'R9', 'gejala_ids' => [1, 2, 24]], - ['id' => 10, 'penyakit_id' => 10, 'kode' => 'R10', 'gejala_ids' => [4, 18, 24]], + ['id' => 1, 'penyakit_id' => 1, 'kode' => 'R1', 'gejala_ids' => [12, 18, 6, 7]], + ['id' => 2, 'penyakit_id' => 2, 'kode' => 'R2', 'gejala_ids' => [13, 6, 7]], + ['id' => 3, 'penyakit_id' => 3, 'kode' => 'R3', 'gejala_ids' => [11, 6, 7]], + ['id' => 4, 'penyakit_id' => 4, 'kode' => 'R4', 'gejala_ids' => [12, 23, 6]], + ['id' => 5, 'penyakit_id' => 5, 'kode' => 'R5', 'gejala_ids' => [1, 10, 14, 22]], + ['id' => 6, 'penyakit_id' => 6, 'kode' => 'R6', 'gejala_ids' => [23, 6, 9]], + ['id' => 7, 'penyakit_id' => 7, 'kode' => 'R7', 'gejala_ids' => [15, 24, 20]], + ['id' => 8, 'penyakit_id' => 8, 'kode' => 'R8', 'gejala_ids' => [9, 24, 20]], + ['id' => 9, 'penyakit_id' => 9, 'kode' => 'R9', 'gejala_ids' => [1, 2, 25]], + ['id' => 10, 'penyakit_id' => 10, 'kode' => 'R10', 'gejala_ids' => [5, 19, 25]], ]; /** @@ -29,28 +29,29 @@ class ForwardChainingService private $gejalaKodeMap = [ 'G01' => 1, 'G02' => 2, - 'G04' => 3, - 'G05' => 4, - 'G06' => 5, - 'G07' => 6, - 'G08' => 7, - 'G09' => 8, - 'G10' => 9, - 'G11' => 10, - 'G12' => 11, - 'G13' => 12, - 'G14' => 13, - 'G15' => 14, - 'G16' => 15, - 'G17' => 16, - 'G18' => 17, - 'G19' => 18, - 'G20' => 19, - 'G21' => 20, - 'G22' => 21, - 'G23' => 22, - 'G24' => 23, - 'G25' => 24, + 'G03' => 3, + 'G04' => 4, + 'G05' => 5, + 'G06' => 6, + 'G07' => 7, + 'G08' => 8, + 'G09' => 9, + 'G10' => 10, + 'G11' => 11, + 'G12' => 12, + 'G13' => 13, + 'G14' => 14, + 'G15' => 15, + 'G16' => 16, + 'G17' => 17, + 'G18' => 18, + 'G19' => 19, + 'G20' => 20, + 'G21' => 21, + 'G22' => 22, + 'G23' => 23, + 'G24' => 24, + 'G25' => 25, ]; /** @@ -58,56 +59,56 @@ class ForwardChainingService */ private $penyakitGejala = [ // R1: P01 - G12 AND G18 AND G06 AND G07 - ['penyakit_id' => 1, 'gejala_id' => 11, 'cf_pakar' => 1.0], - ['penyakit_id' => 1, 'gejala_id' => 17, 'cf_pakar' => 0.8], - ['penyakit_id' => 1, 'gejala_id' => 5, 'cf_pakar' => 0.6], - ['penyakit_id' => 1, 'gejala_id' => 6, 'cf_pakar' => 0.8], + ['penyakit_id' => 1, 'gejala_id' => 12, 'cf_pakar' => 1.0], + ['penyakit_id' => 1, 'gejala_id' => 18, 'cf_pakar' => 0.8], + ['penyakit_id' => 1, 'gejala_id' => 6, 'cf_pakar' => 0.6], + ['penyakit_id' => 1, 'gejala_id' => 7, 'cf_pakar' => 0.8], // R2: P02 - G13 AND G06 AND G07 - ['penyakit_id' => 2, 'gejala_id' => 12, 'cf_pakar' => 1.0], - ['penyakit_id' => 2, 'gejala_id' => 5, 'cf_pakar' => 0.6], - ['penyakit_id' => 2, 'gejala_id' => 6, 'cf_pakar' => 0.8], + ['penyakit_id' => 2, 'gejala_id' => 13, 'cf_pakar' => 1.0], + ['penyakit_id' => 2, 'gejala_id' => 6, 'cf_pakar' => 0.6], + ['penyakit_id' => 2, 'gejala_id' => 7, 'cf_pakar' => 0.8], // R3: P03 - G11 AND G06 AND G07 - ['penyakit_id' => 3, 'gejala_id' => 10, 'cf_pakar' => 1.0], - ['penyakit_id' => 3, 'gejala_id' => 5, 'cf_pakar' => 0.6], - ['penyakit_id' => 3, 'gejala_id' => 6, 'cf_pakar' => 0.8], + ['penyakit_id' => 3, 'gejala_id' => 11, 'cf_pakar' => 1.0], + ['penyakit_id' => 3, 'gejala_id' => 6, 'cf_pakar' => 0.6], + ['penyakit_id' => 3, 'gejala_id' => 7, 'cf_pakar' => 0.8], // R4: P04 - G12 AND G23 AND G06 - ['penyakit_id' => 4, 'gejala_id' => 11, 'cf_pakar' => 1.0], - ['penyakit_id' => 4, 'gejala_id' => 22, 'cf_pakar' => 0.8], - ['penyakit_id' => 4, 'gejala_id' => 5, 'cf_pakar' => 0.6], + ['penyakit_id' => 4, 'gejala_id' => 12, 'cf_pakar' => 1.0], + ['penyakit_id' => 4, 'gejala_id' => 23, 'cf_pakar' => 0.8], + ['penyakit_id' => 4, 'gejala_id' => 6, 'cf_pakar' => 0.6], // R5: P05 - G01 AND G10 AND G14 AND G22 ['penyakit_id' => 5, 'gejala_id' => 1, 'cf_pakar' => 1.0], - ['penyakit_id' => 5, 'gejala_id' => 9, 'cf_pakar' => 0.8], - ['penyakit_id' => 5, 'gejala_id' => 13, 'cf_pakar' => 0.8], - ['penyakit_id' => 5, 'gejala_id' => 21, 'cf_pakar' => 0.8], + ['penyakit_id' => 5, 'gejala_id' => 10, 'cf_pakar' => 0.8], + ['penyakit_id' => 5, 'gejala_id' => 14, 'cf_pakar' => 0.8], + ['penyakit_id' => 5, 'gejala_id' => 22, 'cf_pakar' => 0.8], // R6: P06 - G23 AND G06 AND G09 - ['penyakit_id' => 6, 'gejala_id' => 22, 'cf_pakar' => 1.0], - ['penyakit_id' => 6, 'gejala_id' => 5, 'cf_pakar' => 0.6], - ['penyakit_id' => 6, 'gejala_id' => 8, 'cf_pakar' => 0.6], + ['penyakit_id' => 6, 'gejala_id' => 23, 'cf_pakar' => 1.0], + ['penyakit_id' => 6, 'gejala_id' => 6, 'cf_pakar' => 0.6], + ['penyakit_id' => 6, 'gejala_id' => 9, 'cf_pakar' => 0.6], // R7: P07 - G15 AND G24 AND G20 - ['penyakit_id' => 7, 'gejala_id' => 14, 'cf_pakar' => 1.0], - ['penyakit_id' => 7, 'gejala_id' => 23, 'cf_pakar' => 0.8], - ['penyakit_id' => 7, 'gejala_id' => 19, 'cf_pakar' => 0.6], + ['penyakit_id' => 7, 'gejala_id' => 15, 'cf_pakar' => 1.0], + ['penyakit_id' => 7, 'gejala_id' => 24, 'cf_pakar' => 0.8], + ['penyakit_id' => 7, 'gejala_id' => 20, 'cf_pakar' => 0.6], // R8: P08 - G09 AND G24 AND G20 - ['penyakit_id' => 8, 'gejala_id' => 8, 'cf_pakar' => 1.0], - ['penyakit_id' => 8, 'gejala_id' => 23, 'cf_pakar' => 0.8], - ['penyakit_id' => 8, 'gejala_id' => 19, 'cf_pakar' => 0.6], + ['penyakit_id' => 8, 'gejala_id' => 9, 'cf_pakar' => 1.0], + ['penyakit_id' => 8, 'gejala_id' => 24, 'cf_pakar' => 0.8], + ['penyakit_id' => 8, 'gejala_id' => 20, 'cf_pakar' => 0.6], // R9: P09 - G01 AND G02 AND G25 ['penyakit_id' => 9, 'gejala_id' => 1, 'cf_pakar' => 1.0], ['penyakit_id' => 9, 'gejala_id' => 2, 'cf_pakar' => 0.8], - ['penyakit_id' => 9, 'gejala_id' => 24, 'cf_pakar' => 0.8], + ['penyakit_id' => 9, 'gejala_id' => 25, 'cf_pakar' => 0.8], // R10: P10 - G05 AND G19 AND G25 - ['penyakit_id' => 10, 'gejala_id' => 4, 'cf_pakar' => 1.0], - ['penyakit_id' => 10, 'gejala_id' => 18, 'cf_pakar' => 0.8], - ['penyakit_id' => 10, 'gejala_id' => 24, 'cf_pakar' => 0.8], + ['penyakit_id' => 10, 'gejala_id' => 5, 'cf_pakar' => 1.0], + ['penyakit_id' => 10, 'gejala_id' => 19, 'cf_pakar' => 0.8], + ['penyakit_id' => 10, 'gejala_id' => 25, 'cf_pakar' => 0.8], ]; /** @@ -117,111 +118,111 @@ class ForwardChainingService private $decisionTree = [ 'root' => [ 'name' => 'Diagnosis Jamur Tiram', - 'primary_symptoms' => [1, 5, 8, 11, 12, 14], // Gejala utama untuk initial split + 'primary_symptoms' => [1, 6, 9, 12, 13, 15], // Gejala utama untuk initial split 'branches' => [ - // Branch 1: Gejala 11 (Tubuh Buah Pucat) - [ - 'symptom_id' => 11, - 'name' => 'Tubuh Buah Pucat', - 'children' => [ - [ - 'symptom_id' => 17, - 'name' => 'Ada Lendir', - 'penyakit_ids' => [1] // R1: Penyakit 1 - ], - [ - 'symptom_id' => 22, - 'name' => 'Bau Menyengat', - 'penyakit_ids' => [4] // R4: Penyakit 4 - ] - ] - ], - // Branch 2: Gejala 12 (Umbi Membusuk) + // Branch 1: Gejala 12 (G12 - Bintik noda hijau) [ 'symptom_id' => 12, - 'name' => 'Umbi Membusuk', - 'children' => [ - [ - 'symptom_id' => 5, - 'name' => 'Substrat Basah', - 'penyakit_ids' => [2] // R2: Penyakit 2 - ] - ] - ], - // Branch 3: Gejala 10 (Kepala Susu Coklat) - [ - 'symptom_id' => 10, - 'name' => 'Kepala Susu Coklat', - 'children' => [ - [ - 'symptom_id' => 5, - 'name' => 'Substrat Basah', - 'penyakit_ids' => [3] // R3: Penyakit 3 - ] - ] - ], - // Branch 4: Gejala 1 (Jamur Putih pada Kepala Susu) - [ - 'symptom_id' => 1, - 'name' => 'Jamur Putih pada Kepala Susu', - 'children' => [ - [ - 'symptom_id' => 9, - 'name' => 'Busuk Pangkal', - 'penyakit_ids' => [5] // R5: Penyakit 5 - ], - [ - 'symptom_id' => 2, - 'name' => 'Berbau Asam', - 'penyakit_ids' => [9] // R9: Penyakit 9 - ] - ] - ], - // Branch 5: Gejala 22 (Bau Menyengat) - [ - 'symptom_id' => 22, - 'name' => 'Bau Menyengat', - 'children' => [ - [ - 'symptom_id' => 8, - 'name' => 'Kepala Susu Berlendir', - 'penyakit_ids' => [6] // R6: Penyakit 6 - ] - ] - ], - // Branch 6: Gejala 14 (Kepala Susu Kerdil) - [ - 'symptom_id' => 14, - 'name' => 'Kepala Susu Kerdil', - 'children' => [ - [ - 'symptom_id' => 23, - 'name' => 'Warna Tidak Seragam', - 'penyakit_ids' => [7] // R7: Penyakit 7 - ] - ] - ], - // Branch 7: Gejala 8 dan 23 (Non-primary) - [ - 'symptom_id' => 8, - 'name' => 'Kepala Susu Berlendir', - 'children' => [ - [ - 'symptom_id' => 19, - 'name' => 'Miselium Tidak Berkembang', - 'penyakit_ids' => [8] // R8: Penyakit 8 - ] - ] - ], - // Branch 8: Gejala 4 (Pertumbuhan Terganggu) - [ - 'symptom_id' => 4, - 'name' => 'Pertumbuhan Terganggu', + 'name' => 'Bintik Noda Hijau', 'children' => [ [ 'symptom_id' => 18, - 'name' => 'Kontaminan Terlihat', - 'penyakit_ids' => [10] // R10: Penyakit 10 + 'name' => 'Noda Hijau di Daun', + 'penyakit_ids' => [1] // R1: P01 - Trichoderma + ], + [ + 'symptom_id' => 23, + 'name' => 'Warna Coklat pada Miselium', + 'penyakit_ids' => [4] // R4: P04 - Penicilium + ] + ] + ], + // Branch 2: Gejala 13 (G13 - Tepung orange) + [ + 'symptom_id' => 13, + 'name' => 'Tepung Orange pada Baglog', + 'children' => [ + [ + 'symptom_id' => 6, + 'name' => 'Pertumbuhan Lambat', + 'penyakit_ids' => [2] // R2: P02 - Neurospora + ] + ] + ], + // Branch 3: Gejala 11 (G11 - Noda hitam) + [ + 'symptom_id' => 11, + 'name' => 'Noda Hitam pada Baglog', + 'children' => [ + [ + 'symptom_id' => 6, + 'name' => 'Pertumbuhan Lambat', + 'penyakit_ids' => [3] // R3: P03 - Mucor + ] + ] + ], + // Branch 4: Gejala 1 (G01 - Membusuk) + [ + 'symptom_id' => 1, + 'name' => 'Jamur Tiram Membusuk', + 'children' => [ + [ + 'symptom_id' => 10, + 'name' => 'Bau Menyengat', + 'penyakit_ids' => [5] // R5: P05 - Pseudomonas + ], + [ + 'symptom_id' => 2, + 'name' => 'Jamur Tiram Keriput', + 'penyakit_ids' => [9] // R9: P09 - Lalat + ] + ] + ], + // Branch 5: Gejala 23 (G23 - Warna coklat miselium) + [ + 'symptom_id' => 23, + 'name' => 'Warna Coklat pada Miselium', + 'children' => [ + [ + 'symptom_id' => 9, + 'name' => 'Baglog Rusak', + 'penyakit_ids' => [6] // R6: P06 - Chaetomium + ] + ] + ], + // Branch 6: Gejala 15 (G15 - Warna biru) + [ + 'symptom_id' => 15, + 'name' => 'Warna Biru pada Ujung Jamur', + 'children' => [ + [ + 'symptom_id' => 24, + 'name' => 'Kerusakan Tubuh Buah', + 'penyakit_ids' => [7] // R7: P07 - Coprinus + ] + ] + ], + // Branch 7: Gejala 9 (G09 - Baglog rusak) + [ + 'symptom_id' => 9, + 'name' => 'Baglog Rusak', + 'children' => [ + [ + 'symptom_id' => 20, + 'name' => 'Jamur Rontok', + 'penyakit_ids' => [8] // R8: P08 - Tikus + ] + ] + ], + // Branch 8: Gejala 5 (G05 - Tumbuh kecil) + [ + 'symptom_id' => 5, + 'name' => 'Jamur Tumbuh Kecil', + 'children' => [ + [ + 'symptom_id' => 19, + 'name' => 'Perakaran Lembek', + 'penyakit_ids' => [10] // R10: P10 - Tungau ] ] ] @@ -293,9 +294,7 @@ private function extractPenyakitFromBranch(array $branch, array $selectedGejalaI /** * Mencari penyakit berdasarkan gejala menggunakan AND logic. - * Prioritas utama: exact match dengan rule (semua gejala rule harus terpenuhi). - * Fallback: penyakit yang memiliki setidaknya satu gejala yang dipilih - * (CF tetap menghitung keyakinan secara proporsional). + * Semua gejala dalam rule harus terpenuhi (exact match). * * @param array $selectedGejalaIds Array ID gejala yang dipilih user * @return array Array of Penyakit models @@ -304,7 +303,7 @@ public function findMatchingDiseases(array $selectedGejalaIds): array { $matchingPenyakitIds = []; - // Prioritas 1: Exact AND match dengan rule + // Exact AND match dengan rule (semua gejala rule harus terpenuhi) foreach ($this->rules as $rule) { $ruleGejalaIds = $rule['gejala_ids'] ?? []; @@ -321,18 +320,6 @@ public function findMatchingDiseases(array $selectedGejalaIds): array } } - // Fallback: penyakit dengan gejala terkait (partial match) - // CF akan menangani perhitungan keyakinan secara proporsional - if (empty($matchingPenyakitIds)) { - $penyakitIds = []; - foreach ($this->penyakitGejala as $pg) { - if (in_array($pg['gejala_id'], $selectedGejalaIds)) { - $penyakitIds[] = $pg['penyakit_id']; - } - } - $matchingPenyakitIds = $penyakitIds; - } - return Penyakit::whereIn('id', array_unique($matchingPenyakitIds))->get()->all(); } }