use crate::rand::genrand;
pub trait MDP<S, A> {
fn get_states(&self) -> Vec<S>;
fn get_actions(&self, state: &S) -> Vec<A>;
fn get_transitions(&self, state: &S, action: &A) -> Vec<(S, f64)>;
fn get_reward(&self, state: &S, action: &A, next_state: &S) -> f64;
fn is_terminal(&self, state: &S) -> bool;
fn get_discount_factor(&self) -> f64;
fn get_initial_state(&self) -> S;
fn get_goal_states(&self) -> Vec<S>;
fn execute(&self, state: &S, action: &A) -> (S, f64, bool) {
let mut transitions = self.get_transitions(state, &action);
assert!(!transitions.is_empty(), "No transitions for this action");
let r = (genrand(0, 1000) as f64) / 1000.0; let mut cumulative = 0.0;
let chosen_index = transitions
.iter()
.position(|(_, p)| {
cumulative += p;
return cumulative >= r;
})
.unwrap_or(0);
let (chosen_state, _) = transitions.swap_remove(chosen_index);
let reward = self.get_reward(state, &action, &chosen_state);
let done = self.is_terminal(&chosen_state);
return (chosen_state, reward, done);
}
}