51 lines
2.1 KiB
Python
51 lines
2.1 KiB
Python
from __future__ import annotations
|
|
from typing import TYPE_CHECKING, Optional
|
|
|
|
from pulp import lpSum
|
|
|
|
from models import Constraint, Problem, Attribute, Target, Item, Bundle
|
|
|
|
if TYPE_CHECKING:
|
|
from models.solver_run import SolverRun
|
|
|
|
class IrtTargetConstraint(Constraint):
|
|
reference_attribute: Optional[Attribute]
|
|
minimum: Optional[float]
|
|
maximum: Optional[float]
|
|
target: Target
|
|
target_type: str
|
|
|
|
def build(self, problem_handler: Problem, solver_run: SolverRun):
|
|
problem_handler.problem += lpSum([
|
|
self.bundle_irt_function(bundle, solver_run.irt_model, self.target.theta)
|
|
* problem_handler.solver_bundles_var[bundle.id]
|
|
for bundle in problem_handler.bundles
|
|
] + [
|
|
self.item_irt_function(item, solver_run.irt_model, self.target.theta) *
|
|
problem_handler.solver_items_var[item.id]
|
|
for item in problem_handler.items
|
|
]) >= self.target.minimum(
|
|
), f'Min {self.target_type} theta({self.target.theta}) at target {self.target.value}'
|
|
|
|
problem_handler.problem += lpSum([
|
|
self.bundle_irt_function(bundle, solver_run.irt_model, self.target.theta)
|
|
* problem_handler.solver_bundles_var[bundle.id]
|
|
for bundle in problem_handler.bundles
|
|
] + [
|
|
self.item_irt_function(item, solver_run.irt_model, self.target.theta) *
|
|
problem_handler.solver_items_var[item.id]
|
|
for item in problem_handler.items
|
|
]) <= self.target.maximum(
|
|
), f'Max {self.target_type} theta({self.target.theta}) at target {self.target.value}'
|
|
|
|
def item_irt_function(self, item: Item, irt_model: str, theta: float) -> float:
|
|
if self.target_type == 'tcc':
|
|
return item.irf(irt_model, theta)
|
|
elif self.target_type == 'tif':
|
|
return item.iif(irt_model, theta)
|
|
|
|
def bundle_irt_function(self, bundle: Bundle, irt_model: str, theta: float) -> float:
|
|
if self.target_type == 'tcc':
|
|
return bundle.trf(irt_model, theta)
|
|
elif self.target_type == 'tif':
|
|
return bundle.tif(irt_model, theta) |