swarm_engine_core/exploration/selection/stats.rs
1//! Selection Statistics - 探索ノード選択の統計管理
2//!
3//! ノード選択に必要な統計情報を管理する。
4//!
5//! # 設計
6//!
7//! 統計情報は `SwarmStats`(collector/stats.rs)が Single Source of Truth。
8//! このモジュールの `NodeStats` は後方互換のために残しているが、
9//! 実際には `SwarmStats::ActionStats` を使用する。
10//!
11//! - `NodeStats`: 個別ノードの成功/失敗統計(後方互換)
12
13// ============================================================================
14// Node Statistics - ノードの実行統計
15// ============================================================================
16
17/// ノードの実行統計
18///
19/// UCB1/Thompson で使用する成功/失敗カウント。
20#[derive(Debug, Clone, Default)]
21pub struct NodeStats {
22 /// 訪問回数
23 pub visits: u32,
24 /// 成功回数
25 pub successes: u32,
26 /// 失敗回数
27 pub failures: u32,
28 /// 発見した子ノード数の合計
29 pub discoveries: u32,
30}
31
32impl NodeStats {
33 pub fn new() -> Self {
34 Self::default()
35 }
36
37 /// 成功を記録
38 pub fn record_success(&mut self) {
39 self.visits += 1;
40 self.successes += 1;
41 }
42
43 /// 失敗を記録
44 pub fn record_failure(&mut self) {
45 self.visits += 1;
46 self.failures += 1;
47 }
48
49 /// 発見を記録
50 pub fn record_discovery(&mut self, count: u32) {
51 self.visits += 1;
52 self.successes += 1;
53 self.discoveries += count;
54 }
55
56 /// 成功率(訪問なしの場合は 0.5)
57 pub fn success_rate(&self) -> f64 {
58 if self.visits == 0 {
59 0.5 // 事前確率
60 } else {
61 self.successes as f64 / self.visits as f64
62 }
63 }
64}
65
66// ============================================================================
67// Tests
68// ============================================================================
69
70#[cfg(test)]
71mod tests {
72 use super::*;
73
74 #[test]
75 fn test_node_stats_success_rate() {
76 let mut stats = NodeStats::new();
77 assert_eq!(stats.success_rate(), 0.5); // 事前確率
78
79 stats.record_success();
80 stats.record_success();
81 stats.record_failure();
82 assert!((stats.success_rate() - 0.666).abs() < 0.01);
83 }
84}