from __future__ import annotations from pydantic import BaseModel from typing import Dict, List, AnyStr from pulp import lpSum from models.targets.tif_target import TifTarget from models.targets.tcc_target import TccTarget from models.problem import Problem class ObjectiveFunction(BaseModel): # minimizing tif/tcc target value is only option currently # as we add more we can build this out to be more dynamic # likely with models representing each objective function type tif_targets: List[TifTarget] tcc_targets: List[TccTarget] target_variance_percentage: int = 10 objective: AnyStr = "minimize" weight: Dict = {'tif': 1, 'tcc': 1} def for_problem(self, problem_handler: Problem) -> None: problem_handler.problem += lpSum([ bundle.count * problem_handler.solver_bundles_var[bundle.id] for bundle in problem_handler.bundles ] + [ problem_handler.solver_items_var[item.id] for item in problem_handler.items ]) def increment_targets_drift(self, limit: float or bool, all: bool = False, amount: float = 0.1, targets: list[TifTarget|TccTarget] = []) -> bool: if all: for target in self.tif_targets: target.drift = round(target.drift + amount, 2) for target in self.tcc_targets: target.drift = round(target.drift + amount, 2) else: for target in targets: target.drift = round(target.drift + amount, 2) return amount def update_targets_drift(self, amount: float = 0.0): for target in self.tif_targets: target.drift = round(amount, 2) for target in self.tcc_targets: target.drift = round(amount, 2) def minimum_drift(self) -> float: minimum_drift = 0.0 for target in self.all_targets(): if target.drift < minimum_drift: minimum_drift = target.drift return minimum_drift def all_targets(self) -> list[TifTarget|TccTarget]: return self.tif_targets + self.tcc_targets