Combining Real and Theoretical Data in Gurobi Optimization Model
Hello everyone,
I'm working on an optimization problem where I need to combine real and theoretical markers for a fabric cutting operation. The challenge is to ensure that if a specific marker combination is available in a dictionary (real markers with specific combinations and lengths), the model should prioritize using it. If the specific combination is not found in the real marker dictionary, the model should default to a theoretical marker calculated based on average consumption.
Objective:
- Prioritize real markers when available.
- Use theoretical markers only when the specific combination is not found in the real marker dictionary.
Issues:
- I need to ensure that theoretical markers are used only when the specific combination is not found in the real marker dictionary.
from gurobipy import GRB
import gurobipy as gp
def add_specific_marker_constraints(model, binary_vars, length_marker, filtered_markers, avg_cons, max_pcs):
# Handle real markers
for marker in ['x', 'y', 'z', 'w']:
indicator_vars = []
for key, value in filtered_markers.items():
indicator_var = model.addVar(vtype=GRB.BINARY, name=f"indicator_{marker}_{key}")
model.addGenConstrIndicator(indicator_var, True,
binary_vars[marker]['XS'][key[0]] +
binary_vars[marker]['S'][key[1]] +
binary_vars[marker]['M'][key[2]] +
binary_vars[marker]['L'][key[3]] +
binary_vars[marker]['XL'][key[4]] +
binary_vars[marker]['XXL'][key[5]] == 6)
model.addConstr(indicator_var * length_marker[marker] == indicator_var * value)
indicator_vars.append(indicator_var)
# Set the length_marker to the length corresponding to the selected real marker
model.addConstr(length_marker[marker] == gp.quicksum(indicator_vars[i] * list(filtered_markers.values())[i] for i in range(len(filtered_markers))), name=f"length_marker_constraint_{marker}")
# Handle theoretical markers (combinations not present in the dictionary)
for marker in ['x', 'y', 'z', 'w']:
# Define the default length for theoretical markers
default_length = avg_cons * (
gp.quicksum(val * binary_vars[marker]['XS'][val] for val in range(max_pcs)) +
gp.quicksum(val * binary_vars[marker]['S'][val] for val in range(max_pcs)) +
gp.quicksum(val * binary_vars[marker]['M'][val] for val in range(max_pcs)) +
gp.quicksum(val * binary_vars[marker]['L'][val] for val in range(max_pcs)) +
gp.quicksum(val * binary_vars[marker]['XL'][val] for val in range(max_pcs)) +
gp.quicksum(val * binary_vars[marker]['XXL'][val] for val in range(max_pcs))
)
for xs in range(max_pcs):
for s in range(max_pcs):
for m in range(max_pcs):
for l in range(max_pcs):
for xl in range(max_pcs):
for xxl in range(max_pcs):
combination = (xs, s, m, l, xl, xxl)
if combination not in filtered_markers:
# Directly assign the default length
model.addConstr(length_marker[marker] == default_length, name=f"theoretical_length_{marker}_{combination}")
I'm unable to run the code with the current nested loop structure, but I believe the logic is rigth. Is there a more efficient way to implement the logic, possibly avoiding the nested loops, while ensuring that theoretical markers are only used when a real marker isn't available?
Please sign in to leave a comment.
Comments
0 comments