如何利用变量引用在定点高效评估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
相关产品推荐
相关产品推荐

