1pub mod constant;
2pub mod goal_count;
3
4use std::time::{Duration, Instant};
5
6use clap::ValueEnum;
7use pddllib::{state::State, task::Task};
8
9#[derive(ValueEnum, Clone, Debug, Copy)]
10pub enum HeuristicKind {
11 Constant,
12 GoalCount,
13}
14
15pub struct Heuristic {
16 kind: HeuristicKind,
17 best_estimate: usize,
18 estimates: usize,
19 time: Duration,
20}
21
22impl Heuristic {
23 pub fn new(kind: HeuristicKind) -> Self {
24 Self {
25 kind,
26 best_estimate: usize::MAX,
27 estimates: 0,
28 time: Duration::default(),
29 }
30 }
31
32 pub fn estimate(&mut self, task: &Task, state: &State) -> usize {
33 let t = Instant::now();
34 let estimate = match self.kind {
35 HeuristicKind::Constant => constant::estimate(task, state),
36 HeuristicKind::GoalCount => goal_count::estimate(task, state),
37 };
38 self.time += t.elapsed();
39 if estimate < self.best_estimate {
40 println!("New best heuristic estimate: {}", estimate);
41 self.best_estimate = estimate;
42 }
43 self.estimates += 1;
44 estimate
45 }
46}
47
48impl Drop for Heuristic {
49 fn drop(&mut self) {
50 println!(
51 "Heuristic estimates: {} ({:.2}s) ({:.2}/s)",
52 self.estimates,
53 self.time.as_secs_f64(),
54 self.estimates as f64 / self.time.as_secs_f64()
55 );
56 }
57}