Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MethodError: no method matching (:: LinearInterpolation {Vector {Real}, Vector {Real}, true, Real}) (:: AffExpr) occurs when DataInterpolation is called in the optimization objective #3543

Closed
chooron opened this issue Oct 13, 2023 · 2 comments

Comments

@chooron
Copy link

chooron commented Oct 13, 2023

Hello, I am using JuMP for reservoir optimization scheduling. Because the reservoir capacity changes, I need to obtain the reservoir water level changes using interpolation methods. Therefore, I used DataInterpolation.jl. However, when building the optimization problem, the variable x generated is of type Vector{VariableRef}, which does not match the type required by DataInterpolation, resulting in this error. Is there a solution for this issue? Here is my code:

# 构建水库调度的优化函数基于JuMP
using DataInterpolations, Statistics, JuMP
import HiGHS

# 定义reservoir对象
default_levels = Float32.([22, 24, 26, 28, 30, 32])
default_storages = Float32.([0.61e8, 0.694e8, 0.876e8, 1.133e8, 1.450e8, 1.852e8])
inflow = Float32.([28, 69, 105, 367, 1320, 2440, 2760, 3020, 3140, 2900, 2750, 1870, 1300, 1100, 980, 820])
dt = 1

# 约束条件设置
min_outflow = 100.0;
max_outflow = 2000.0;

max_level = 26.0;
min_level = 22.0;


struct Curve
    levels::Vector{Real}
    storages::Vector{Real}
end

curve = Curve(default_levels, default_storages)

function interp(c::Curve, input_series, series_name)
    interp_linear = Nothing
    if series_name == "storages"
        interp_linear = LinearInterpolation(c.levels, c.storages)
    else
        interp_linear = LinearInterpolation(c.storages, c.levels)
    end
    interp_series = interp_linear.(input_series)
    return interp_series
end

# test interp
# curve = Curve(default_levels, default_storages)
# interp_res = interp(curve, [23,25,26], "levels")

function water_balance(inflow, outflow, dt)
    Δstorage = (inflow - outflow) * dt * 3600
    return Δstorage
end

function objective(u)
    tmp_storages = water_balance.(inflow, u, dt)
    tmp_levels = interp(curve, tmp_storages, "storages")
    minimum(tmp_levels)
end

function min_level_constraint(u)
    min_storage = minimum(water_balance.(inflow, u, dt))
    interp(curve, min_storage, "storages")
end

function max_level_constraint(u)
    max_storage = maximum(water_balance.(inflow, u, dt))
    interp(curve, max_storage, "storages")
end


n = size(inflow, 1)
model = Model(HiGHS.Optimizer)
@variable(model, min_outflow <= x[1:n] <= max_outflow, Int)
@constraint(model, min_level_constraint(x) >= min_level)
@constraint(model, max_level_constraint(x) <= max_level)
@objective(model, Min, objective(x))
@odow
Copy link
Member

odow commented Oct 13, 2023

Hi @chooron,

HiGHS is a linear programming solver. You cannot use regular Julia functions (like interp) to define your problem. You must formulate it as a mixed-integer linear program with linear constraints and an objective.

If you need help with the formulation, please post on the community forum: https://discourse.julialang.org/c/domain/opt/13

@odow
Copy link
Member

odow commented Oct 15, 2023

Closing this as won't-fix.

@chooron if you post on the https://discourse.julialang.org/c/domain/opt/13 I'll be happy to discuss further 😄

We try to keep the GitHub issues for bug reports and feature requests.

@odow odow closed this as completed Oct 15, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

No branches or pull requests

2 participants