Search code examples
pythonoptimizationpyomogurobi

Pyomo: Best way to optimize size of power plants and TypeError: unsupported operand type(s) for *: 'float' and 'IndexedVar'


I am trying to solve a optimization problem where the load demand has to be met by two power plants. These power plants have different power production. For example (random numbers)

power_prod1 = [2,0,1]
power_prod2 = [0,1,1]

The load demand and cost of different power plants is given in a similar way.The costs refer the size of the plant see plant1 and plant2 size below.

load_demand = [4,4,4] 
Costs = {'power 1':60, 'power2':120}

To solve this I have tried


def plant1_size(model,i,j):
    return(0, None)
model.PowerPlant1Size = pyo.Var(model.plants,model.periods,bounds=plant1_size)

def plant2_size(model,i,j):
    return(0, None)
model.PowerPlant2Size  = pyo.Var(model.plants,model.periods,bounds=plant2_size)


def load_balance(model,i,j):
    return (power_prod1[j]*model.PowerPlant1Size + power_prod2[j]*model.PowerPlant2Size == load_demand[j])
model.load_constraint = pyo.Constraint(model.plants,model.periods,rule=load_balance)


and having a objective function where the objective is to minimize the costs by selecting the right size for the power plants. When i run this code i get an error "TypeError: unsupported operand type(s) for *: 'float' and 'IndexedVar'". I know why i get this error, but i cant figure out a way to solve for the size of the power plants. (There might be some excess code from when i tried to solve the problem another way and some code I havent included).

How do i rewrite this problem in a way pyomo can solve?


Solution

  • There are several things that are troublesome here. I'm not sure if your underlying math problem is sound. I'd slow down with the implementation and lay out all of the variables and indices with pencil and paper to make sure it makes sense. For instance, you have plant size as a variable that is indexed over time periods... Does that mean that power plant # 5 can get bigger and smaller in different time periods?

    On that same variable, you seem to be embedding the index into the name, even though you are indexing by plant number. I would expect to see something like the production from a particular plant as a variable like:

    model.production = pyo.Var(model.plants, model.time_periods)
    

    Oh, and the main source of the error you are seeing is that you are using an indexed variable without supplying the index for PowerPlantSize in your objective...