random select recursive solution for bundle constraints
This commit is contained in:
parent
8ce5e6e540
commit
14a07ff9b2
@ -56,6 +56,22 @@ def build_constraints(solver_run: SolverRun, problem: LpProblem, items: list[Ite
|
|||||||
logging.error(error)
|
logging.error(error)
|
||||||
raise ItemGenerationError("Bundle min and/or max larger than bundle amount provided", error.args[0])
|
raise ItemGenerationError("Bundle min and/or max larger than bundle amount provided", error.args[0])
|
||||||
|
|
||||||
|
def get_random_bundles(total_form_items: int, total_bundles: int, bundles: list[Bundle], found_bundles = False) -> list[Bundle]:
|
||||||
|
selected_bundles = None
|
||||||
|
total_bundle_items = 0
|
||||||
|
|
||||||
|
while found_bundles == False:
|
||||||
|
selected_bundles = sample(bundles, total_bundles)
|
||||||
|
total_bundle_items = sum(bundle.count for bundle in selected_bundles)
|
||||||
|
|
||||||
|
if total_bundle_items <= total_form_items:
|
||||||
|
found_bundles = True
|
||||||
|
|
||||||
|
if found_bundles == True:
|
||||||
|
return selected_bundles
|
||||||
|
else:
|
||||||
|
return get_random_bundles(total_form_items, total_bundles - 1, bundles)
|
||||||
|
|
||||||
def valid_bundle_combinations(total_form_items: int, total_bundles: int, min_bundles: int, bundles: list[Bundle], selected_bundle_combinations: list[list[Bundle]] = []) -> list[list[Bundle]]:
|
def valid_bundle_combinations(total_form_items: int, total_bundles: int, min_bundles: int, bundles: list[Bundle], selected_bundle_combinations: list[list[Bundle]] = []) -> list[list[Bundle]]:
|
||||||
if total_bundles < min_bundles:
|
if total_bundles < min_bundles:
|
||||||
return selected_bundle_combinations
|
return selected_bundle_combinations
|
||||||
|
@ -74,33 +74,36 @@ class LoftService(Base):
|
|||||||
response_id=random.randint(100, 5000),
|
response_id=random.randint(100, 5000),
|
||||||
forms=[]
|
forms=[]
|
||||||
)
|
)
|
||||||
|
|
||||||
# initiate problem
|
# initiate problem
|
||||||
problem = None
|
problem = None
|
||||||
count = 0
|
count = 0
|
||||||
|
|
||||||
if bundle_constraint:
|
if bundle_constraint:
|
||||||
# generate valid bundle combinations
|
# # generate valid bundle combinations
|
||||||
bundle_combinations = solver_helper.valid_bundle_combinations(
|
# bundle_combinations = solver_helper.valid_bundle_combinations(
|
||||||
self.solver_run.total_form_items,
|
# self.solver_run.total_form_items,
|
||||||
int(bundle_constraint.maximum),
|
# int(bundle_constraint.maximum),
|
||||||
int(bundle_constraint.minimum),
|
# int(bundle_constraint.minimum),
|
||||||
self.solver_run.bundles)
|
# self.solver_run.bundles)
|
||||||
|
|
||||||
# scramble bundle_combinations to ensure distinctiveness for each form generated
|
# # scramble bundle_combinations to ensure distinctiveness for each form generated
|
||||||
random.shuffle(bundle_combinations)
|
# random.shuffle(bundle_combinations)
|
||||||
|
|
||||||
for bundles in bundle_combinations:
|
# for bundles in bundle_combinations:
|
||||||
problem = self.solve_problem(items, bundles)
|
# problem = self.solve(items, bundles)
|
||||||
|
|
||||||
# if optimal solution found, break loop
|
# # if optimal solution found, break loop
|
||||||
if LpStatus[problem.status] == 'Optimal':
|
# if LpStatus[problem.status] == 'Optimal':
|
||||||
break
|
# break
|
||||||
|
bundles_amount = random.randint(int(bundle_constraint.minimum), int(bundle_constraint.maximum))
|
||||||
|
problem = self.recursive_solve(items, bundles_amount)
|
||||||
else: # no bundles
|
else: # no bundles
|
||||||
problem = self.solve_problem(items)
|
problem = self.solve(items)
|
||||||
|
|
||||||
# successfull form, increment and exit out of loop
|
# successfull form, increment and exit out of loop
|
||||||
f += 1
|
f += 1
|
||||||
|
|
||||||
# add return items and create as a form
|
# add return items and create as a form
|
||||||
form_items = service_helper.solution_items(problem.variables(), self.solver_run)
|
form_items = service_helper.solution_items(problem.variables(), self.solver_run)
|
||||||
|
|
||||||
@ -108,8 +111,22 @@ class LoftService(Base):
|
|||||||
solution.forms.append(Form.create(form_items, self.solver_run, LpStatus[problem.status]))
|
solution.forms.append(Form.create(form_items, self.solver_run, LpStatus[problem.status]))
|
||||||
|
|
||||||
return solution
|
return solution
|
||||||
|
|
||||||
def solve_problem(self, items: list[Item], bundles: list[Bundle] or None = None) -> LpProblem:
|
def recursive_solve(self, items, bundles_amount, attempts = 1000) -> LpProblem:
|
||||||
|
selected_bundles = solver_helper.get_random_bundles(
|
||||||
|
self.solver_run.total_form_items,
|
||||||
|
bundles_amount,
|
||||||
|
self.solver_run.bundles)
|
||||||
|
|
||||||
|
problem = self.solve(items, selected_bundles)
|
||||||
|
|
||||||
|
# if optimal solution found, break loop
|
||||||
|
if LpStatus[problem.status] == 'Optimal' or attempts == 0:
|
||||||
|
return problem
|
||||||
|
else:
|
||||||
|
return self.recursive_solve(items, max, attempts - 1)
|
||||||
|
|
||||||
|
def solve(self, items: list[Item], bundles: list[Bundle] or None = None) -> LpProblem:
|
||||||
# create problem
|
# create problem
|
||||||
problem = LpProblem("ata-form-generate", LpMinimize)
|
problem = LpProblem("ata-form-generate", LpMinimize)
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user