Wednesday, May 27, 2009

Convert GAMS to OML

A simple way to generate scalar OML from GAMS is to use the CONVERT “dummy” solver. Use an option file convert.opt with

sfs

E.g. for the model trnsport.gms from the GAMS model library we do:

> gams trnsport lp=convert optfile=1

This will show:

--- Job trnsport.gms Start 05/27/09 17:03:47 WEX-VIS 23.0.2 x86/MS Windows       
GAMS Rev 230  Copyright (C) 1987-2009 GAMS Development. All rights reserved
Licensee: Erwin Kalvelagen                               G090213/0001CV-WIN
          Amsterdam Optimization Modeling Group                      DC4572
--- Starting compilation
--- trnsport.gms(69) 3 Mb
--- Starting execution: elapsed 0:00:00.003
--- trnsport.gms(45) 4 Mb
--- Generating LP model transport
--- trnsport.gms(66) 4 Mb
---   6 rows  7 columns  19 non-zeroes
--- Executing CONVERT: elapsed 0:00:00.009

Convert 2.0      Feb 14, 2009 23.0.2 WIN 9388.9411 VIS x86/MS Windows        

--- Using Option File
Reading parameter(s) from "C:\projects\ms\convert.opt"
>>  sfs
>>
Finished reading from "C:\projects\ms\convert.opt"
--- Writing SFS       : sfs.oml

--- Restarting execution
--- trnsport.gms(66) 0 Mb
--- Reading solution for model transport
--- Executing after solve: elapsed 0:00:00.063
--- trnsport.gms(68) 3 Mb
*** Status: Normal completion
--- Job trnsport.gms Stop 05/27/09 17:03:47 elapsed 0:00:00.083

The output will look like:

//  LP written by GAMS Convert at 05/27/09 17:03:47
//
//  Equation counts
//      Total        E        G        L        N        X        C
//          6        1        3        2        0        0        0
//
//  Variable counts
//                   x        b        i      s1s      s2s       sc       si
//      Total     cont   binary  integer     sos1     sos2    scont     sint
//          7        7        0        0        0        0        0        0
//  FX      0        0        0        0        0        0        0        0
//
//  Nonzero counts
//      Total    const       NL      DLL
//         19       19        0        0
//
//  Reformulation has removed 1 variable and 1 equation

Model[
  Decisions[Reals[0, Infinity],x1],
  Decisions[Reals[0, Infinity],x2],
  Decisions[Reals[0, Infinity],x3],
  Decisions[Reals[0, Infinity],x4],
  Decisions[Reals[0, Infinity],x5],
  Decisions[Reals[0, Infinity],x6],

Goals[ Minimize[    0.225*x1 + 0.153*x2 + 0.162*x3 + 0.225*x4 + 0.162*x5 + 0.126*x6 ]],

Constraints[

e2 ->   x1 + x2 + x3 <= 350,

e3 ->   x4 + x5 + x6 <= 600,

e4 ->   x1 + x4 >= 325,

e5 ->   x2 + x5 >= 300,

e6 ->   x3 + x6 >= 275 ]]

This format is called “scalar” model opposed to an “indexed” model. I produced by hand the following “indexed” model, which is preferable if you need to maintain the model in OML or if large amounts of data needs to be imported from data sources:

Model[
  Parameters[Sets,Plants,Markets],
  Parameters[Reals,Capacity[Plants],Demand[Markets],Cost[Plants,Markets]],

  Decisions[Reals[0,Infinity],x[Plants,Markets],TotalCost],

  Constraints[
     TotalCost == Sum[{i,Plants},{j,Markets},Cost[i,j]*x[i,j]],
     Foreach[{i,Plants}, Sum[{j,Markets},x[i,j]]<=Capacity[i]],
     Foreach[{j,Markets}, Sum[{i,Plants},x[i,j]]>=Demand[j]]
  ],

  Goals[Minimize[TotalCost]]
]

The scalar model may be especially useful for experimentation and evaluation.

Notes: