KeyError = 0 from objective function
回答済みHi,
I am new to gurobi and python and I am trying to create a simple route model. I however keep getting the KeyError = 0 from my objective function. Any suggestions?
import gurobipy as gp
from gurobipy import GRB
import numpy as np
"""Define Model"""
f = gp.Model(name = "SimpleModel")
"""Sets"""
# P = Ports
ports = ['Port 1','Port 2','Port 3','Port 4', 'Port 5']
"""Parameters"""
# d_ij = arcs, cost
arcs, cost = gp.multidict({
('Port 1', 'Port 1'): 0,
('Port 1', 'Port 2'): 5,
('Port 1', 'Port 3'): 7,
('Port 1', 'Port 4'): 11,
('Port 1', 'Port 5'): 17,
('Port 2', 'Port 1'): 5,
('Port 2', 'Port 2'): 0,
('Port 2', 'Port 3'): 2,
('Port 2', 'Port 4'): 6,
('Port 2', 'Port 5'): 12,
('Port 3', 'Port 1'): 7,
('Port 3', 'Port 2'): 2,
('Port 3', 'Port 3'): 0,
('Port 3', 'Port 4'): 4,
('Port 3', 'Port 5'): 10,
('Port 4', 'Port 1'): 11,
('Port 4', 'Port 2'): 6,
('Port 4', 'Port 3'): 4,
('Port 4', 'Port 4'): 0,
('Port 4', 'Port 5'): 6,
('Port 5', 'Port 1'): 17,
('Port 5', 'Port 2'): 12,
('Port 5', 'Port 3'): 10,
('Port 5', 'Port 4'): 6,
('Port 5', 'Port 5'): 0 })
CostRP = dict({'Port 1': 100,
'Port 2': 90,
'Port 3': 80,
'Port 4': 100,
'Port 5': 70})
CostCCS = 15
"""Inidices"""
I = range(len(ports))
J = range(len(ports))
"""Variables"""
x = f.addVars(I, name = 'x', vtype = GRB.BINARY)
y = f.addVars(arcs, name = 'y', vtype = GRB.BINARY)
"""Constraints"""
c1 = f.addConstrs((x.sum('*') >= y.sum('*',j) for j in J), name='Constraint 1')
c2 = f.addConstrs((y.sum(1,j) == 1 for j in J), name= 'Constraint 2')
c3 = f.addConstrs((y.sum(i,5) == 1 for i in I), name='Constraint 3')
c4 = f.addConstrs((y.sum(i,'*') == y.sum('*',i) for i in I), name='Constraint 4')
"""Objective function"""
#obj = (CostRP.keys() * x.sum()) + (CostCCS * max(cost * y[i,j]) for i in I for j in J)
obj1 = sum(x[i] * CostRP[i] for i in I) + (CostCCS * max(cost*y))
f.setObjective(obj1, GRB.MINIMIZE)
"""Solving"""
f.optimize()
-
正式なコメント
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 try Gurobot, our chatbot interface offering instant, expert-level support. -
You defined your \(x\) variables over \(I=\{0,1,2,3,4\}\) but your \(\texttt{CostRP}\) dictionary maps Ports to values. There are multiple solutions to this issue.
You could define your \(\texttt{CostRP}\) dictionary as
CostRP = dict({0: 100,
1: 90,
2: 80,
3: 100,
4: 70})to access \(\texttt{CostRP}\) values via the same indices used to access the \(x\) variables. Alternatively, you could define your \(x\) variables over the \(\texttt{ports}\) list.
x = f.addVars(ports, name = 'x', vtype = GRB.BINARY)
# ...
obj1 = sum(x[i] * CostRP[i] for i in ports)There is another issue with your code. You are trying to compute the maximum over all costs multiplied with the respective \(y\) variables. Gurobi has a special method for the \(\max\) function. However, in your case, you can just add 1 auxiliary variable and a set of inequality constraints to model the minimum of a \(\max\) function
aux = f.addVar(name = 'aux', vtype = GRB.CONTINUOUS)
f.addConstrs((y[a]*cost[a] <= aux for a in arcs), name='max constraint')
obj1 = sum(x[i] * CostRP[i] for i in ports) + (CostCCS * aux)Moreover, you are defining your \(y\) variables over \(\texttt{arcs}\) but then use the numerical sets \(I,J\) to access the entries of \(y\). This is not possible because \(\texttt{arcs}\) are defined over \(\texttt{ports}\) and not over numerical indices \(0,1,2,3,4\). Thus, your code should look similar to
c1 = f.addConstrs((x.sum('*') >= y.sum('*',p) for p in ports), name='Constraint 1')
c2 = f.addConstr(gp.quicksum(y['Port 1',p] for p in ports) == 1, name= 'Constraint 2')
c3 = f.addConstr(gp.quicksum(y[p,'Port 5'] for p in ports) == 1, name='Constraint 3')
c4 = f.addConstrs((y.sum(p,'*') == y.sum('*',p) for p in ports), name='Constraint 4')You can always use the write method to write an LP file and analyze it by hand whether the model actually looks as expected.
Another side note: We recommend to not use white spaces or any special characters in variable and constraint names.
Best regards,
Jaromił1 -
Hi Jaromil,
Thank you so much for the guidance! It helped a lot!
Just a question regarding the a auxiliary variable and the set of inequality constraints: how would this be included in a written mathematical model? Should I just write it as a separate variable there as well? Or is there a more correct mathematical way of including this?
Kind regards
Marit Solheim Thériault0 -
Hi Marit,
In a mathematical model, you can also just add this auxiliary variable explicitly and mention that it is used to reformulate the \(\max\) function. As long as it is clear and understandable for the reader, it should be fine.
Best regards,
Jaromił0
投稿コメントは受け付けていません。
コメント
4件のコメント