I am working with a large optimization model using Plasmo.jl, but I encountered a performance issue when calling set_to_node_objectives(graph) on a graph with many nodes.
graph = OptiGraph()
set_optimizer(graph, Gurobi.Optimizer)
# Initial call to build the tree
println("Building Graph")
build_layer1_tree(graph, SA[], 1.0, 0)
display(graph)
# An OptiGraph
# g##284 #local elements #total elements
#--------------------------------------------------
# Nodes: 161617 161617
# Edges: 182364 182364
# Subgraphs: 0 0
# Variables: 714177 714177
# Constraints: 1306045 1306045
using JuMP
println("Setting Objective")
# set_to_node_objectives(graph) # hangs indefinitely
println("Optimizing")
optimize!(graph)
Upon investigating the source code of this function, I found two inefficiencies:
- The obj variable is initialized as an integer, but it accumulates more complex types (e.g., JuMP expressions).
- obj += sense * JuMP.objective_function(node) creates a copy of the expression each time it’s executed.
function set_to_node_objectives(graph::OptiGraph)
obj = 0
for node in all_nodes(graph)
if has_objective(node)
sense = JuMP.objective_sense(node) == MOI.MAX_SENSE ? -1 : 1
obj += sense * JuMP.objective_function(node) # Copies obj each time
end
end
if obj != 0
@objective(graph, Min, obj)
end
return nothing
end
For my specific case (which involves linear objectives), I was able to use the following workaround.
function set_to_node_objectives_linear(graph::OptiGraph)
obj::GenericAffExpr{Float64, NodeVariableRef} = 0.0
for node in all_nodes(graph)
if Plasmo.has_objective(node)
sense = JuMP.objective_sense(node) == MOI.MAX_SENSE ? -1 : 1
JuMP.add_to_expression!(obj, JuMP.objective_function(node), sense)
end
end
@objective(graph, Min, obj)
return
end
Is there a general way to fix this performance issue?
I am working with a large optimization model using Plasmo.jl, but I encountered a performance issue when calling
set_to_node_objectives(graph)on a graph with many nodes.Upon investigating the source code of this function, I found two inefficiencies:
For my specific case (which involves linear objectives), I was able to use the following workaround.
Is there a general way to fix this performance issue?