Tuesday, June 2, 2009

Using awk from GAMS to split set elements

I have a set with

ARG_BT_EX
ARG_BT_IM
ARG_BT_NT
ARG_BT_QC

Now I want to extract from this three sets: Country (ARG), Commodity (BT) and Other (EX,..).

This can be done easily with AWK:

$onecho > baseset.inc
ARG_BT_EX
ARG_BT_IM
ARG_BT_NT
ARG_BT_QC
ARG_BT_QP
$offecho

$onecho > gen.awk
BEGIN{
  FS="_"
}
{
  print $0 "." $1 "." $2 "." $3
}
$offecho

$call awk.exe -f gen.awk baseset.inc > extset.inc

set i(*) /
$include baseset.inc
/;

set imap(i,*,*,*) /
$include extset.inc
/;

alias (*,s1,s2,s3);

set country(*);
set commodity(*);
set other(*);

loop(imap(i,s1,s2,s3),
  country(s1) = yes;
  commodity(s2) = yes;
  other(s3) = yes;
);

execute_unload "sets.gdx",imap,i,country,commodity,other;

The AWK script will generate the mapping set imap:

ARG_BT_EX.ARG.BT.EX
ARG_BT_IM.ARG.BT.IM
ARG_BT_NT.ARG.BT.NT
ARG_BT_QC.ARG.BT.QC
ARG_BT_QP.ARG.BT.QP

while the rest of the GAMS code will extract the individual sets from this compound set.

AWK is included in the Windows versions of GAMS.

3 comments:

  1. Hi! First of all, i'm deeply sorry to bother you through your blog, but right know it seems like you are one of my last chances to end my master thesis...

    I'm programing in gams and i have a problem with one of the restrictions. To be precise, i will show you that part of the code:

    ENT(T).. SUM((I,K),(E(T,I)*X(I,K))/CARD(K)) = Z(T);

    ENTL(T).. LZ(T) =E= -Log(Z(T));

    In this program, E(T,I) is a parameter that only contains binary values, and X(I,K), Z(T) and LZ(T) are variables. X(I,K) contains binary values too, and Z(T) takes values between [0,1].

    As you must already see, there is a log function that is sendind error to the solver because in some cases Z(T) is 0 and log is undefined. I have tried everything to pass this gap, but it has been impossible to find an answer. First, i've been trying with conditions, with codes like LZ(T)$(Z.l(T) ne 0) and stuff likes that, but the program says that there's an error and that it won't compile. I even fixed the lower limit for Z(T) in 0.00000001, but despite the program compiles, the solution is not correct cause i'm fixing that Z(T) must be always greater than 0, think that's not true.

    I don't know what to do since GAMS doesn't support conditions on variables. How do you solve this case? How do you put a condition in a log with a variable inside?

    PLEASE ERWIN SAVE MY SOUL!!! Hahaha...

    Sorry again for using this space to ask for help, but i'm truly desperate.

    If you could answer me at takaoka@gmail.com, i would be eternally grateful.

    Excuse my english, i'm from Chile, an spanish-speaking country.

    Greetings,
    Tadashi Takaoka
    Industrial Engineer

    ReplyDelete
  2. The log of 0 is not defined, even in Chile. May be use something like -Log(Z(t)+0.0001). For GAMS help the best place to get support is support@gams.com.

    ReplyDelete
  3. Hahaha, even in Chile...

    I'm aware of that, that's why i was asking. The solution is good!!! Thanks!!!

    ReplyDelete