3
$\begingroup$

I looked at the GAMS python API but the documentation only describing already predefined models (run .gms with some tweaking options). My question is now: Can I somehow build a gams model from scratch with data I have imported in python. When I worked with gurobi everything seemed easy, but my professor forces me to use Gams... It seems to me GAMS is only good for hardcoding and doesn't give me a lot of flexibility.

Advice?

I found this, but it just looks like it inserts the whole model in a string with the GAMS syntax...

from gams import *
 import os
 import sys
  
 def get_data_text():
     return '''
   Sets
        i   canning plants   / seattle, san-diego /
        j   markets          / new-york, chicago, topeka / ;
  
   Parameters
  
        a(i)  capacity of plant i in cases
          /    seattle     350
               san-diego   600  /
  
        b(j)  demand at market j in cases
          /    new-york    325
               chicago     300
               topeka      275  / ;
  
   Table d(i,j)  distance in thousands of miles
                     new-york       chicago      topeka
       seattle          2.5           1.7          1.8
       san-diego        2.5           1.8          1.4  ;
  
   Scalar f  freight in dollars per case per thousand miles  /90/ ; '''
  
 def get_model_text():
     return '''
   Sets
        i   canning plants
        j   markets
  
   Parameters
        a(i)   capacity of plant i in cases
        b(j)   demand at market j in cases
        d(i,j) distance in thousands of miles
   Scalar f  freight in dollars per case per thousand miles;
  
 $if not set gdxincname $abort 'no include file name for data file provided'
 $gdxin %gdxincname%
 $load i j a b d f
 $gdxin
  
   Parameter c(i,j)  transport cost in thousands of dollars per case ;
  
             c(i,j) = f * d(i,j) / 1000 ;
  
   Variables
        x(i,j)  shipment quantities in cases
        z       total transportation costs in thousands of dollars ;
  
   Positive Variable x ;
  
   Equations
        cost        define objective function
        supply(i)   observe supply limit at plant i
        demand(j)   satisfy demand at market j ;
  
   cost ..        z  =e=  sum((i,j), c(i,j)*x(i,j)) ;
  
   supply(i) ..   sum(j, x(i,j))  =l=  a(i) ;
  
   demand(j) ..   sum(i, x(i,j))  =g=  b(j) ;
  
   Model transport /all/ ;
  
   Solve transport using lp minimizing z ;
  
   Display x.l, x.m ; '''
  
  
 if __name__ == "__main__":
     if len(sys.argv) > 1:
         ws = GamsWorkspace(system_directory = sys.argv[1])
     else:
         ws = GamsWorkspace()
  
     t3 = ws.add_job_from_string(get_data_text())
     t3.run()
     t3.out_db.export(os.path.join(ws.working_directory, "tdata.gdx"))
     t3 = ws.add_job_from_string(get_model_text())
  
     opt = ws.add_options()
     opt.defines["gdxincname"] = "tdata"
     opt.all_model_types = "xpress"
     t3.run(opt)
     for rec in t3.out_db["x"]:
         print("x(" + rec.key(0) + "," + rec.key(1) + "): level=" + str(rec.level) + " marginal=" + str(rec.marginal))
  
     t3a = ws.add_job_from_string(get_data_text())
     t3b = ws.add_job_from_string(get_model_text())
     t3a.run()
     opt.defines["gdxincname"] = t3a.out_db.name
     t3b.run(opt, databases=t3a.out_db)
     for rec in t3b.out_db["x"]:
         print("x(" + rec.key(0) + "," + rec.key(1) + "): level=" + str(rec.level) + " marginal=" + str(rec.marginal))
```
$\endgroup$

1 Answer 1

4
$\begingroup$

Unfortunately, GAMS does not have an independent low-level API language (such as CPLEX or Gurobi) and you will need to use its high-level language into your favourite API. In the simplest form, you can write your optimization problem in the gams file (.gms) and invoke it in python as follows:

# transport1 example in the gams directory
from __future__ import print_function
from gams import *
import os
import sys


if __name__ == "__main__":
    if len(sys.argv) > 1:
        ws = GamsWorkspace(system_directory = sys.argv[1])
    else:
        ws = GamsWorkspace()

    ws.gamslib("trnsport")
    
    t1 = ws.add_job_from_file("trnsport.gms")
    t1.run()
    print("Ran with Default:")

    for rec in t1.out_db["x"]:
        print("x(" + rec.key(0) + "," + rec.key(1) + "): level=" + str(rec.level) + " marginal=" + str(rec.marginal))
    
    opt = ws.add_options()
    opt.all_model_types = "xpress"
    t1.run(opt)

If you would like to write and modify your code simultaneously, you will have to follow up the mentioned template. (e.g. see transport6 example in the gams directory).

Please noted that, GAMS (from ver. 25) has a studio platform with lots of features that would be interested if you do not have any force to use a low-level API.

$\endgroup$
2
  • $\begingroup$ yes i am playing around with GAMS studio but its mainly for hardcoding. Can u explain what the difference between high and low-level api is? Then there is the question: Whats most convinient way to generate problem instances for gams... my idea was to use python-string manipulation and just make a massive string with everything in it, but it is tedious ... $\endgroup$
    – Eddiee
    Nov 7, 2020 at 15:15
  • $\begingroup$ @DerEddie, A high-level language looks like GAMS syntax, AMPL, OPL, etc. but a low-level language is specific libraries and its functions/methods which write with a programming language like python. I believe that and agree with you in which GAMS API is a bit tedious VS some of the other platforms/solver that you mentioned. However, if you need more details, you can contact with GAMS support team. :) $\endgroup$
    – A.Omidi
    Nov 7, 2020 at 18:44

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.