[docs]defget_makespan_with_penalties_objective(deadline_penalty_factor:float=1_000_000,due_date_penalty_factor:float=100,)->ObjectiveFunction:"""Builds an objective function that returns the makespan plus penalties. This factory returns a callable that evaluates a Schedule as the sum of its makespan and penalties for violating operation-level deadlines and due dates. Penalties are applied per scheduled operation that finishes after its corresponding attribute value: - Deadline violation: adds ``deadline_penalty_factor`` once per violating operation (hard constraint surrogate). - Due date violation: adds ``due_date_penalty_factor`` once per violating operation (soft constraint surrogate). Args: deadline_penalty_factor: Cost added for each operation that finishes after its deadline. Defaults to 1_000_000. due_date_penalty_factor: Cost added for each operation that finishes after its due date. Defaults to 100. Returns: A function ``f(schedule) -> float`` that computes ``schedule.makespan() + penalty``. Notes: - Deadlines and due dates are taken from each operation. If an operation does not define the attribute (``None``), no penalty is applied for that attribute. - If the instance has neither deadlines nor due dates, the objective is simply the makespan. """defobjective(schedule:Schedule)->float:makespan=schedule.makespan()penalty_for_deadlines=compute_penalty_for_deadlines(schedule,deadline_penalty_factor)penalty_for_due_dates=compute_penalty_for_due_dates(schedule,due_date_penalty_factor)penalty=penalty_for_deadlines+penalty_for_due_datesreturnmakespan+penaltyreturnobjective
[docs]defcompute_penalty_for_deadlines(schedule:Schedule,penalty_per_violation:float)->float:"""Compute the total penalty for deadline violations in a schedule. Args: schedule: The schedule to evaluate. penalty_per_violation: The penalty to apply for each operation that finishes after its deadline. Returns: The total penalty for deadline violations. """ifnotschedule.instance.has_deadlinesorpenalty_per_violation==0:return0.0penalty=0.0formachine_scheduleinschedule.schedule:forscheduled_opinmachine_schedule:op=scheduled_op.operationifop.deadlineisnotNoneandscheduled_op.end_time>op.deadline:penalty+=penalty_per_violationreturnpenalty
[docs]defcompute_penalty_for_due_dates(schedule:Schedule,penalty_per_violation:float)->float:"""Compute the total penalty for due date violations in a schedule. Args: schedule: The schedule to evaluate. penalty_per_violation: The penalty to apply for each operation that finishes after its due date. Returns: The total penalty for due date violations. """ifnotschedule.instance.has_due_datesorpenalty_per_violation==0:return0.0penalty=0.0formachine_scheduleinschedule.schedule:forscheduled_opinmachine_schedule:op=scheduled_op.operationifop.due_dateisnotNoneandscheduled_op.end_time>op.due_date:penalty+=penalty_per_violationreturnpenalty