You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何利用变量引用在定点高效评估JuMP模型中的表达式?

高效评估JuMP表达式(无需手动构建字典)

你可以通过自定义求值回调函数,直接将模型变量与对应的DenseAxisArray数值关联,无需手动编写字典。以下是两种可行方案:

方案1:动态索引查找(适合变量数量较少的场景)

通过判断变量所属的容器,动态查找对应索引的数值:

using JuMP
using JuMP.Containers

# 初始化模型、变量与表达式
model = Model()
@variables(model, begin
    -1 <= x[1:5] <= 1
    -5 <= y[1:3] <= 8
    -30 <= z <= 5
end)
ex = @NLexpression(model, sum(x[i] for i=1:4) - y[1] * y[2] + z)

# 你的数值数组
last_x = Containers.DenseAxisArray(vcat(1:4), vcat(1:4))
last_y = Containers.DenseAxisArray([5,6], vcat(1:2))
last_z = Containers.DenseAxisArray([7], 1)

# 创建求值回调函数
function create_evaluator(var_containers::Pair...)
    return var -> begin
        for (container, values) in var_containers
            if var in container
                # 找到变量在容器中的对应索引
                idx = only(filter(k -> container[k] === var, eachindex(container)))
                return values[idx]
            end
        end
        # 未匹配变量返回默认值
        return 0.0
    end
end

# 生成求值器并评估表达式
eval_func = create_evaluator(model[:x] => last_x, model[:y] => last_y, model[:z] => last_z)
result = value(eval_func, ex)
println(result)  # 输出:-13

方案2:自动生成映射字典(高效,适合大量变量场景)

内部自动构建变量到数值的映射字典,既省去手动编写字典的麻烦,又保证O(1)的查找效率:

using JuMP
using JuMP.Containers

# 初始化模型、变量与表达式(同方案1)
model = Model()
@variables(model, begin
    -1 <= x[1:5] <= 1
    -5 <= y[1:3] <= 8
    -30 <= z <= 5
end)
ex = @NLexpression(model, sum(x[i] for i=1:4) - y[1] * y[2] + z)

# 你的数值数组(同方案1)
last_x = Containers.DenseAxisArray(vcat(1:4), vcat(1:4))
last_y = Containers.DenseAxisArray([5,6], vcat(1:2))
last_z = Containers.DenseAxisArray([7], 1)

# 创建高效求值回调函数
function create_evaluator(var_containers::Pair...)
    var_map = Dict{VariableRef, Float64}()
    # 自动遍历容器与数值数组,构建映射
    for (container, values) in var_containers
        for idx in eachindex(container)
            var_map[container[idx]] = values[idx]
        end
    end
    return var -> get(var_map, var, 0.0)
end

# 生成求值器并评估表达式
eval_func = create_evaluator(model[:x] => last_x, model[:y] => last_y, model[:z] => last_z)
result = value(eval_func, ex)
println(result)  # 输出:-13

关键说明

  • JuMP的value函数支持传入回调函数,该函数接收VariableRef对象并返回对应数值,这是实现的核心。
  • 两种方案都无需手动编写变量-数值的字典,只需传入模型变量容器(如model[:x])与对应的数值数组即可。
  • 方案2内部虽使用字典,但完全自动生成,无需你手动维护变量与数值的对应关系。

内容的提问来源于stack exchange,提问作者Hugo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 00:05:01