-
-
Notifications
You must be signed in to change notification settings - Fork 393
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add solution_summary
function
#2512
Conversation
Codecov Report
@@ Coverage Diff @@
## master #2512 +/- ##
==========================================
+ Coverage 92.42% 93.69% +1.26%
==========================================
Files 43 43
Lines 4688 5313 +625
==========================================
+ Hits 4333 4978 +645
+ Misses 355 335 -20
Continue to review full report at Codecov.
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks! A few comments, but this looks nice.
Thank you for reviewing. I think I addressed all of your comments and CI was fixed. PTAL. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for working on this. I think it will make a great addition.
A couple of very minor things, and one more substantial point about whether we should print values in verbose
mode if they have empty names.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks! I added one thing to only print the variable if the name is non-empty.
Assuming I didn't make a typo, I'll merge this once CI passes.
Actually, I have one more thing to bikeshed. I know we have |
I think many Julia codes use |
Maybe |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
+1 to @blegat's struct proposal. Having a solution_summary
doesn't force us to have other summary structs any more than show_solution_summary
forces us to have other show_XXX_summary
.
show_solution_summary
functionsolution_summary
function
@mlubin Thank you for your comment. I understood. I used struct. PTAL. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@blegat, I don't really understand the motivation for returning a struct just to overload show
. solution_summary
just prints things.
If we were to return a struct, it should have accessible fields with all the data.
struct SolutionSummary
solver::String
# Status
termination_status::MOI.TerminationStatusCode
primal_status::MOI.ResultStatusCode
dual_status::MOI.ResultStatusCode
raw_status::String
result_count::Int
has_values::Bool
has_duals::Bool
# Candidate solution
objective_value::Float64
objective_bound::Float64
dual_objective_value::Float64
primal_solution::Dict{String,Float64}
dual_solution::Dict{String,Float64}
# Work counters
solve_time::Float64
barrier_iterations::Union{Missing,Int}
simplex_iterations::Union{Missing,Int}
node_count::Union{Missing,Int}
end
Then it makes sense to overload show
on that.
Agreed, no need to defer computation to when it's printed so we might as well store them in a struct. |
src/print.jl
Outdated
has_duals(model), | ||
objective_value(model), | ||
_try_get(objective_bound, model), | ||
_try_get(dual_objective_value, model), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should have an array here with one entry for i in 1:result_count
that contains a struct containing the objective value, solution and dual solution, dual objective value, primal status, dual status, ...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you have an example code which has result_count is 2 or more? I would like to add a test using it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I found this codes. Maybe I can use it.
JuMP.jl/test/generate_and_solve.jl
Lines 601 to 638 in 90e63c4
@testset "ResultCount" begin | |
m = Model() | |
@variable(m, x >= 0.0) | |
@variable(m, y >= 0.0) | |
@objective(m, Max, x + y) | |
@constraint(m, c1, x <= 2) | |
@constraint(m, c2, x + y <= 1) | |
model = MOIU.Model{Float64}() | |
MOIU.loadfromstring!( | |
model, | |
""" | |
variables: x, y | |
maxobjective: x + y | |
xub: x >= 0.0 | |
ylb: y >= 0.0 | |
c1: x <= 2.0 | |
c2: x + y <= 1.0 | |
""", | |
) | |
set_optimizer( | |
m, | |
() -> MOIU.MockOptimizer( | |
MOIU.Model{Float64}(), | |
eval_objective_value = false, | |
), | |
) | |
JuMP.optimize!(m) | |
mock = JuMP.backend(m).optimizer.model | |
MOI.set(mock, MOI.TerminationStatus(), MOI.OPTIMAL) | |
MOI.set(mock, MOI.ResultCount(), 2) | |
aff_expr = @expression(m, x + y) | |
quad_expr = @expression(m, x * y) | |
nl_expr = @NLexpression(m, log(x + y)) | |
@test JuMP.result_count(m) == 2 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's just leave this as-is for now. It covers 99.9% of peoples use-cases, and I'm mindful that @AtsushiSakai has put a lot of effort in, and we keep asking for more and more changes.
In future, we could add a alternative_solutions::Vector
that is backward compatible. The first result is special as it is the only solution guaranteed to be optimal if TerminationStatus
is optimal.
Thanks @AtsushiSakai. It's a very nice contribution. |
Hi. First of all, thank you for developing great OSS!! JuMP is one of the greatest OSS I've ever used : ).
I am +1 for #2191, I think solution summary report is very helpful for checking optimization results briefly.
So, I added
show_solution_summary
function to fix #2191 based on the comment( #2191 (comment)).I also added tests and docs, and updated manual.
This is the first time for me to contribute JuMP, so any kind of feedback is welcome.