Skip to content

Commit

Permalink
Transition to MOI (#107)
Browse files Browse the repository at this point in the history
Co-authored-by: iManGHD <[email protected]>
  • Loading branch information
mtefagh and iManGHD authored Jul 9, 2022
1 parent d4f3afb commit 5dcab63
Show file tree
Hide file tree
Showing 5 changed files with 117 additions and 35 deletions.
11 changes: 4 additions & 7 deletions Project.toml
Original file line number Diff line number Diff line change
@@ -1,38 +1,35 @@
name = "COBRA"
uuid = "58298e0b-d05c-52ec-a210-0694647ebfc7"
version = "0.4.1"
version = "0.4.2"

[deps]
CPLEX = "a076750e-1247-5638-91d2-ce28b192dca0"
Distributed = "8ba89e20-285c-5b6f-9357-94700520ee1b"
GLPK = "60bf3e95-4087-53dc-ae20-288a0d20c6a6"
GLPKMathProgInterface = "3c7084bd-78ad-589a-b5bb-dbd673274bea"
HTTP = "cd3eb016-35fb-5094-929b-558a96fad6f3"
LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
MAT = "23992714-dd62-5051-b70f-ba57cb901cac"
MathOptInterface = "b8f27783-ece8-5eb3-8dc8-9495eed66fee"
MathProgBase = "fdba3010-5040-5b88-9595-932c9decdf73"
Pkg = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f"
SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf"
JuMP = "4076af6c-e467-56ae-b986-b466b2749572"

[compat]
CPLEX = "0.9"
GLPK = "1.0"
GLPKMathProgInterface = "0.5"
HTTP = "0.9"
MAT = "0.10"
MathOptInterface = "0.10, 1.1"
MathProgBase = "0.7"
julia = "1"
JuMP = "1.0"

[extras]
CPLEX = "a076750e-1247-5638-91d2-ce28b192dca0"
GLPK = "60bf3e95-4087-53dc-ae20-288a0d20c6a6"
GLPKMathProgInterface = "3c7084bd-78ad-589a-b5bb-dbd673274bea"
Gurobi = "2e9cd046-0924-5485-92f1-d5272153d98b"
MAT = "23992714-dd62-5051-b70f-ba57cb901cac"
MATLAB = "10e44e05-a98a-55b3-a45b-ba969058deb6"
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"

[targets]
test = ["GLPKMathProgInterface", "GLPK", "Test"]
test = ["GLPK", "Test"]
2 changes: 1 addition & 1 deletion src/COBRA.jl
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ module COBRA
# include the load file to load a model of .mat format
import Pkg
using SparseArrays, Distributed, LinearAlgebra
using MAT, MathProgBase
using MAT, MathOptInterface, JuMP
if "MATLAB" in keys(Pkg.installed())
using MATLAB
end
Expand Down
2 changes: 1 addition & 1 deletion src/connect.jl
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ function createPool(localWorkers::Int, connectSSH::Bool=false, connectionFile::S
end

try
if !is_windows()
if !(Sys.iswindows())
# try logging in quietly to defined node using SSH
successConnect = success(`ssh -T -o BatchMode=yes -o ConnectTimeout=1 $(sshWorkers[i]["usernode"]) $(sshWorkers[i]["flags"])`)

Expand Down
9 changes: 4 additions & 5 deletions src/distributedFBA.jl
Original file line number Diff line number Diff line change
Expand Up @@ -74,14 +74,14 @@ function preFBA!(model, solver, optPercentage::Float64=0.0, osenseStr::String="m
hasObjective = true

# solve the original LP problem
fbaSolution = solveCobraLP(model, solver)
status, objval, sol = solveCobraLP(model, solver)

if fbaSolution.status == :Optimal
if status == MathOptInterface.TerminationStatusCode(1)
# retrieve the solution to the initial LP
FBAobj = fbaSolution.objval
FBAobj = objval

# retrieve the solution vector
fbaSol = fbaSolution.sol
fbaSol = sol

if osenseStr == "max"
objValue = floor(FBAobj/tol) * tol * optPercentage / 100.0
Expand Down Expand Up @@ -124,7 +124,6 @@ function preFBA!(model, solver, optPercentage::Float64=0.0, osenseStr::String="m
end

end

#-------------------------------------------------------------------------------------------
"""
splitRange(model, rxnsList, nWorkers, strategy, printLevel)
Expand Down
128 changes: 107 additions & 21 deletions src/solve.jl
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
=#

#-------------------------------------------------------------------------------------------

"""
SolverConfig(name, handle)
Expand All @@ -22,10 +23,90 @@ mutable struct SolverConfig
end

#-------------------------------------------------------------------------------------------

"""
buildlp(c, A, sense, b, l, u, solver)
Function used to build a model using JuMP.
# INPUTS
- `c`: The objective vector, always in the sense of minimization
- `A`: Constraint matrix
- `sense`: Vector of constraint sense characters '<', '=', and '>'
- `b`: Right-hand side vector
- `l`: Vector of lower bounds on the variables
- `u`: Vector of upper bounds on the variables
- `solver`: A `::SolverConfig` object that contains a valid `handle`to the solver
# OUTPUTS
- `model`: An `::LPproblem` object that has been built using the JuMP.
- `x`: Primal solution vector
# EXAMPLES
```julia
julia> model, x = buildlp(c, A, sense, b, l, u, solver)
```
"""

function buildlp(c, A, sense, b, l, u, solver)
N = length(c)
model = Model(solver)
x = @variable(model, l[i] <= x[i=1:N] <= u[i])
@objective(model, Min, c' * x)
eq_rows, ge_rows, le_rows = sense .== '=', sense .== '>', sense .== '<'
@constraint(model, A[eq_rows, :] * x .== b[eq_rows])
@constraint(model, A[ge_rows, :] * x .>= b[ge_rows])
@constraint(model, A[le_rows, :] * x .<= b[le_rows])
return model, x
end

#-------------------------------------------------------------------------------------------

"""
solvelp(model, x)
Function used to solve a LPproblem using JuMP.
# INPUTS
- `model`: An `::LPproblem` object that has been built using the JuMP.
- `x`: Primal solution vector
# OUTPUTS
- `status`: Termination status
- `objval`: Optimal objective value
- `sol`: Primal solution vector
# EXAMPLES
```julia
julia> status, objval, sol = solvelp(model, x)
```
"""

function solvelp(model, x)
#println(x)
optimize!(model)
return (
status = termination_status(model),
objval = objective_value(model),
sol = value.(x)
)
end

#-------------------------------------------------------------------------------------------


"""
buildCobraLP(model, solver)
Build a model by interfacing directly with the CPLEX solver
Build a model by interfacing directly with the GLPK solver
# INPUTS
Expand All @@ -35,15 +116,16 @@ Build a model by interfacing directly with the CPLEX solver
# OUTPUTS
- `m`: A MathProgBase.LinearQuadraticModel object with `inner` field
- `model`: An `::LPproblem` object that has been built using the JuMP.
- `x`: primal solution vector
# EXAMPLES
```julia
julia> m = buildCobraLP(model, solver)
julia> model, x = buildCobraLP(model, solver)
```
See also: `MathProgBase.LinearQuadraticModel()`, `MathProgBase.HighLevelInterface.buildlp()`
See also: `buildlp()`
"""

function buildCobraLP(model, solver::SolverConfig)
Expand All @@ -55,8 +137,7 @@ function buildCobraLP(model, solver::SolverConfig)
if model.csense[i] == 'G' model.csense[i] = '>' end
if model.csense[i] == 'L' model.csense[i] = '<' end
end

return MathProgBase.HighLevelInterface.buildlp(model.osense * model.c, model.S, model.csense, model.b, model.lb, model.ub, solver.handle)
return buildlp(model.osense * model.c, model.S, model.csense, model.b, model.lb, model.ub, solver.handle)
else
error("The solver is not supported. Please set solver name to one the supported solvers.")
end
Expand Down Expand Up @@ -89,7 +170,12 @@ Minimum working example (for the CPLEX solver)
julia> changeCobraSolver("CPLEX", cpxControl)
```
See also: `MathProgBase.jl`
Minimum working example (for the GLPK solver)
```julia
julia> solverName = :GLPK
julia> solver = changeCobraSolver(solverName)
```
"""

function changeCobraSolver(name, params=[]; printLevel::Int=1)
Expand All @@ -113,12 +199,12 @@ function changeCobraSolver(name, params=[]; printLevel::Int=1)
error("The solver `CPLEX` cannot be set using `changeCobraSolver()`.")
end

elseif name == "GLPKMathProgInterface" || name == "GLPK"
elseif name == "GLPK"
try
if length(params) > 1
solver.handle = GLPKSolverLP(method=params[1], presolve=params[2])
solver.handle = GLPK.Optimizer
else
solver.handle = GLPKSolverLP()
solver.handle = GLPK.Optimizer
end
catch
error("The solver `GLPK` or `GLPKMathProgInterface` cannot be set using `changeCobraSolver()`.")
Expand Down Expand Up @@ -188,33 +274,33 @@ LP problem must have the form:
# OUTPUTS
- `solutionLP`: Solution object of type `LPproblem`
- `status`: Termination status
- `objval`: Optimal objective value
- `sol`: Primal solution vector
# EXAMPLES
Minimum working example
```julia
julia> solveCobraLP(model, solver)
julia> status, objval, sol = solveCobraLP(model, solver)
```
See also: `MathProgBase.linprog()`,
See also: `solvelp()`,
"""

function solveCobraLP(model, solver)

if solver.handle != -1

# retrieve the solution
m = buildCobraLP(model, solver)
solutionLP = MathProgBase.HighLevelInterface.solvelp(m)
m, x = buildCobraLP(model, solver)
status, objval, sol = solvelp(m, x)

# adapt the objective value
if solutionLP.status == :Optimal
solutionLP.objval = model.osense * solutionLP.objval
if status == :Optimal
objval = model.osense * objval
end

return solutionLP

return status, objval, sol
else
error("The solver handle is not set properly using `changeCobraSolver()`.")
end
Expand Down Expand Up @@ -256,6 +342,6 @@ function autoTuneSolver(m, nMets, nRxns, solver, pid::Int=1)
end
end

export buildCobraLP, changeCobraSolver, solveCobraLP, autoTuneSolver
export buildlp, solvelp, buildCobraLP, changeCobraSolver, solveCobraLP, autoTuneSolver

#-------------------------------------------------------------------------------------------

0 comments on commit 5dcab63

Please sign in to comment.