We don't know how to parse constraints containing expressions of type :generator

I am trying to set up the following dispatch optimization problem. However, the capacity constraints gives me the error:

`@constraint(m, [t in time], (cfD[:p] >= y[p, t] for p = plants))`: Unsupported constraint expression: we don't know how to parse constraints containing expressions of type :generator.

The model looks like this:

 Set Up Optimization model  
m = Model(GLPK.Optimizer)

plants = cf[:,1]
time = keys(dd[:,1])


# Decision Variable
@variable(m, 0 <= y[plants,time])


#  Objective Function
@objective(m,Min, 
sum(dt[!,:tmc] * y[p,t] for p in plants,t in time)
);



# Demand constraint
k = dd[!,1]
v = dd[!,2]
demand = Dict(zip(time,v))
dd[1,2]

@constraint(m, [t in time], 
    sum(y[p, t] for p in plants) == dd[t,2])


# Capacity Constraint
for (name, col) in pairs(eachcol(cf[!,2:end]))
    cf[!,name] =  cf[!,name] .* dt[!,:Cap] 
end

k = cf[!,1]
v = Matrix(cf[!,2:11])

cfD = Dict(k .=> [v[i,:] for i in 1:8])


@constraint(m, [t in time] , cfD[:p] >= y[p,t] for p in plants
)

Where I use the following data

the dt Dataframe:

string= "Column1,Cap,ETA_EL,Fuel_P,c_var_other,EMF,mc,CO2Costs,tmc\nCCGT,30000.0,0.54,19.0,1.5,0.2048,35.18518518518518,45.511111111111106,126.20740740740739\nGT_GasOil,4400.0,0.28,19.0,1.5,0.2048,67.85714" ⋯ 214 bytes ⋯ ",129.60000000000002,268.3891891891892\nNuclear,8400.0,0.33,1.8,0.7,0.0,5.454545454545454,0.0,5.454545454545454\nWind,61000.0,1.0,0.0,1.4,0.0,0.0,0.0,0.0\nSolar,46500.0,1.0,0.0,1.0,0.0,0.0,0.0,0.0\n"
dt = CSV.read(IOBuffer(string),DataFrame)

here is the demand DataFrame

string= "t1,83115\nt2,71169\nt3,66729\nt4,61442\nt5,60430\nt6,57013\nt7,52048\nt8,48701\nt9,43981\nt10,40498\n"
dd= CSV.read(IOBuffer(string),DataFrame)

and here is the capacity factor DataFrame

string = "Column1,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10\nCCGT,17700.0,18900.0,17700.0,18300.0,20100.0,18300.0,18900.0,20100.0,18600.0,19200.0\nGT_GasOil,2772.0,3035.9999999999995,2992.0,2992.0,3080.0,2772.0,2992.0,2684.0,3080.0,3080.0\nHydro,4056.0,4108.0,3587.99" ⋯ 248 bytes ⋯ "clear,7980.0,8064.0,7308.0,7476.0,7728.0,7896.0,8148.0,7308.0,7392.0,7728.0\nWind,10370.0,9760.0,12200.0,12810.0,18910.0,18910.0,12810.0,14640.0,20740.0,10370.0\nSolar,11160.0,2325.0,4185.0,7905.000000000001,7440.0,6975.0,5580.0,1395.0,0.0,0.0\n"
cf= CSV.read(IOBuffer(string),DataFrame)

Thanks a lot!
Alex

That syntax isn’t quite correct. Do you mean instead:

@constraint(m, [p in plants, t in time] , cfD[p] >= y[p,t])

(I can’t run your code because I can’t reproduce your input data from the printouts.)

Thank you! Now this works but I still get a problem when coding my objective function:

#  Objective Function
k = dt[!,1]
v = dt[!,:Cap]

capD = Dict(k .=> [v[i,:] for i in 1:8])


@objective(m,Min, 
sum(capD[p] * y[p,t] for p in plants,t in time)
);

I get the following error:

The solver does not support an objective function of type MathOptInterface.VectorAffineFunction{Float64}

I think with a bit of re-organization you can make something a lot cleaner. How about;

using JuMP
import CSV, DataFrames, HiGHS
string = "Tech,Cap,ETA_EL,Fuel_P,c_var_other,EMF,mc,CO2Costs,tmc\nCCGT,30000.0,0.54,19.0,1.5,0.2048,35.18518518518518,45.511111111111106,126.20740740740739\nNuclear,8400.0,0.33,1.8,0.7,0.0,5.454545454545454,0.0,5.454545454545454\nWind,61000.0,1.0,0.0,1.4,0.0,0.0,0.0,0.0\nSolar,46500.0,1.0,0.0,1.0,0.0,0.0,0.0,0.0\n"
dt = CSV.read(IOBuffer(string), DataFrames.DataFrame)
string = "TimePeriod,Demand\nt1,83115\nt2,71169\nt3,66729\nt4,61442\nt5,60430\nt6,57013\nt7,52048\nt8,48701\nt9,43981\nt10,40498\n"
dd = CSV.read(IOBuffer(string), DataFrames.DataFrame)
string = "Tech,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10\nCCGT,17700.0,18900.0,17700.0,18300.0,20100.0,18300.0,18900.0,20100.0,18600.0,19200.0\nNuclear,7980.0,8064.0,7308.0,7476.0,7728.0,7896.0,8148.0,7308.0,7392.0,7728.0\nWind,10370.0,9760.0,12200.0,12810.0,18910.0,18910.0,12810.0,14640.0,20740.0,10370.0\nSolar,11160.0,2325.0,4185.0,7905.000000000001,7440.0,6975.0,5580.0,1395.0,0.0,0.0\n"
cf = CSV.read(IOBuffer(string), DataFrames.DataFrame)

model = Model(HiGHS.Optimizer)
@variable(model, 0 <= y[cf.Tech, dd.TimePeriod])
capacity = Dict(dt.Tech .=> dt.Cap)
for row in DataFrames.eachrow(DataFrames.stack(cf))
    set_upper_bound(y[row.Tech, row.variable], capacity[row.Tech] * row.value)
end
@objective(
    model,
    Min,
    sum(row.tmc * sum(y[row.Tech, :]) for row in DataFrames.eachrow(dt))
)
@constraint(model, [row in DataFrames.eachrow(dd)], sum(y[:, row.TimePeriod]) == row.Demand)

This tutorial has some suggestions for using DataFrames and JuMP: The diet problem · JuMP

1 Like