use crate::solution::{apply_bounds, finalize_scalar_solution, Solution};
pub struct RealSolutionBuilder {
variables: Vec<f64>,
quality: Option<f64>,
lower_bounds: Option<Vec<f64>>,
upper_bounds: Option<Vec<f64>>,
}
impl RealSolutionBuilder {
pub fn new(size: usize) -> Self {
Self {
variables: vec![0.0; size],
quality: None,
lower_bounds: None,
upper_bounds: None,
}
}
pub fn from_variables(variables: Vec<f64>) -> Self {
Self {
variables,
quality: None,
lower_bounds: None,
upper_bounds: None,
}
}
pub fn with_variables(mut self, variables: Vec<f64>) -> Self {
self.variables = variables;
self
}
pub fn with_quality(mut self, quality: f64) -> Self {
self.quality = Some(quality);
self
}
pub fn with_lower_bounds(mut self, bounds: Vec<f64>) -> Self {
self.lower_bounds = Some(bounds);
self
}
pub fn with_upper_bounds(mut self, bounds: Vec<f64>) -> Self {
self.upper_bounds = Some(bounds);
self
}
pub fn with_bounds(mut self, lower: f64, upper: f64) -> Self {
let size = self.variables.len();
self.lower_bounds = Some(vec![lower; size]);
self.upper_bounds = Some(vec![upper; size]);
self
}
pub fn set_variable(mut self, index: usize, value: f64) -> Self {
if index < self.variables.len() {
self.variables[index] = value;
}
self
}
pub fn fill(mut self, value: f64) -> Self {
self.variables.fill(value);
self
}
pub fn build(self) -> Solution<f64> {
let lower_bounds = self.lower_bounds.clone();
let upper_bounds = self.upper_bounds.clone();
let variables = apply_bounds(self.variables, &self.lower_bounds, &self.upper_bounds);
let mut solution = finalize_scalar_solution(variables, self.quality);
if let (Some(lower_bounds), Some(upper_bounds)) = (lower_bounds, upper_bounds) {
solution.set_bounds(lower_bounds, upper_bounds);
}
solution
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_real_solution_builder_with_bounds() {
let solution = RealSolutionBuilder::new(3)
.fill(5.0)
.with_bounds(0.0, 1.0)
.build();
assert_eq!(solution.variables(), &[1.0, 1.0, 1.0]);
assert_eq!(solution.bounds_at(0), Some((0.0, 1.0)));
}
#[test]
fn test_real_solution_builder_individual_bounds() {
let solution = RealSolutionBuilder::from_variables(vec![5.0, -5.0, 10.0])
.with_lower_bounds(vec![0.0, 0.0, 0.0])
.with_upper_bounds(vec![1.0, 1.0, 1.0])
.build();
assert_eq!(solution.variables(), &[1.0, 0.0, 1.0]);
}
}