循环求解JuMP(HiGHS)模型时的内存泄漏问题求助
优化JuMP+HiGHS批量时序模型的循环性能问题
针对你用JuMP(HiGHS求解器)批量处理时序数据时,循环调用empty!(Model)导致求解时间呈O(n²)增长的问题,以下是具体优化方案:
1. 放弃模型复用+empty!,改用每次创建新模型
empty!(mdl)无法完全清除JuMP模型内部的所有元数据和缓存,随着循环次数增加,这些残留会导致模型构建和求解的开销持续上升。直接在每次循环中创建新模型,能避免这类累积问题:
using JuMP, HiGHS, CSV, DataFrames df = CSV.read("data.csv", DataFrame) final_output = Vector{Matrix{Float64}}(undef, 10) # 预分配输出数组 for batch = 1:10 batchIndex = # 你的批次索引逻辑 # 每次循环创建全新模型 mdl = Model(HiGHS.Optimizer) batch_output = optimizer_function(mdl, df[batchIndex]) final_output[batch] = batch_output end function optimizer_function(mdl, input_data) T = 1:24 @variable(mdl, 100 .>= x[T] .>= 0) @variable(mdl, 200 .>= y[T] .>= 0) # 定义约束、表达式、目标(保持原逻辑) @constraint(mdl, ...) exp1 = @expression(mdl, ...) @objective(mdl, Max, sum(exp1 + ...)) optimize!(mdl) return hcat(value.(x), value.(y)) end
2. 采用参数化模型(最优方案)
这是JuMP批量处理场景的核心优化手段:只一次性定义变量、约束和目标结构,用参数承载批次间变化的输入数据,循环中仅更新参数值,彻底避免重复解析JuMP宏的开销:
using JuMP, HiGHS, CSV, DataFrames # 一次性构建参数化模型 function build_parametric_model() mdl = Model(HiGHS.Optimizer) T = 1:24 # 定义固定结构的变量 @variable(mdl, 100 >= x[T] >= 0) @variable(mdl, 200 >= y[T] >= 0) # 定义参数,用于存储批次输入数据 @parameter(mdl, input_data[T]) # 用参数定义约束和目标(保持原逻辑) @constraint(mdl, con1[t in T], x[t] + y[t] <= input_data[t]) exp1 = @expression(mdl, sum(x[t] for t in T)) exp2 = @expression(mdl, sum(y[t] * input_data[t] for t in T)) @objective(mdl, Max, exp1 + exp2) return mdl, x, y, input_data end # 初始化模型和变量/参数 mdl, x, y, input_param = build_parametric_model() # 开启warmstart,利用批次间解的连续性加速求解 set_optimizer_attribute(mdl, "warm_start", "yes") df = CSV.read("data.csv", DataFrame) final_output = Vector{Matrix{Float64}}(undef, 365) # 预分配365个批次的输出 for batch = 1:365 batchIndex = # 你的批次索引逻辑 # 更新参数值为当前批次数据 batch_data = df[batchIndex, :your_input_column] set_value.(input_param, batch_data) # 求解 optimize!(mdl) # 保存结果 final_output[batch] = hcat(value.(x), value.(y)) end
3. 配置求解器选项加速
针对时序批次数据的连续性,开启HiGHS的warmstart功能,让求解器以上一次的解作为初始点,大幅减少迭代次数:
# 创建模型时直接设置 mdl = Model(() -> HiGHS.Optimizer( "warm_start" => "yes", "presolve" => "on", # 开启预求解简化模型 "time_limit" => 30 # 可选,设置单批次求解超时 ))
4. 避免全局变量,利用函数编译优化
Julia对全局变量的性能支持较差,将整个批量处理逻辑封装到函数中,触发Julia的函数级编译优化,进一步降低内存分配和运行开销:
function run_full_batch(df, num_batches::Int) mdl, x, y, input_param = build_parametric_model() set_optimizer_attribute(mdl, "warm_start", "yes") final_output = Vector{Matrix{Float64}}(undef, num_batches) for batch = 1:num_batches batchIndex = # 你的批次索引逻辑 batch_data = df[batchIndex, :your_input_column] set_value.(input_param, batch_data) optimize!(mdl) final_output[batch] = hcat(value.(x), value.(y)) end return final_output end # 调用函数 df = CSV.read("data.csv", DataFrame) results = run_full_batch(df, 365)
内容的提问来源于stack exchange,提问作者Telemakos_1987BC
相关产品推荐
相关产品推荐

