From 6ebe33a76b092061b149c6546ed31d379f9b6b6a Mon Sep 17 00:00:00 2001 From: Adrian Manteza Date: Thu, 24 Mar 2022 16:47:55 +0000 Subject: [PATCH] cleanup and < 3 bundle pre-filter --- app/helpers/service_helper.py | 1 - app/helpers/solver_helper.py | 9 ++------- app/models/solver_run.py | 9 +++++++++ app/services/loft_service.py | 2 +- 4 files changed, 12 insertions(+), 9 deletions(-) diff --git a/app/helpers/service_helper.py b/app/helpers/service_helper.py index c922aac..7d252c8 100644 --- a/app/helpers/service_helper.py +++ b/app/helpers/service_helper.py @@ -43,7 +43,6 @@ def csv_to_item(items_csv_reader, solver_run): item[col] = row[key] # confirm item is only added if it meets the criteria of 100% constraints as a pre-filter - # items.append(Item.parse_obj(item)) valid_item = True item = Item.parse_obj(item) for constraint in solver_run.constraints: diff --git a/app/helpers/solver_helper.py b/app/helpers/solver_helper.py index aa6444c..8d0609f 100644 --- a/app/helpers/solver_helper.py +++ b/app/helpers/solver_helper.py @@ -26,18 +26,13 @@ def build_constraints(solver_run: SolverRun, problem: LpProblem, if attribute.type == 'metadata': logging.info('Metadata Constraint Generating...') - con = dict( - zip([item.id for item in solver_run.items], [ - boolean_to_int(item.attribute_exists(attribute)) - for item in solver_run.items - ])) problem += lpSum( [ len(bundle.items_with_attribute(attribute)) * bundles[bundle.id] for bundle in solver_run.bundles ] + [ - con[item.id] * items[item.id] for item in solver_run.unbundled_items() + item.attribute_exists(attribute).real * items[item.id] for item in solver_run.unbundled_items() ] ) >= round(total_form_items * (min / 100)), f'{attribute.id} - {attribute.value} - min' @@ -46,7 +41,7 @@ def build_constraints(solver_run: SolverRun, problem: LpProblem, len(bundle.items_with_attribute(attribute)) * bundles[bundle.id] for bundle in solver_run.bundles ] + [ - con[item.id] * items[item.id] for item in solver_run.unbundled_items() + item.attribute_exists(attribute).real * items[item.id] for item in solver_run.unbundled_items() ] ) <= round(total_form_items * (max / 100)), f'{attribute.id} - {attribute.value} - max' elif attribute.type == 'bundle': diff --git a/app/models/solver_run.py b/app/models/solver_run.py index b3fbe8c..174eb8a 100644 --- a/app/models/solver_run.py +++ b/app/models/solver_run.py @@ -86,6 +86,12 @@ class SolverRun(BaseModel): items=[item], type=type_attribute) ] + # temporary compensator for bundle item limits, since we shouldn't be using cases with less than 3 items + # ideally this should be in the bundles model as a new attribute to handle "constraints of constraints" + logging.info('Removing bundles with items < 3') + for k,v in enumerate(self.bundles): + bundle = self.bundles[k] + if bundle.count < 3: del self.bundles[k] logging.info('Bundles Generated...') @@ -94,4 +100,7 @@ class SolverRun(BaseModel): if constraint.reference_attribute.id == name), None) def unbundled_items(self) -> list: + # since the only bundles are based on passage id currently + # in the future when we have more than just passage based bundles + # we'll need to develop a more sophisticated way of handling this concern return [item for item in self.items if item.passage_id == None] diff --git a/app/services/loft_service.py b/app/services/loft_service.py index 7eebd8c..4cf9bba 100644 --- a/app/services/loft_service.py +++ b/app/services/loft_service.py @@ -65,7 +65,7 @@ class LoftService(Base): solution = Solution(response_id=random.randint(100, 5000), forms=[]) # unsolved solution # setup common Solver variables - items = LpVariable.dicts("Item", [item.id for item in self.solver_run.items], lowBound=0, upBound=1, cat='Binary') + items = LpVariable.dicts("Item", [item.id for item in self.solver_run.unbundled_items()], lowBound=0, upBound=1, cat='Binary') bundles = LpVariable.dicts("Bundle", [bundle.id for bundle in self.solver_run.bundles], lowBound=0, upBound=1, cat='Binary') # iterate for number of forms that require creation