I am brand new to Pyomo, and pretty new to Python. I am trying to write a model that includes an objective function with a nested sum. Here's a toy example that hopefully makes this question relevant to others as well:
I have a set of customers C and a set of servers S. I hire the servers by the minute, and I have a Pyomo Set of costs representing the cost per minute to hire each server (some more expensive than others). This Set has length equal to the number of servers. I also have a two-dimensional Pyomo set of service times representing the time needed to serve each customer. This is dependent on both the server and the customer, so it's indexed by both.
The total cost is the sum of the server costs, indexed by server, times the sum of the service times, indexed by both server and customer.
I can't figure out how to represent this in Pyomo, because the sets I'm indexing over are different. This link: Pyomo sum inside sum with various index seems like a similar question, but doesn't help. Keep in mind this all has to live inside a Pyomo Objective
function.
I tried using Pyomo's sum_product
function and indexing over the Cartesian product of both (index = model.customers * model.servers
), but that doesn't work because servers aren't indexable over customers.
I also tried nesting the sums (sum_product(server costs, sum_product(service times, index = model.customers * model.servers), index = servers)
), but that doesn't work either because the inner sum_product
becomes a LinearExpression object that isn't subscriptable by server.
How can I properly express this sum? Thanks so much.
I'm pretty sure your objective function will look something like this (assuming you have a binary variable x
in your model indicating if Server s was assigned to Customer c):
def cost_(model):
return sum(model.Scostperminute[s]*model.servicetime[s,c]*model.x[s,c] for s in model.S for c in model.C)
model.cost = Objective(rule=cost_)