1use rand::prelude::*;
2use rand_distr;
3use rand_xoshiro;
4
5pub struct NodeNoiseGenerator<
6 L: rand_distr::Distribution<f64>,
7 I: rand_distr::Distribution<f64>,
8> {
9 pub load_distributions: Vec<L>, pub inflow_distributions: Vec<I>, pub num_branchings: usize,
12 pub num_load_entities: usize,
13 pub num_inflow_entities: usize,
14}
15
16pub struct NoiseGenerator<
17 L: rand_distr::Distribution<f64>,
18 I: rand_distr::Distribution<f64>,
19> {
20 pub node_generators: Vec<NodeNoiseGenerator<L, I>>,
21}
22
23impl<L: rand_distr::Distribution<f64>, I: rand_distr::Distribution<f64>>
24 NoiseGenerator<L, I>
25{
26 pub fn new() -> Self {
27 Self {
28 node_generators: vec![],
29 }
30 }
31
32 pub fn add_node_generator(
33 &mut self,
34 load_distributions: Vec<L>,
35 inflow_distributions: Vec<I>,
36 num_branchings: usize,
37 ) {
38 let num_load_entities = load_distributions.len();
39 let num_inflow_entities = inflow_distributions.len();
40 self.node_generators.push(NodeNoiseGenerator::<L, I> {
41 load_distributions,
42 inflow_distributions,
43 num_branchings,
44 num_load_entities,
45 num_inflow_entities,
46 });
47 }
48
49 pub fn get_node_generator(
50 &mut self,
51 id: usize,
52 ) -> Option<&NodeNoiseGenerator<L, I>> {
53 self.node_generators.get(id)
54 }
55
56 pub fn generate(&self, seed: u64) -> SAA {
81 let mut rng = rand_xoshiro::Xoshiro256Plus::seed_from_u64(seed);
82
83 let mut saa = SAA::new(&self);
84 for (stage_id, stage_generator) in
85 self.node_generators.iter().enumerate()
86 {
87 let load_noises: Vec<Vec<f64>> = stage_generator
89 .load_distributions
90 .iter()
91 .map(|entity_generator| {
92 entity_generator
93 .sample_iter(&mut rng)
94 .take(stage_generator.num_branchings)
95 .collect()
96 })
97 .collect();
98 let inflow_noises: Vec<Vec<f64>> = stage_generator
99 .inflow_distributions
100 .iter()
101 .map(|entity_generator| {
102 entity_generator
103 .sample_iter(&mut rng)
104 .take(stage_generator.num_branchings)
105 .collect()
106 })
107 .collect();
108
109 saa.set_noises_by_stage(
110 stage_id,
111 stage_generator.num_branchings,
112 stage_generator.num_load_entities,
113 stage_generator.num_inflow_entities,
114 load_noises,
115 inflow_noises,
116 );
117 }
118
119 saa
120 }
121}
122
123#[derive(Debug, Clone)]
124pub struct SampledBranchingNoises {
125 pub load_noises: Vec<f64>,
126 pub inflow_noises: Vec<f64>,
127 pub num_load_entities: usize,
128 pub num_inflow_entities: usize,
129}
130
131impl SampledBranchingNoises {
132 pub fn new(num_load_entities: usize, num_inflow_entities: usize) -> Self {
133 Self {
134 load_noises: Vec::<f64>::with_capacity(num_load_entities),
135 inflow_noises: Vec::<f64>::with_capacity(num_inflow_entities),
136 num_load_entities,
137 num_inflow_entities,
138 }
139 }
140
141 pub fn get_load_noises(&self) -> &[f64] {
142 return self.load_noises.as_slice();
143 }
144
145 pub fn get_inflow_noises(&self) -> &[f64] {
146 return self.inflow_noises.as_slice();
147 }
148
149 pub fn set_load_noises(&mut self, noises: &[f64]) {
150 self.load_noises.extend_from_slice(noises);
151 }
152
153 pub fn set_inflow_noises(&mut self, noises: &[f64]) {
154 self.inflow_noises.extend_from_slice(noises);
155 }
156}
157
158#[derive(Debug, Clone)]
159pub struct SampledNodeBranchings {
160 pub num_branchings: usize,
161 pub branching_noises: Vec<SampledBranchingNoises>,
162}
163
164impl SampledNodeBranchings {
165 pub fn new<
166 L: rand_distr::Distribution<f64>,
167 I: rand_distr::Distribution<f64>,
168 >(
169 stage_generator: &NodeNoiseGenerator<L, I>,
170 ) -> Self {
171 let num_load_entities = stage_generator.num_load_entities;
172 let num_inflow_entities = stage_generator.num_inflow_entities;
173 Self {
174 num_branchings: stage_generator.num_branchings,
175 branching_noises: vec![
176 SampledBranchingNoises::new(
177 num_load_entities,
178 num_inflow_entities
179 );
180 stage_generator.num_branchings
181 ],
182 }
183 }
184
185 pub fn get_noises_by_branching(
186 &self,
187 branching_id: usize,
188 ) -> Option<&SampledBranchingNoises> {
189 return self.branching_noises.get(branching_id);
190 }
191
192 pub fn set_noises_by_branching(
193 &mut self,
194 branching_id: usize,
195 load_noises: &[f64],
196 inflow_noises: &[f64],
197 ) {
198 self.branching_noises
199 .get_mut(branching_id)
200 .unwrap()
201 .set_load_noises(load_noises);
202 self.branching_noises
203 .get_mut(branching_id)
204 .unwrap()
205 .set_inflow_noises(inflow_noises);
206 }
207}
208
209#[derive(Debug)]
210pub struct SAA {
211 pub branching_samples: Vec<SampledNodeBranchings>,
212 pub index_samplers: Vec<rand_distr::Uniform<usize>>,
213}
214
215impl SAA {
216 pub fn new<
217 L: rand_distr::Distribution<f64>,
218 I: rand_distr::Distribution<f64>,
219 >(
220 scenario_generator: &NoiseGenerator<L, I>,
221 ) -> Self {
222 let branching_samples: Vec<SampledNodeBranchings> = scenario_generator
223 .node_generators
224 .iter()
225 .map(|g| SampledNodeBranchings::new(g))
226 .collect();
227 let index_samplers = scenario_generator
228 .node_generators
229 .iter()
230 .map(|g| {
231 rand_distr::Uniform::<usize>::try_from(0..g.num_branchings)
232 .unwrap()
233 })
234 .collect();
235 Self {
236 branching_samples,
237 index_samplers,
238 }
239 }
240
241 pub fn get_branching_count_at_stage(
242 &self,
243 stage_id: usize,
244 ) -> Option<usize> {
245 return Some(self.branching_samples.get(stage_id)?.num_branchings);
246 }
247
248 pub fn get_noises_by_stage_and_branching(
249 &self,
250 stage_id: usize,
251 branching_id: usize,
252 ) -> Option<&SampledBranchingNoises> {
253 return self
254 .branching_samples
255 .get(stage_id)?
256 .get_noises_by_branching(branching_id);
257 }
258
259 pub fn sample_scenario(
260 &self,
261 rng: &mut rand_xoshiro::Xoshiro256Plus,
262 ) -> Vec<&SampledBranchingNoises> {
263 let branching_indices: Vec<usize> =
264 self.index_samplers.iter().map(|d| d.sample(rng)).collect();
265
266 branching_indices
267 .iter()
268 .enumerate()
269 .map(|(id, branching_id)| {
270 self.get_noises_by_stage_and_branching(id, *branching_id)
271 .unwrap()
272 })
273 .collect()
274 }
275
276 pub fn set_noises_by_stage(
277 &mut self,
278 stage_id: usize,
279 num_branchings: usize,
280 num_load_entities: usize,
281 num_inflow_entities: usize,
282 load_noises: Vec<Vec<f64>>,
283 inflow_noises: Vec<Vec<f64>>,
284 ) {
285 for branching_id in 0..num_branchings {
286 let mut branching_load_noises =
287 Vec::<f64>::with_capacity(num_load_entities);
288 for entitiy_id in 0..num_load_entities {
289 branching_load_noises.push(
290 *load_noises
291 .get(entitiy_id)
292 .unwrap()
293 .get(branching_id)
294 .unwrap(),
295 );
296 }
297 let mut branching_inflow_noises =
298 Vec::<f64>::with_capacity(num_inflow_entities);
299 for entitiy_id in 0..num_inflow_entities {
300 branching_inflow_noises.push(
301 *inflow_noises
302 .get(entitiy_id)
303 .unwrap()
304 .get(branching_id)
305 .unwrap(),
306 );
307 }
308 self.branching_samples
309 .get_mut(stage_id)
310 .unwrap()
311 .set_noises_by_branching(
312 branching_id,
313 branching_load_noises.as_slice(),
314 branching_inflow_noises.as_slice(),
315 );
316 }
317 }
318}
319
320#[cfg(test)]
321mod tests {
322
323 use super::*;
324
325 #[test]
326 fn test_generate_saa() {
327 let mu = 3.6;
328 let sigma = 0.6928;
329 let num_entities = 2;
330 let mut scenario_generator = NoiseGenerator::new();
331 let num_branchings = 10;
332 scenario_generator.add_node_generator(
333 vec![rand_distr::Normal::new(10.0, 0.0).unwrap(); num_entities],
334 vec![rand_distr::LogNormal::new(mu, sigma).unwrap(); num_entities],
335 num_branchings,
336 );
337 let saa = scenario_generator.generate(0);
338 assert!(saa.get_noises_by_stage_and_branching(0, 0).is_some())
339 }
340}