1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73
use crate::{gp::Gp, Obj, ObjDirection}; use cl_traits::Storage; use core::{ iter::Sum, ops::{Add, Div}, slice::Iter, }; use mop_common::TraitCfg; use num_traits::One; #[derive(Debug)] pub struct MinWeightedSum<OI, WI> { objs: OI, weights: WI, } impl<OI, WI> MinWeightedSum<OI, WI> { pub fn new<CS, D, OR, S>(objs: OI, weights: WI) -> Self { Self { objs, weights } } } impl<'a, O, WI> MinWeightedSum<Iter<'a, O>, WI> { pub fn from_gp<D, HCRS, HCS, ORS, OS, SCRS, SCS, SS>( mp: &'a Gp<D, HCRS, HCS, ORS, OS, SCRS, SCS, SS>, weights: WI, ) -> Self where OS: AsRef<[O]> + Storage<Item = O>, { Self { objs: mp.defs().objs().as_ref().iter(), weights } } } impl<O, OR, OI, S, WI> Obj<OR, S> for MinWeightedSum<OI, WI> where O: Obj<OR, S>, OR: Add<Output = OR> + Div<Output = OR> + One + Sum, OI: Clone + Iterator<Item = O> + TraitCfg, WI: Clone + Iterator<Item = OR> + TraitCfg, { fn obj_direction(&self) -> ObjDirection { ObjDirection::Min } fn result(&self, s: &S) -> OR { self .objs .clone() .zip(self.weights.clone()) .map(|(o, w)| { let result = o.result(s); let transformed = match o.obj_direction() { ObjDirection::Max => OR::one() / (OR::one() + result), ObjDirection::Min => result, }; transformed * w }) .sum() } } impl<'a, O, OR, OI, S, WI> From<&'a MinWeightedSum<OI, WI>> for &'a dyn Obj<OR, S> where O: Obj<OR, S>, OR: Add<Output = OR> + Div<Output = OR> + One + Sum, OI: Clone + Iterator<Item = O> + TraitCfg, WI: Clone + Iterator<Item = OR> + TraitCfg, { fn from(f: &'a MinWeightedSum<OI, WI>) -> Self { f } }