= 0.81) return 'Sangat Yakin'; if ($cf >= 0.61) return 'Yakin'; if ($cf >= 0.41) return 'Cukup Yakin'; if ($cf >= 0.21) return 'Mungkin'; if ($cf >= 0.01) return 'Tidak Yakin'; return 'Tidak Terdeteksi'; } // ───────────────────────────────────────────────────────── // PROSES UTAMA: HITUNG CF // Menerima array ID gejala yang dipilih user, lalu // menghitung nilai CF gabungan untuk setiap penyakit. // ───────────────────────────────────────────────────────── public function hitung(array $gejalaIds, array $cfUserMap = []): array { if (empty($gejalaIds)) { return ['error' => 'Minimal 1 gejala harus dipilih.']; } foreach ($gejalaIds as $id) { if (!isset($cfUserMap[$id])) { $cfUserMap[$id] = 1.0; } } $ruleCocok = Rule::with(['penyakit', 'gejala']) ->whereIn('id_gejala', $gejalaIds) ->get(); if ($ruleCocok->isEmpty()) { return ['error' => 'Tidak ada rule yang cocok dengan gejala yang dipilih.']; } $hasilCF = []; $detailLog = []; $penyakitIds = $ruleCocok->pluck('id_penyakit')->unique(); foreach ($penyakitIds as $idPenyakit) { $rulesPerPenyakit = $ruleCocok->where('id_penyakit', $idPenyakit); $cfGabungan = 0.0; $log = []; $step = 1; foreach ($rulesPerPenyakit as $rule) { $cfPakar = (float) $rule->nilai_cf; $cfUser = (float) ($cfUserMap[$rule->id_gejala] ?? 1.0); $cfIndividu = $cfPakar * $cfUser; $cfSebelum = $cfGabungan; if ($cfGabungan == 0.0) { $cfGabungan = $cfIndividu; $rumus = number_format($cfIndividu, 4); } else { $cfGabungan = $this->kombinasiCF($cfGabungan, $cfIndividu); $rumus = number_format($cfSebelum, 4) . ' + ' . number_format($cfIndividu, 4) . ' × (1 - ' . number_format($cfSebelum, 4) . ')' . ' = ' . number_format($cfGabungan, 4); } $log[] = [ 'step' => $step++, 'rule' => $rule->kode_rule, 'kode_gejala' => $rule->gejala->kode ?? '-', 'nama_gejala' => $rule->gejala->nama ?? '-', 'cf_pakar' => $cfPakar, 'cf_user' => $cfUser, 'cf_individu' => round($cfIndividu, 4), 'cf_sebelum' => round($cfSebelum, 4), 'cf_sesudah' => round($cfGabungan, 4), 'rumus' => $rumus, ]; } $hasilCF[$idPenyakit] = round($cfGabungan, 6); $detailLog[$idPenyakit] = $log; } $terdeteksi = array_filter($hasilCF, fn($cf) => $cf >= $this->threshold); arsort($terdeteksi); return [ 'gejala_ids' => $gejalaIds, 'cf_user_map' => $cfUserMap, 'semua_cf' => $hasilCF, 'terdeteksi' => $terdeteksi, 'total_diperiksa' => count($hasilCF), 'total_terdeteksi' => count($terdeteksi), 'detail_log' => $detailLog, ]; } // ───────────────────────────────────────────────────────── // SIMPAN HASIL KE DATABASE // Menyimpan sesi konsultasi, gejala yang dipilih, dan // hasil CF ke tiga tabel sekaligus dalam satu transaksi. // ───────────────────────────────────────────────────────── public function simpan(int $userId, array $gejalaIds, array $cfUserMap, array $hasilInferensi): Konsultasi { return DB::transaction(function () use ($userId, $gejalaIds, $cfUserMap, $hasilInferensi) { $kode = 'KON-' . date('Ymd') . '-' . str_pad( Konsultasi::whereDate('created_at', today())->count() + 1, 4, '0', STR_PAD_LEFT ); $status = empty($hasilInferensi['terdeteksi']) ? 'tidak_terdeteksi' : 'selesai'; $konsultasi = Konsultasi::create([ 'kode_konsultasi' => $kode, 'user_id' => $userId, 'tanggal' => now(), 'status' => $status, ]); foreach ($gejalaIds as $idGejala) { KonsultasiGejala::create([ 'id_konsultasi' => $konsultasi->id, 'id_gejala' => $idGejala, 'cf_user' => $cfUserMap[$idGejala] ?? 1.0, ]); } $ranking = 1; foreach ($hasilInferensi['terdeteksi'] as $idPenyakit => $cfAkhir) { HasilDiagnosa::create([ 'id_konsultasi' => $konsultasi->id, 'id_penyakit' => $idPenyakit, 'nilai_cf_akhir' => $cfAkhir, 'persentase' => round($cfAkhir * 100, 2), 'ranking' => $ranking++, ]); } return $konsultasi; }); } }