diff --git a/app/models/bundle.py b/app/models/bundle.py index 3811284..12bd2d8 100644 --- a/app/models/bundle.py +++ b/app/models/bundle.py @@ -15,14 +15,14 @@ class Bundle(BaseModel): type: str def tif(self, irt_model: IRTModel, theta: float) -> float: - return 0.9 - # return TestInformationFunction(irt_model).calculate(self.items, - # theta=theta) + val = TestInformationFunction(irt_model).calculate(self.items, theta=theta) + + return round(val, 2) def trf(self, irt_model: IRTModel, theta: float) -> float: - return 0.9 - # return TestResponseFunction(irt_model).calculate(self.items, - # theta=theta) + val = TestResponseFunction(irt_model).calculate(self.items, theta=theta) + + return round(val, 2) def tif_trf_sum(self, solver_run): return self.__trf_sum(solver_run) + self.__tif_sum(solver_run) diff --git a/app/models/item.py b/app/models/item.py index 59b6f5c..ef21c9e 100644 --- a/app/models/item.py +++ b/app/models/item.py @@ -14,14 +14,14 @@ class Item(BaseModel): b_param: float = 0.00 def iif(self, solver_run, theta): - return 0.9 - # return ItemInformationFunction(solver_run.irt_model).calculate( - # b_param=self.b_param, theta=theta) + val = ItemInformationFunction(solver_run.irt_model).calculate(b_param=self.b_param, theta=theta) + + return round(val, 2) def irf(self, solver_run, theta): - return 0.9 - # return ItemResponseFunction(solver_run.irt_model).calculate( - # b_param=self.b_param, theta=theta) + val = ItemResponseFunction(solver_run.irt_model).calculate(b_param=self.b_param, theta=theta) + + return round(val, 2) def get_attribute(self, ref_attribute): for attribute in self.attributes: diff --git a/app/models/target.py b/app/models/target.py index 43bfecb..501db7f 100644 --- a/app/models/target.py +++ b/app/models/target.py @@ -9,8 +9,14 @@ class Target(BaseModel): @classmethod def max_drift(cls): - return 10 # 10% elasticity + return 120 # let it drift... @classmethod def max_drift_increment(cls): - return 1 # 1% + return 10 # 10% + + def minimum(self, drift_percent = 0.0) -> float: + return round(self.value - (self.value * drift_percent), 2) + + def maximum(self, drift_percent = 0.0) -> float: + return round(self.value + (self.value * drift_percent), 2) diff --git a/app/services/loft_service.py b/app/services/loft_service.py index 343b464..64bb09e 100644 --- a/app/services/loft_service.py +++ b/app/services/loft_service.py @@ -86,13 +86,13 @@ class LoftService(Base): problem = LpProblem('ata-form-generate', LpMinimize) # objective function - problem += lpSum( - [item.iif_irf_sum(self.solver_run) * items[item.id] for item in self.solver_run.unbundled_items()] - + - [bundle.tif_trf_sum(self.solver_run) * bundles[bundle.id] for bundle in self.solver_run.bundles] - ) + # problem += lpSum( + # [item.iif_irf_sum(self.solver_run) * items[item.id] for item in self.solver_run.unbundled_items()] + # + + # [bundle.tif_trf_sum(self.solver_run) * bundles[bundle.id] for bundle in self.solver_run.bundles] + # ) # problem += lpSum([items[item.id] for item in self.solver_run.unbundled_items()] + [bundles[bundle.id] for bundle in self.solver_run.bundles]) - # problem += lpSum([items[item.id] for item in self.solver_run.items]) + problem += lpSum([items[item.id] for item in self.solver_run.items]) # Form Constraints problem += lpSum( @@ -111,93 +111,87 @@ class LoftService(Base): # ) == self.solver_run.total_form_items, f'Total bundle form items for form {form_number}' # Dynamic constraints.. currently we only support Metadata and Bundles(Cases/Passages) - problem = solver_helper.build_constraints(self.solver_run, problem, items, bundles) + # problem = solver_helper.build_constraints(self.solver_run, problem, items, bundles) logging.info('Creating TIF and TCC Elastic constraints') # Behold our very own Elastic constraints! for tif_target in self.solver_run.objective_function.tif_targets: - problem += lpSum( - [ - bundle.tif(self.solver_run.irt_model, tif_target.theta) * bundles[bundle.id] - for bundle in self.solver_run.bundles - ] + - [ - item.iif(self.solver_run, tif_target.theta) * items[item.id] - for item in self.solver_run.unbundled_items() - ] - ) >= tif_target.value - (tif_target.value * drift_percent) - problem += lpSum( - [ - bundle.tif(self.solver_run.irt_model, tif_target.theta) * bundles[bundle.id] - for bundle in self.solver_run.bundles - ] + - [ - item.iif(self.solver_run, tif_target.theta) * items[item.id] - for item in self.solver_run.unbundled_items() - ] - ) <= tif_target.value + (tif_target.value * drift_percent) - # problem += lpSum( # [ + # bundle.tif(self.solver_run.irt_model, tif_target.theta) * bundles[bundle.id] + # for bundle in self.solver_run.bundles + # ] + + # [ # item.iif(self.solver_run, tif_target.theta) * items[item.id] - # for item in self.solver_run.items + # for item in self.solver_run.unbundled_items() # ] # ) >= tif_target.value - (tif_target.value * drift_percent) # problem += lpSum( # [ + # bundle.tif(self.solver_run.irt_model, tif_target.theta) * bundles[bundle.id] + # for bundle in self.solver_run.bundles + # ] + + # [ # item.iif(self.solver_run, tif_target.theta) * items[item.id] - # for item in self.solver_run.items + # for item in self.solver_run.unbundled_items() # ] # ) <= tif_target.value + (tif_target.value * drift_percent) - for tcc_target in self.solver_run.objective_function.tcc_targets: problem += lpSum( [ - bundle.trf(self.solver_run.irt_model, tcc_target.theta) * bundles[bundle.id] - for bundle in self.solver_run.bundles - ] + - [ - item.irf(self.solver_run, tcc_target.theta) * items[item.id] - for item in self.solver_run.unbundled_items() + item.iif(self.solver_run, tif_target.theta) * items[item.id] + for item in self.solver_run.items ] - ) >= tcc_target.value - (tcc_target.value * drift_percent) + ) >= tif_target.minimum(drift_percent) problem += lpSum( [ - bundle.trf(self.solver_run.irt_model, tcc_target.theta) * bundles[bundle.id] - for bundle in self.solver_run.bundles - ] + - [ - item.irf(self.solver_run, tcc_target.theta) * items[item.id] - for item in self.solver_run.unbundled_items() + item.iif(self.solver_run, tif_target.theta) * items[item.id] + for item in self.solver_run.items ] - ) <= tcc_target.value + (tcc_target.value * drift_percent) + ) <= tif_target.maximum(drift_percent) + for tcc_target in self.solver_run.objective_function.tcc_targets: # problem += lpSum( # [ + # bundle.trf(self.solver_run.irt_model, tcc_target.theta) * bundles[bundle.id] + # for bundle in self.solver_run.bundles + # ] + + # [ # item.irf(self.solver_run, tcc_target.theta) * items[item.id] - # for item in self.solver_run.items + # for item in self.solver_run.unbundled_items() # ] # ) >= tcc_target.value - (tcc_target.value * drift_percent) # problem += lpSum( # [ + # bundle.trf(self.solver_run.irt_model, tcc_target.theta) * bundles[bundle.id] + # for bundle in self.solver_run.bundles + # ] + + # [ # item.irf(self.solver_run, tcc_target.theta) * items[item.id] - # for item in self.solver_run.items + # for item in self.solver_run.unbundled_items() # ] # ) <= tcc_target.value + (tcc_target.value * drift_percent) + problem += lpSum( + [ + item.irf(self.solver_run, tcc_target.theta) * items[item.id] + for item in self.solver_run.items + ] + ) >= tcc_target.minimum(drift_percent) + problem += lpSum( + [ + item.irf(self.solver_run, tcc_target.theta) * items[item.id] + for item in self.solver_run.items + ] + ) <= tcc_target.maximum(drift_percent) + logging.info(f'Solving for Form {form_number} with a drift of {current_drift}%') problem.solve() if LpStatus[problem.status] == 'Infeasible': logging.info(f'attempt infeasible for drift of {current_drift}%') - - - # print(problem.objective.value()) - # print(problem.constraints) - # print(problem.objective) - if current_drift == Target.max_drift(): # this is the last attempt, so lets finalize the solution for v in problem.variables(): print(v.name, "=", v.varValue);