Creating constraints that reference other decision variables
回答済みHello,
I'm new to Gurobi and I have a question about constructing constraints that reference things between decision variables.
Here is a knapsack-type example where 4 shapes are being chosen and I'm attempting to maximize the total dollars of the selected shapes. Each shape must be chosen once. The total weight of the selected shapes must be less than or equal to 20.
In addition, each shape has a top_color and bottom_color associated to them. I would like to construct a constraint that does not allow the top_color of the selected square to be the same as the bottom_color of the selected rectangle.
My question is how to best construct this constraint? I've attempted creating two loops to compare the selected square shape to the selected rectangle shape, but I can't get this working.
A secondary question - my data is usually in a pandas data frame and I then construct lists like in the below example. Is there a better way to construct models using data frames, or is creating lists for variables preferable?
Thanks!
shapes = ['triangle', 'square', 'circle', 'rectangle', 'triangle', 'square', 'circle', 'rectangle', 'triangle', 'square', 'circle', 'rectangle']
top_color = ['blue', 'red', 'yellow', 'blue', 'red', 'yellow', 'blue', 'red', 'yellow', 'blue', 'red', 'yellow']
bottom_color = ['yellow', 'blue', 'red', 'blue', 'yellow', 'red', 'red', 'yellow', 'blue', 'yellow', 'blue', 'red']
weight = [2, 3, 4, 7, 6, 4, 5, 7, 8, 2, 1, 3]
dollars = [3 ,3 ,5 ,4 ,3, 8, 6, 7, 7, 5, 6, 4]
n = len(shapes)
model = gp.Model()
model.params.LogToConsole = True
decision_v_shapes = model.addVars(range(n), vtype=GRB.BINARY)
#Maximize Dollars
model.setObjective(gp.quicksum(decision_v_shapes[i] * dollars[i] for i in range(n)), GRB.MAXIMIZE)
#Constraints - Choose only one of each shape
model.addConstr(gp.quicksum(decision_v_shapes[i] for i in range(n) if shapes[i] == 'triangle') == 1)
model.addConstr(gp.quicksum(decision_v_shapes[i] for i in range(n) if shapes[i] == 'square') == 1)
model.addConstr(gp.quicksum(decision_v_shapes[i] for i in range(n) if shapes[i] == 'circle') == 1)
model.addConstr(gp.quicksum(decision_v_shapes[i] for i in range(n) if shapes[i] == 'rectangle') == 1)
model.addConstr(gp.quicksum(decision_v_shapes[i] for i in range(n)) == 4)
#Constraint - Weight must be under 20
model.addConstr(gp.quicksum(decision_v_shapes[i] * weight[i] for i in range(n)) <= 20)
#Constraint - Don't allow the top_color of the square to be the same as the bottom color of the rectangle
model.addConstr(gp.quicksum(decision_v_shapes[i] if shapes[i] == 'square' for i in range(n) and (gp.quicksum(decision_v_shapes[j] for j in range(n) if shapes[j] == 'rectangle' and top_color[i] == bottom_color[j]) > 0)) == 0)
model.optimize()
selected_shapes = [str(i) + ' ' + shapes[i] + ' ' + top_color[i] + ' ' + bottom_color[i] + ' ' + str(weight[i]) + ' ' + str(dollars[i]) for i in range(n) if decision_v_shapes[i].X > 0.1]
print(selected_shapes)
#Solution without the top_color of the square constraint
#0:"5 square yellow red 4 8"
#1:"7 rectangle red yellow 7 7"
#2:"8 triangle yellow blue 8 7"
#3:"10 circle red blue 1 6"
#
#But, The chosen squares top_color (yellow) is the same as the chosen rectangles bottom_color (yellow)
-
正式なコメント
This post is more than three years old. Some information may not be up to date. For current information, please check the Gurobi Documentation or Knowledge Base. If you need more help, please create a new post in the community forum. Or why not try our AI Gurobot?. -
Because you have three colours you will need three constraints. For the specific violated constraint you have it looks like:
sum(squares with yellow on top)+sum(rectangles with yellow on bottom) <= 1
0 -
Thank you. This works now.
0
投稿コメントは受け付けていません。
コメント
3件のコメント