use std::time::Instant;
use heuropt::core::async_problem::AsyncProblem;
use heuropt::prelude::*;
struct RemoteService;
impl AsyncProblem for RemoteService {
type Decision = Vec<f64>;
fn objectives(&self) -> ObjectiveSpace {
ObjectiveSpace::new(vec![Objective::minimize("loss")])
}
async fn evaluate_async(&self, x: &Vec<f64>) -> Evaluation {
tokio::time::sleep(std::time::Duration::from_millis(20)).await;
let loss: f64 = x.iter().map(|v| v * v).sum();
Evaluation::new(vec![loss])
}
}
#[tokio::main]
async fn main() {
let bounds = vec![(-1.0_f64, 1.0_f64); 4];
let problem = RemoteService;
println!("RandomSearch with 200 evaluations (20 ms each)");
println!();
for &concurrency in &[1_usize, 4, 16] {
let mut opt = RandomSearch::new(
RandomSearchConfig {
iterations: 100,
batch_size: 2,
seed: 42,
},
RealBounds::new(bounds.clone()),
);
let started = Instant::now();
let result = opt.run_async(&problem, concurrency).await;
let elapsed = started.elapsed();
println!(
"concurrency = {:>2} elapsed = {:>5} ms best loss = {:>8.5} evaluations = {}",
concurrency,
elapsed.as_millis(),
result.best.unwrap().evaluation.objectives[0],
result.evaluations,
);
}
println!();
println!("DifferentialEvolution at concurrency=8");
let started = Instant::now();
let mut de = DifferentialEvolution::new(
DifferentialEvolutionConfig {
population_size: 8,
generations: 10,
differential_weight: 0.5,
crossover_probability: 0.9,
seed: 42,
},
RealBounds::new(bounds.clone()),
);
let result = de.run_async(&problem, 8).await;
let elapsed = started.elapsed();
println!(
"elapsed = {:>5} ms best loss = {:>8.5} evaluations = {}",
elapsed.as_millis(),
result.best.unwrap().evaluation.objectives[0],
result.evaluations,
);
}