update forward chaining diambil dari database

This commit is contained in:
Prayoga K. I. 2026-07-05 18:32:30 +07:00
parent 34c1c586e0
commit b815e90de2
1 changed files with 22 additions and 153 deletions

View File

@ -3,124 +3,15 @@
namespace App\Services;
use App\Models\Penyakit;
use Illuminate\Support\Facades\DB;
class ForwardChainingService
{
/**
* Data rules untuk forward chaining
*/
private $rules = [
['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]],
];
/**
* Mapping gejala kode ke ID
* Digunakan untuk konversi dari kode gejala ke gejala_id di database
*/
private $gejalaKodeMap = [
'G01' => 1,
'G02' => 2,
'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,
];
/**
* Data relasi penyakit-gejala dengan CF pakar
*/
private $penyakitGejala = [
// R1: P01 - G12 AND G18 AND G06 AND G07
['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' => 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' => 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' => 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' => 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' => 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' => 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' => 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' => 25, 'cf_pakar' => 0.8],
// R10: P10 - G05 AND G19 AND G25
['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],
];
/**
* Decision Tree - Struktur hierarki untuk diagnosis
* Mengorganisasi gejala dan rules dalam bentuk pohon keputusan
*/
private $decisionTree = [
'root' => [
'name' => 'Diagnosis Jamur Tiram',
'primary_symptoms' => [1, 6, 9, 12, 13, 15], // Gejala utama untuk initial split
'primary_symptoms' => [1, 6, 9, 12, 13, 15],
'branches' => [
// Branch 1: Gejala 12 (G12 - Bintik noda hijau)
[
'symptom_id' => 12,
'name' => 'Bintik Noda Hijau',
@ -128,16 +19,15 @@ class ForwardChainingService
[
'symptom_id' => 18,
'name' => 'Noda Hijau di Daun',
'penyakit_ids' => [1] // R1: P01 - Trichoderma
'penyakit_ids' => [1]
],
[
'symptom_id' => 23,
'name' => 'Warna Coklat pada Miselium',
'penyakit_ids' => [4] // R4: P04 - Penicilium
'penyakit_ids' => [4]
]
]
],
// Branch 2: Gejala 13 (G13 - Tepung orange)
[
'symptom_id' => 13,
'name' => 'Tepung Orange pada Baglog',
@ -145,11 +35,10 @@ class ForwardChainingService
[
'symptom_id' => 6,
'name' => 'Pertumbuhan Lambat',
'penyakit_ids' => [2] // R2: P02 - Neurospora
'penyakit_ids' => [2]
]
]
],
// Branch 3: Gejala 11 (G11 - Noda hitam)
[
'symptom_id' => 11,
'name' => 'Noda Hitam pada Baglog',
@ -157,11 +46,10 @@ class ForwardChainingService
[
'symptom_id' => 6,
'name' => 'Pertumbuhan Lambat',
'penyakit_ids' => [3] // R3: P03 - Mucor
'penyakit_ids' => [3]
]
]
],
// Branch 4: Gejala 1 (G01 - Membusuk)
[
'symptom_id' => 1,
'name' => 'Jamur Tiram Membusuk',
@ -169,16 +57,15 @@ class ForwardChainingService
[
'symptom_id' => 10,
'name' => 'Bau Menyengat',
'penyakit_ids' => [5] // R5: P05 - Pseudomonas
'penyakit_ids' => [5]
],
[
'symptom_id' => 2,
'name' => 'Jamur Tiram Keriput',
'penyakit_ids' => [9] // R9: P09 - Lalat
'penyakit_ids' => [9]
]
]
],
// Branch 5: Gejala 23 (G23 - Warna coklat miselium)
[
'symptom_id' => 23,
'name' => 'Warna Coklat pada Miselium',
@ -186,11 +73,10 @@ class ForwardChainingService
[
'symptom_id' => 9,
'name' => 'Baglog Rusak',
'penyakit_ids' => [6] // R6: P06 - Chaetomium
'penyakit_ids' => [6]
]
]
],
// Branch 6: Gejala 15 (G15 - Warna biru)
[
'symptom_id' => 15,
'name' => 'Warna Biru pada Ujung Jamur',
@ -198,11 +84,10 @@ class ForwardChainingService
[
'symptom_id' => 24,
'name' => 'Kerusakan Tubuh Buah',
'penyakit_ids' => [7] // R7: P07 - Coprinus
'penyakit_ids' => [7]
]
]
],
// Branch 7: Gejala 9 (G09 - Baglog rusak)
[
'symptom_id' => 9,
'name' => 'Baglog Rusak',
@ -210,11 +95,10 @@ class ForwardChainingService
[
'symptom_id' => 20,
'name' => 'Jamur Rontok',
'penyakit_ids' => [8] // R8: P08 - Tikus
'penyakit_ids' => [8]
]
]
],
// Branch 8: Gejala 5 (G05 - Tumbuh kecil)
[
'symptom_id' => 5,
'name' => 'Jamur Tumbuh Kecil',
@ -222,7 +106,7 @@ class ForwardChainingService
[
'symptom_id' => 19,
'name' => 'Perakaran Lembek',
'penyakit_ids' => [10] // R10: P10 - Tungau
'penyakit_ids' => [10]
]
]
]
@ -230,26 +114,16 @@ class ForwardChainingService
]
];
/**
* Get decision tree structure
*/
public function getDecisionTree(): array
{
return $this->decisionTree;
}
/**
* Get primary symptoms untuk starting diagnosis
*/
public function getPrimarySymptoms(): array
{
return $this->decisionTree['root']['primary_symptoms'];
}
/**
* Traverse decision tree berdasarkan selected gejala
* Mengembalikan branch yang cocok dan possible penyakit
*/
public function traverseDecisionTree(array $selectedGejalaIds): array
{
$matching = [];
@ -268,9 +142,6 @@ public function traverseDecisionTree(array $selectedGejalaIds): array
return $matching;
}
/**
* Extract possible penyakit IDs dari branch
*/
private function extractPenyakitFromBranch(array $branch, array $selectedGejalaIds): array
{
$penyakitIds = [];
@ -292,21 +163,19 @@ private function extractPenyakitFromBranch(array $branch, array $selectedGejalaI
return array_unique($penyakitIds);
}
/**
* Mencari penyakit berdasarkan gejala menggunakan AND logic.
* Semua gejala dalam rule harus terpenuhi (exact match).
*
* @param array $selectedGejalaIds Array ID gejala yang dipilih user
* @return array Array of Penyakit models
*/
public function findMatchingDiseases(array $selectedGejalaIds): array
{
$rules = DB::table('penyakit_gejala')
->select('penyakit_id', 'gejala_id')
->get()
->groupBy('penyakit_id')
->map(function ($group) {
return $group->pluck('gejala_id')->toArray();
});
$matchingPenyakitIds = [];
// Exact AND match dengan rule (semua gejala rule harus terpenuhi)
foreach ($this->rules as $rule) {
$ruleGejalaIds = $rule['gejala_ids'] ?? [];
foreach ($rules as $penyakitId => $ruleGejalaIds) {
$match = true;
foreach ($ruleGejalaIds as $gejalaId) {
if (!in_array($gejalaId, $selectedGejalaIds)) {
@ -316,7 +185,7 @@ public function findMatchingDiseases(array $selectedGejalaIds): array
}
if ($match) {
$matchingPenyakitIds[] = $rule['penyakit_id'];
$matchingPenyakitIds[] = $penyakitId;
}
}