From 7c5a870cef18d9129f3c397313ba0c13d16e1128 Mon Sep 17 00:00:00 2001 From: jalving Date: Fri, 5 Jul 2024 14:53:27 -0700 Subject: [PATCH] address above comments --- src/node_variables.jl | 2 +- src/optigraph.jl | 9 +++++++++ src/optimizer_interface.jl | 9 +++++++++ src/optinode.jl | 14 ++++++++++++++ test/test_optigraph.jl | 6 ++++++ 5 files changed, 39 insertions(+), 1 deletion(-) diff --git a/src/node_variables.jl b/src/node_variables.jl index fc7f43e..d0ef0c2 100644 --- a/src/node_variables.jl +++ b/src/node_variables.jl @@ -270,7 +270,7 @@ function JuMP.upper_bound(nvref::NodeVariableRef) end function JuMP.delete_upper_bound(nvref::NodeVariableRef) - JuMP.delete(JuMP.owner_model(nvref), JuMP.LowerBoundRef(nvref)) + JuMP.delete(JuMP.owner_model(nvref), JuMP.UpperBoundRef(nvref)) return nothing end diff --git a/src/optigraph.jl b/src/optigraph.jl index 3f85951..f9480f9 100644 --- a/src/optigraph.jl +++ b/src/optigraph.jl @@ -719,6 +719,15 @@ end # Objective function # +function has_node_objective(graph::OptiGraph) + for node in all_nodes(graph) + if has_objective(node) + return true + end + end + return false +end + function set_to_node_objectives(graph::OptiGraph) obj = 0 for node in all_nodes(graph) diff --git a/src/optimizer_interface.jl b/src/optimizer_interface.jl index beda3cc..dcfb59a 100644 --- a/src/optimizer_interface.jl +++ b/src/optimizer_interface.jl @@ -139,6 +139,15 @@ function JuMP.optimize!( throw(JuMP.NoOptimizer()) end + # check for node objectives when graph objective is empty + if iszero(objective_function(graph)) + if has_node_objective(graph) + @warn "The optigraph objective is empty but objectives exist on optinodes. + If this is not intended, consider using `set_to_node_objectives(graph)` to + set the graph objective function." + end + end + try # make sure subgraph elements are tracked in parent graph after solve MOI.optimize!(graph_backend(graph)) diff --git a/src/optinode.jl b/src/optinode.jl index d3d3368..be0d077 100644 --- a/src/optinode.jl +++ b/src/optinode.jl @@ -189,6 +189,20 @@ function JuMP.set_objective( return nothing end +function JuMP.set_objective_function(node::OptiNode, func::JuMP.AbstractJuMPScalar) + # check that all func terms are for this node + unique(collect_nodes(func)) == [node] || error("Optinode does not own all variables.") + d = JuMP.object_dictionary(node) + d[(node, :objective_function)] = func + return nothing +end + +function JuMP.set_objective_sense(node::OptiNode, sense::MOI.OptimizationSense) + d = JuMP.object_dictionary(node) + d[(node, :objective_sense)] = sense + return nothing +end + function JuMP.objective_function(node::OptiNode) return JuMP.object_dictionary(node)[(node, :objective_function)] end diff --git a/test/test_optigraph.jl b/test/test_optigraph.jl index 4e38629..df473c8 100644 --- a/test/test_optigraph.jl +++ b/test/test_optigraph.jl @@ -160,6 +160,12 @@ function test_objective_functions() @test objective_function(graph) == n1[:x] - n2[:x] + n3[:x][1]^2 + n3[:x][2]^2 + n4[:x]^2 + JuMP.set_objective_function(n1, n1[:y]) + JuMP.set_objective_sense(n1, MOI.MAX_SENSE) + set_to_node_objectives(graph) + @test objective_function(graph) == + -n1[:y] - n2[:x] + n3[:x][1]^2 + n3[:x][2]^2 + n4[:x]^2 + @objective(n4, Min, n4[:x]^3) set_to_node_objectives(graph) @test typeof(objective_function(graph)) == GenericNonlinearExpr{NodeVariableRef}