#![allow(
clippy::missing_docs_in_private_items,
clippy::expect_used,
clippy::cast_possible_truncation
)]
use simul::agent::{periodic_consumer, periodic_producer};
use simul::experiment::monte_carlo_search;
use simul::{AgentInitializer, DiscreteTime, Simulation, SimulationParameters};
fn periodic_agent_generator_fixed_producer(
producer_period: DiscreteTime,
consumer_max_period: DiscreteTime,
) -> impl Fn() -> Vec<AgentInitializer> {
move || {
let consumer_period = rand::random::<u32>() % (consumer_max_period + 1) as u32;
let producer_agent = periodic_producer(
"producer".to_string(),
producer_period,
"consumer".to_string(),
);
let consumer_agent = periodic_consumer("consumer".to_string(), u64::from(consumer_period));
vec![producer_agent, consumer_agent]
}
}
fn run_experiment() {
let halt_condition = |s: &Simulation| {
s.find_by_name("consumer")
.expect("consumer to exist")
.state
.consumed
.len()
> 10
};
let agent_generator = periodic_agent_generator_fixed_producer(2, 10);
let simulation_parameters_generator = move || SimulationParameters {
agent_initializers: agent_generator(),
halt_check: halt_condition,
enable_agent_asleep_cycles_metric: true,
..Default::default()
};
let objective_fn = |s: &Simulation| {
-(s.time() as f64)
- s.find_agent(|a| a.name == "consumer")
.expect("consumer to exist")
.agent
.cost()
};
let replications_limit = 1000;
let approx_optimal = monte_carlo_search(
simulation_parameters_generator,
replications_limit,
objective_fn,
);
println!(
"{:#?}",
approx_optimal
.expect("result to exist")
.calc_avg_wait_statistics()
);
}
fn main() {
run_experiment();
}