-
Notifications
You must be signed in to change notification settings - Fork 25
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
Numerical differences between versions 0.7.0 and 0.8.4 #120
Comments
Yes.
It seems like you're terminating the solver after a limited number of iterations. There is no guarantee that the solver will find identical solutions as a function of the iteration number. If you have a situation where it finds different optimal solutions, that is worth investigating as a bug. |
Oscar,
Thanks for your quick reply.
If the underlying C-code has changed, that limits what the Julia community can do.
For now, we are advising our users that the public package interface has changed and that things are generally the same.
If the literally thousands of test cases I have run, I have only found a handful of examples where the optimized value is noticeably different.
Numerical fuzz knife-edge cases are problematic for our application, as they create a sort of butterfly effect where different LP results propagate to different simulation behavior in future periods.
However, we have seen this happen due to numerical fuzz differences in inputs, so it is something we have come to accept.
I notice that there has been some activity on the jump-dev/Clp.jl project, b+ut my version of Julia is still updating only to version v0.8.4 of Clp.
I have attached some files with test cases where v0.8.4 produces different objective values than v0.7.0.
The LP is finding an optimal solution in all cases.
The following script turns the *.csv data files into the inputs required for my decision_solver function.
The two interfaces (Decision_084.jl uses Clp 0.8.4 and Decision_070.jl uses Clp 0.7.0) are identical in terms of inputs and output.
Let me know if there is anything else I can do.
Thanks,
Kim
using DelimitedFiles
indata = readdlm("D:/SIMS/case_3_3.csv", ',')
lengths = [findfirst(x -> !isa(x,Number), indata[i,2:end]) for i in 1:first(size(indata))]
rows = lengths[1] - 1
cols = lengths[3] - 1
@Assert size(indata)[2] == 1 + rows*cols
obj = Vector{Float64}(indata[1, 2:rows+1])
a = Matrix{Float64}(reshape(indata[2, 2:end], (cols, rows)))
rhs = Vector{Float64}(indata[3, 2:cols+1])
lb = Vector{Float64}(indata[4, 2:rows+1])
ub = Vector{Float64}(indata[5, 2:rows+1])
maxiter = indata[6, 2]
maxtime = indata[7, 2]
(status, objval, sol) = decision_solver(obj, a, rhs, ub, lb, Int64(maxtime), Int64(maxiter))
From: Oscar Dowson ***@***.***>
Sent: Thursday, September 23, 2021 8:00 PM
To: jump-dev/Clp.jl ***@***.***>
Cc: Kim Balls ***@***.***>; Author ***@***.***>
Subject: Re: [jump-dev/Clp.jl] Numerical differences between versions 0.7.0 and 0.8.4 (#120)
Has the underlying COIN code changed?
Yes.
Sometimes the objective value is better, and sometimes worse.
It seems like you're terminating the solver after a limited number of iterations. There is no guarantee that the solver will find identical solutions as a function of the iteration number.
If you have a situation where it finds different optimal solutions, that is worth investigating as a bug.
-
You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub<https://nam02.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Fjump-dev%2FClp.jl%2Fissues%2F120%23issuecomment-926034288&data=04%7C01%7Ckim.balls%40conning.com%7C5ed70ae913c9466a4e3f08d97ebbf5ba%7Cadb6f4f040cd4c1696875893dcdf4f2a%7C1%7C0%7C637680168022696815%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&sdata=1EL%2BFHTOsrzTorg6hbXfjjM%2BlxMyTmNpXI2KifhKziA%3D&reserved=0>, or unsubscribe<https://nam02.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Fnotifications%2Funsubscribe-auth%2FACIHT2JTEKX7VG5A6UAOA4LUDNTJ5ANCNFSM5ETJCSWA&data=04%7C01%7Ckim.balls%40conning.com%7C5ed70ae913c9466a4e3f08d97ebbf5ba%7Cadb6f4f040cd4c1696875893dcdf4f2a%7C1%7C0%7C637680168022696815%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&sdata=gOTIbDbaAIkxOJsTHtrzJGIBRjwpF8TvCw68xxuWV3Q%3D&reserved=0>.
Triage notifications on the go with GitHub Mobile for iOS<https://nam02.safelinks.protection.outlook.com/?url=https%3A%2F%2Fapps.apple.com%2Fapp%2Fapple-store%2Fid1477376905%3Fct%3Dnotification-email%26mt%3D8%26pt%3D524675&data=04%7C01%7Ckim.balls%40conning.com%7C5ed70ae913c9466a4e3f08d97ebbf5ba%7Cadb6f4f040cd4c1696875893dcdf4f2a%7C1%7C0%7C637680168022706771%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&sdata=TbMGWn5D1qYr6oDdHBueznuoTFkW67TLIFl8ZbnBTHc%3D&reserved=0> or Android<https://nam02.safelinks.protection.outlook.com/?url=https%3A%2F%2Fplay.google.com%2Fstore%2Fapps%2Fdetails%3Fid%3Dcom.github.android%26referrer%3Dutm_campaign%253Dnotification-email%2526utm_medium%253Demail%2526utm_source%253Dgithub&data=04%7C01%7Ckim.balls%40conning.com%7C5ed70ae913c9466a4e3f08d97ebbf5ba%7Cadb6f4f040cd4c1696875893dcdf4f2a%7C1%7C0%7C637680168022706771%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&sdata=NfyHzZIaC%2Fb5MeJjo2iedsrrmQcN46x6zCkWShlwUmQ%3D&reserved=0>.
|
Github strips attachments if you reply via email so I can't run it. You should upload manually using the web interface. If you're finding different solutions due to a time out, this is expected. If you're finding different solutions with the same objective value, this is expected. If you're finding optimal solutions with different objective values and you did not set a time limit or iteration limit, this is not expected. |
Please provide a reproducible example. You can't attach files via email, this must be done via the web interface. |
I cannot reproduce this.
Oldusing MathProgBase # version v0.7.8
using Clp # version v0.7.0
using DelimitedFiles
indata = readdlm("case_3_3.csv", ',')
lengths = [findfirst(x -> !isa(x,Number), indata[i,2:end]) for i in 1:first(size(indata))]
rows = lengths[1] - 1
cols = lengths[3] - 1
@assert size(indata)[2] == 1 + rows*cols
obj = Vector{Float64}(indata[1, 2:rows+1])
a = Matrix{Float64}(reshape(indata[2, 2:end], (cols, rows)))
rhs = Vector{Float64}(indata[3, 2:cols+1])
lb = Vector{Float64}(indata[4, 2:rows+1])
ub = Vector{Float64}(indata[5, 2:rows+1])
maxiter = indata[6, 2]
maxtime = indata[7, 2]
sol = linprog(obj, a, '=', rhs, lb, ub, ClpSolver(MaximumIterations = maxiter, MaximumSeconds = maxtime, SolveType = 0))
julia> sol.objval
28048.98063242901
(cl2) pkg> st
Status `/private/tmp/cl2/Project.toml`
[e2554f3b] Clp v0.7.0
[fdba3010] MathProgBase v0.7.8 Newusing JuMP # version 0.21.10
using Clp # version 0.8.4
function decision_solver(
obj::Vector{Float64},
a::Matrix{Float64},
rhs::Vector{Float64},
ub::Vector{Float64},
lb::Vector{Float64},
maxtime::Int64,
maxiter::Int64)
model = Model(Clp.Optimizer);
@variable(model, lb[i] <= x[i=1:length(lb)] <= ub[i]);
@objective(model, Min, obj'x);
# Depending on the sense vector, you may need to split it into <= and >= constraints too
@constraint(model, a * x .== rhs);
# JuMP.set_optimizer_attribute(model, "LogLevel", 0)
JuMP.set_optimizer_attribute(model, "MaximumIterations", maxiter)
optimize!(model);
status = Symbol(lowercase(string(termination_status(model))))
@show status
if status in [:infeasible, :dual_infeasible]
JuMP.set_optimizer_attribute(model, "SolveType", 1)
optimize!(model);
status = Symbol(lowercase(string(termination_status(model))))
end
if status != :optimal
return (status, 0.0, Vector{Float64}())
end
sol = value.(x)
objval = objective_value(model)
return (status, objval, sol)
end
using DelimitedFiles
indata = readdlm("case_3_3.csv", ',')
lengths = [findfirst(x -> !isa(x,Number), indata[i,2:end]) for i in 1:first(size(indata))]
rows = lengths[1] - 1
cols = lengths[3] - 1
@assert size(indata)[2] == 1 + rows*cols
obj = Vector{Float64}(indata[1, 2:rows+1])
a = Matrix{Float64}(reshape(indata[2, 2:end], (cols, rows)))
rhs = Vector{Float64}(indata[3, 2:cols+1])
lb = Vector{Float64}(indata[4, 2:rows+1])
ub = Vector{Float64}(indata[5, 2:rows+1])
maxiter = indata[6, 2]
maxtime = indata[7, 2]
(status, objval, sol) = decision_solver(obj, a, rhs, ub, lb, Int64(maxtime), Int64(maxiter))
julia> objval
28048.98063242901
julia> objval
28048.98063242901
(cl) pkg> st
Status `/private/tmp/cl/Project.toml`
[e2554f3b] Clp v0.8.4
[4076af6c] JuMP v0.21.10 |
@s3baki any follow up to this? |
Closing as stale and unreproducible. @s3baki if you can reliably reproduce this on the latest version, please re-open. |
When we moved from Clp 0.7.0 to Clp 0.8.4, I had to completely rewrite my interface to Clp.
Before I was using a very simple
Now I use
I don't mind the extra work of setting up the model.
I write that once and done.
What I do mind is that I am getting different results.
In most cases it is just numerical fuzz, but at times the differences are more noticeable.
Sometimes the objective value is better, and sometimes worse.
My questions are the following:
Has the underlying COIN code changed?
If not, are there some hidden settings that have changed, which causes the underlying C-library to calculate differently?
I am happy to provide examples of both numerical fuzz and substantial differences.
I can be reached at [email protected].
Any insight you can give me will be highly appreciated.
The text was updated successfully, but these errors were encountered: