1#[derive(Debug, Clone)]
19pub struct Transition {
20 pub state: Vec<f32>,
21 pub action: Vec<f32>,
22 pub reward: f32,
23 pub next_state: Vec<f32>,
24 pub done: bool,
25}
26
27#[derive(Debug, Clone, Default)]
29pub struct ReplayBuffer {
30 data: Vec<Transition>,
31 capacity: usize,
32}
33
34impl ReplayBuffer {
35 pub fn with_capacity(capacity: usize) -> Self {
36 Self {
37 data: Vec::new(),
38 capacity,
39 }
40 }
41
42 pub fn len(&self) -> usize {
43 self.data.len()
44 }
45
46 pub fn is_empty(&self) -> bool {
47 self.data.is_empty()
48 }
49
50 pub fn push(&mut self, t: Transition) {
51 if self.data.len() >= self.capacity {
52 self.data.remove(0);
53 }
54 self.data.push(t);
55 }
56
57 pub fn extend<I: IntoIterator<Item = Transition>>(&mut self, iter: I) {
58 for t in iter {
59 self.push(t);
60 }
61 }
62
63 pub fn sample_indices(&self, n: usize, seed: &mut u64) -> Vec<usize> {
65 if self.data.is_empty() {
66 return Vec::new();
67 }
68 (0..n)
69 .map(|_| {
70 *seed = rand_like(*seed);
71 (*seed as usize) % self.data.len()
72 })
73 .collect()
74 }
75
76 pub fn get(&self, idx: usize) -> &Transition {
77 &self.data[idx]
78 }
79
80 pub fn iter(&self) -> impl Iterator<Item = &Transition> {
81 self.data.iter()
82 }
83}
84
85pub fn rand_like(seed: u64) -> u64 {
87 seed.wrapping_mul(6364136223846793005).wrapping_add(1)
88}