Giter VIP home page Giter VIP logo

gams.jl's Introduction

GAMS.jl

GAMS.jl provides a MathOptInterface Optimizer to solve JuMP models using GAMS.

GAMS comes with dozens of supported solvers. Among them are: ALPHAECP, ANTIGONE, BARON, CBC, CONOPT, CPLEX, DICOPT, GUROBI, IPOPT, KNITRO, LINDO, LINDOGLOBAL, MINOS, MOSEK, NLPEC, PATH, QUADMINOS, SBB, SHOT, SCIP, SNOPT, SOPLEX, XPRESS. Find a complete list here.

GAMS.jl supports the following JuMP features:

  • linear, quadratic and nonlinear (convex and non-convex) objective and constraints
  • continuous, binary, integer, semi-continuous and semi-integer variables
  • SOS1 and SOS2 sets
  • complementarity constraints

Installation

  1. Download GAMS and obtain a GAMS license. Please note that GAMS also offers a free community license.
  2. (optional) Add the GAMS system directory to the PATH variable in order to find GAMS automatically.
  3. Install GAMS.jl using the Julia package manager:
    using Pkg
    Pkg.add("GAMS")

Usage

Using GAMS as optimizer for your JuMP model:

using GAMS, JuMP
model = Model(GAMS.Optimizer)

GAMS System

If the GAMS system directory has been added to the PATH variable (you can check this with print(ENV["PATH"])), GAMS.jl will find it automatically. Otherwise, or if you like to switch between systems, the system directory can be specified by (one of the following):

set_optimizer_attribute(model, "SysDir", "<gams_system_dir>")
set_optimizer_attribute(model, GAMS.SysDir(), "<gams_system_dir>")

Analogously, you can specify a working directory with "WorkDir" or GAMS.WorkDir(). If no working directory has been set, GAMS.jl will create a temporary one.

If you want to use the same GAMS workspace (same system and working directory) for multiple models, you can create a GAMSWorkspace first with either of the following

ws = GAMS.GAMSWorkspace()
ws = GAMS.GAMSWorkspace("<gams_system_dir>")
ws = GAMS.GAMSWorkspace("<gams_system_dir>", "<gams_working_dir>")

and then pass it to your models:

model = Model(() -> GAMS.Optimizer(ws))

GAMS Options

GAMS command line options can be specified by

set_optimizer_attribute(model, "<option>", "<solver_name>")
set_optimizer_attribute(model, GAMS.<option>(), "<solver_name>")

where <option> is either HoldFixed, IterLim, License, LogOption, NodLim, OptCA, OptCR, ResLim, Solver, Threads, Trace, TraceOpt as well as LP, MIP, RMIP, NLP, DNLP, CNS, MINLP, RMINLP, QCP, MIQCP, RMIQCP, MCP or MPEC. Note that GAMS.ResLim() is equivalent to MOI.TimeLimitSec() and GAMS.Threads() to MOI.NumberOfThreads(). Options LimCol, LimRow, SolPrint and SolveLink cannot be changed and are set to 0, 0, 0 and 5, respectively.

Model Type

GAMS.jl will automatically choose a GAMS model type for you. Choosing a different model type:

set_optimizer_attribute(model, GAMS.ModelType(), "<model_type>")

GAMS Solver Options

Specifying GAMS solver options:

set_optimizer_attribute(model, "<solver_option_name>", <option_value>)

Note that passing a solver option is only valid when explicitly choosing a GAMS solver and not using the default.

GAMS Names vs. JuMP Names

GAMS uses generated variable and constraint names although it is possible to pass the JuMP names to the GAMS optimizer, because GAMS is more restrictive when it comes to variable and constraint naming. Use the attributes GeneratedVariableName, GeneratedConstraintName, OriginalVariableName, OriginalConstraintName to query a GAMS symbol name from a JuMP symbol and vice versa. This can help for debugging, for example in case of GAMS compilation errors. For example:

using GAMS

model = direct_model(GAMS.Optimizer())

@variable(model, x[1:2,1:3] >= 0)
@constraint(model, c[i = 1:2], sum(x[i,j] for j = 1:3) <= 10)

MOI.get(model, GAMS.GeneratedVariableName(), x[2,2]) # returns x4
MOI.get(model, GAMS.OriginalVariableName("x6"))      # returns x[2,3]
MOI.get(model, GAMS.OriginalVariableName("x10"))     # returns nothing

MOI.get(model, GAMS.GeneratedConstraintName(), c[2]) # returns eq2
MOI.get(model, GAMS.OriginalConstraintName("eq1"))   # returns c[1]
MOI.get(model, GAMS.OriginalConstraintName("eq10"))  # returns nothing

Note that JuMP direct-mode is used.

gams.jl's People

Contributors

mwirungu avatar renkekuhlmann avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

gams.jl's Issues

Input data rounded?

Hello,

first of all, thank you for providing this package allowing to call GAMS and its solvers from Julia. This is really helpful in integrating different solvers into a project.

Currently, I face the issue that some problem data seems to be rounded before the problem is solved in GAMS. It is clear to me that there is a limit on input precision (https://support.gams.com/gams:precision_of_data_within_gams), but I wonder if the rounding in my case is intended or a bug. Especially, since creating the same problem in GAMS Studio does not show this issue.

Here is a minimal working example:

using GAMS
using JuMP
using Gurobi
using MathOptInterface

m1 = JuMP.Model(GAMS.Optimizer)
JuMP.set_optimizer_attribute(m1, "Solver", "Gurobi")
JuMP.@variable(m1, x>=0)
JuMP.@objective(m1, MOI.MIN_SENSE, x)
JuMP.@constraint(m1, x >= 2257.812325)
JuMP.optimize!(m1)

m2 = JuMP.Model(Gurobi.Optimizer)
JuMP.@variable(m2, y>=0)
JuMP.@objective(m2, MOI.MIN_SENSE, y)
JuMP.@constraint(m2, y >= 2257.812325)

JuMP.optimize!(m2)

println()
println("Optimal point calling Gurobi via GAMS:")
println(JuMP.value(x))
println("Optimal point calling Gurobi directly:")
println(JuMP.value(y))

The console output is

Optimal point calling Gurobi via GAMS:
2257.81
Optimal point calling Gurobi directly:
2257.812325

As you can see, calling Gurobi directly provides the correct solution, which also modeling and solving the problem in GAMS Studio does.
Calling Gurobi via GAMS in Julia (which would be the preferred way within my project) gives a solution, though, which does not satisfy the constraint. This may be problematic if cutting planes are created iteratively within an algorithm.

This seems to be input and not output related, since the .gms-file created by gams.jl already contains the constraint in form

x >= 2257.81

only instead of the original form.

I use package version 0.1.4 for GAMS, 0.21.5 for JuMP and 0.9.19 for MathOptInterface.

Many thanks in advance.

slow on iterative solves

How can we pass the solvelink=5 option? This is useful a solution I am obtaining iteratively.

vscode: GAMS executable not found!

Hi all,

I am now running the example model using JuMP and GAMS.jl. When using the Julia REPL on vscode, there is an error GAMS executable not found! . So, then I try to set the absolute PATH for GAMS.jl like set_optimizer_attribute(model, "SysDir", /home/dais2/GAMS/gams34.2_linux_x64_64_sfx"). But it still does not work. Please find the error in the attached screenshot.

Screenshot from 2021-02-10 21-23-07

Interestingly, when running the same model through the terminal using julia test_gms.jl, I obtain the final estimation results.
Even when I run the code through the julia command terminal one-by-one, I can also get the results. Please note that I have defined GAMS PATH in the file .bashrc.

I would like to use the GAMS.jl in the vscode, so could you please give me some suggestions to fix this issue? Many thanks in advance!

ANTIGONE parameter file

When I specify a parameter for ANTIGONE (e.g. set_optimizer_attribute(model,"feas_tolerance", 1e-14)), I get the following error
*** Error Cannot open parameter file "/tmp/gams_jl_lOie8z/antigone.opt"
*** Error Error code = 2; No such file or directory
Is this error coming from my settings or the package.

Thanks!

MathOptInterface deprecated with some newer Julia packages

Hi, I'm trying to install GAMS.jl to access some solvers to use in JuMP along with NemoMod, which requires MathOptInterface 1.2+ (currently have 1.8.2, the latest, installed).

However, it appears as though GAMS.jl is restricted to using these versions: [0.9.13-0.9.22, 0.10.7-0.10.9].

Are there any plans to update the MathOptInterface requirements for GAMS? Is this possible to do?

Here's the error in Pkg.add("GAMS"):

Unsatisfiable requirements detected for package MathOptInterface [b8f27783]:
 MathOptInterface [b8f27783] log:
 ├─possible versions are: 0.5.0-1.8.2 or uninstalled
 ├─restricted to versions 1.2.0-1 by NemoMod [a3c327a0], leaving only versions 1.2.0-1.8.2
 │ └─NemoMod [a3c327a0] log:
 │   ├─possible versions are: 1.8.0 or uninstalled
 │   └─NemoMod [a3c327a0] is fixed to version 1.8.0
 └─restricted by compatibility requirements with GAMS [1ca51c6a] to versions: [0.9.13-0.9.22, 0.10.7-0.10.9] — no versions left
   └─GAMS [1ca51c6a] log:
     ├─possible versions are: 0.1.0-0.3.4 or uninstalled
     └─restricted to versions * by an explicit requirement, leaving only versions 0.1.0-0.3.4

HoldFixed causes value(<fixed_variable>) to return 0.0

A minor issue, but I thought I would report it in case it can be easily fixed or others stumble upon it.

To reproduce:

using JuMP
using GAMS

model = Model(GAMS.Optimizer)
set_optimizer_attribute(model, "HoldFixed", 1)
set_optimizer_attribute(model, GAMS.ModelType(), "CNS")

@variables model begin
    x
    y
end

@constraints model begin
    y == x
end

fix(x, 1.0)
optimize!(model)

@assert value(x) == value(y) "$(value(x)) == $(value(y))"

AssertionError: 0.0 == 1.0

set_optimizer_attribute(model, "HoldFixed", 0)
optimize!(model)
"$(value(x)) == $(value(y))"

"1.0 == 1.0"

is it possible to access dual/marginal variables

I was trying to access a dual variable by way of JuMP.dual(x). I could not and got the following.

ModelLike of type GAMS.Optimizer does not support accessing the attribute MathOptInterface.NLPBlockDual(1)

Parenthesis sometimes missing

Hi,

after the latest update, I sometimes get an error like this:

37  nlp_eq2.. sqr((2) * (x3) * (x3) + (-1.328171015325041) * (x3) + -2.076874228151837e-10) + sqr((+(-2.076874228151837e-10
****                                                                  $445
**** 445  More than one operator in a row. You need to use parenthesis
****        if you want to use such statements. For example
****            x := x + - not y;  ->  x := x + (- (not y));
****            sum(i$not x, ..)   ->  sum(i$(not x),..)

I assume that there is a small bug when writing from the Julia expression to the GAMS representation.
Double values maybe should always have parenthesis?

GAMS doesn't recognize "acos"

Hi,
GAMS.jl has a problem with 'acos'. In GAMS (as opposed to Julia-JuMP) it is called arccos. Might there be a translation problem?
See problem line:

    @NLexpression(DPVI, V̂[i=SN, j=Sdeg], coefs[j] * cos((j - 1) * acos(dz * (kPlus[i] - extkmin) - 1)) )

[FR] Accessing GDX files from Julia

Are you planning to release a tool, similar to gdxrrw in R? I know that you can access R packages by using RCall.jl. However, I would prefer a more direct data exchange between GAMS and Julia.

GeneratedConstraintName() for Non linear constraints

I need to find the name with which a Julia equation is set in GAMS on an NLP formulation. However, the GeneratedConstraintName() function does not work with the @NLconstraint object. Is there any other way to see how equations are named in GAMS?

Alternative License File

Currently, there is no option to pass the path of an alternative GAMS license file e.g. via a set_optimizer_attribute

Update to MOI 1.11

Can you update the combat to MOI 1.11? I have a conflict trying to add this to another project using JuMP

[Q]: which are the benefits of gams.jl over the standard solver calling?

hello,

it is not clear from the description which are the benefit of using this package over calling the solver directly. For instance, the transportation problem in the example can be solved by replacing

model = Model(GAMS.Optimizer)
   set_optimizer_attribute(model, MOI.Silent(), !verbose)

with
model=Model(Gurobi.Optimizer)

given that, i have a licensed version of Gurobi.

So, which are the benefits of the former over the latter approach

ANTIGONE parameter file

When I specify a parameter for ANTIGONE (e.g. set_optimizer_attribute(model,"feas_tolerance", 1e-14)), I get the following error
*** Error Cannot open parameter file "/tmp/gams_jl_lOie8z/antigone.opt"
*** Error Error code = 2; No such file or directory
Is this error coming from my settings or the package.

Thanks!

Support MOI.ScalarNonlinearFunction

Within jump-dev/JuMP.jl#3106, MathOptInteface has upgraded its support for nonlinear modeling.
A very nice feature is better support of "function tracing", which better supports building models programmatically.

I would be exited to use this feature with GAMS in Julia.

Perhaps you could take a look at the changes done to Baron.jl and see if it is easy to adapt this wrapper.

Add support of JuMP variable/constraint names on GAMS level

I am sending a JuMP model to CONOPT4 using GAMS.jl and get an error/warning:
** Error in Square System: A variable tries to exceed its bound.

This is perfectly familiar and I get more information by looking in the generated moi.lst file
to find out which variable is the culprit:

**** ERRORS/WARNINGS IN VARIABLE x382
1 error(s): The variable tries to exceed its bound.

Is there any way of identifying what “x382” refers to in the above?

miles.lubin on discourse suggested opening an issue since "JuMP does provide the capability to pass variable names down to the solver."

Variable index allocation problem for silent variables

Hi,

currently I observe some issues with the variable allocation using GAMS.jl.

It seems that variables which are added to a JuMP model, when solving this model via GAMS.jl are only considered in the corresponding GAMS model if they do actually appear in one of the constraints (or the objective).
While this may be intended to keep the GAMS models as small as possible, it seems to have some side effects on the index allocation. It seems that after solving the model, the variable values are not allocated to the original indices, but simply starting from one, without considering the "silent" variables, which have been omitted in GAMS.

Here is a minimal working example:

using GAMS
using JuMP

dual_vars = zeros(8)

approx_model = JuMP.Model(GAMS.Optimizer)
JuMP.set_optimizer_attribute(approx_model, "Solver", "Gurobi")

@variables approx_model begin
    θ
    x[1:length(dual_vars)]
end
JuMP.@objective(approx_model, JuMP.MOI.MAX_SENSE, θ)

JuMP.@constraint(
    approx_model,
    θ - 0.65 * x[3] + x[4] - x[5] + x[6] + x[7] <= 36
)

JuMP.optimize!(approx_model)
dual_vars .= value.(x)

At the last line, this yields "ERROR: LoadError: BoundsError: attempt to access 6-element Array{Float64,1} at index [7]".

If you look at the single outputs

println(JuMP.value(x[1]))
println(JuMP.value(x[2]))
println(JuMP.value(x[3]))
println(JuMP.value(x[4]))
println(JuMP.value(x[5]))
println(JuMP.value(x[6]))
println(JuMP.value(x[7]))
println(JuMP.value(x[8]))

you get

1.0
0.0
0.0
0.0
0.0
ERROR: LoadError: BoundsError: attempt to access 6-element Array{Float64,1} at index [7]

so it looks like the values of the variables x[3], x[4], x[5], x[6], x[7] appearing in the constraints are allocated to x[1] to x[5] now and for the silent variables no values are returned at all.

A bit more background where this issue occurs:

I try to apply a cutting-plane method to solve a Lagrangian dual problem (as for SDDiP in SDDP.jl), solving all subproblems using GAMS.jl.
The dimension of the dual variables is determined right in the beginning. Let's say it's 8 as in the MWE, so 8 dual variables are added to the approx_model, which is then iteratively extended by cuts.

Now, if by solving the Lagrangian relaxation we obtain a subgradient with some 0 components in the first iteration, a cut is constructed, that contains only some of the dual variables. Solving approx_model considers only those variables then.

Updating dual_vars with the obtained dual solution yields the described error.

Many thanks in advance for having a look at this.

JuMP.direct_model does not work with GAMS.Optimizer()

Using direct_model with GAMS.Optimizer as shown in the README throws an error:

using JuMP
using GAMS
model = direct_model(GAMS.Optimizer())
Error showing value of type Model:
ERROR: ArgumentError: GAMS.Optimizer does not support getting the attribute MathOptInterface.Name().

I am running the latest versions of both JuMP and GAMS:
GAMS v0.3.2
JuMP v0.22.3

Constraint Conflict Resolution or .gms file

It currently appears as if conflict resolution of constraints (e.g., using compute_conflict! is not supported even though the connected GAMS solver (like BARON) supports it. Is it possible to set up such an option or alternatively print out a .gms file such that we can do it manually?

Question: using PATH through GAMS

I have been hoping that something like this is developed. Great work!

But how does one use the PATH solver here. For example to solve the following simple problem:

x >=    0
2x - 1 ⟂ x

Unable to Pass 'Equilibrium' Keyword to Solver in GAMS.jl for Equilibrium Problem

Problem

I am trying to solve an equilibrium problem using the GAMS/EMP with GAMS.jl in Julia. I am encountering an issue where I am unable to pass the 'Equilibrium' keyword to the solver.

Environment

  • Julia version: 1.9.0
  • GAMS.jl version: 0.4.2
  • Operating System: macOS Sonoma

Expected Behavior

I expect to be able to specify the 'Equilibrium' keyword either within the GAMS model file or via the GAMS.jl interface to inform the solver that it should handle the problem as an equilibrium problem.

Add an external option file

Hi,

Is it possible to add an external option file (e.g., conopt.opt) in gams.jl by using the command set_optimizer_attribute or directly pass the options as we did in GAMS, e.g.,

$onecho > conopt.opt
lspret = false
$offecho

gmsmodel.optfile = 1;
Solve gmsmodel using [...];

Thanks!

User Model Type not used

Some of my models might contain the "abs" function.
Before, GAMS would complain that I did not specify "DNLP", so I would just set the model type to "MINLP" (since I want to solve with Baron anyways).

set_optimizer_attribute(model, GAMS.ModelType(), "MINLP")

In the latest 0.4.3 version, this still worked, but it seems to be ignored in the 0.5 versions.
Thus, even after setting the problem type as shown above, "NLP" is written to the .gms file.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.