Search code examples
amplglpkmathprog

Column it's not supposed to look at is 'out of domain'


I get the following out-of-domain error, see below. The thing is, in the referred line, q comes out of the Qualities set, which does not even contain the LAT value. How can I prevent this from happening, and keep all my data in one table? I've been trying to work around it using the separate latdata table, but this looks ugly and redundant to me.

$ glpsol -m ron.mod
GLPSOL: GLPK LP/MIP Solver, v4.60
Parameter(s) specified in the command line:
 -m ron.mod
Reading model section from ron.mod...
Reading data section from ron.mod...
86 lines were read
Generating req...
ron.mod:20: cannot convert LAT to floating-point number
MathProg model processing error
MacBook-Air-van-Ron:examples raarts$ glpsol -m ron.mod
GLPSOL: GLPK LP/MIP Solver, v4.60
Parameter(s) specified in the command line:
 -m ron.mod
Reading model section from ron.mod...
Reading data section from ron.mod...
86 lines were read
Generating req...
ron.mod:20: data[DO_MINI,LAT] out of domain
MathProg model processing error

the source for ron.mod is below:

set AllProducts;
/* all products */

set Qualities;
/* minrequired */

param data{prod in AllProducts, {"price"} union Qualities};

param latdata{prod in AllProducts, "LAT"};
param maxallowed{"LAT"};

set Product := setof{ prod in AllProducts: latdata[prod, "LAT"] <= maxallowed["LAT"]} prod;

param minrequired{q in Qualities};

var x{p in Product}, integer, >= 0;

subject to req{q in Qualities}: sum{p in Product} data[p,q] * x[p] >= minrequired[q];

minimize cost: sum{p in Product} x[p] * data[p, "price"];

solve;

printf "aantal product         CPU   RAM    DISK  PR/STUK   TOTAAL\n";
printf{p in Product: x[p] != 0} "%6d %-12s %6d %6d %6d %8.2f %8.2f\n", x[p], p, data[p,"CPU"] * x[p], data[p,"RAM"] * x[p], data[p,"DISK"] * x[p],data[p,"price"], data[p,"price"] * x[p];
printf                    "%6s %-12s %6d %6d %6d %8.2s %8.2f\n", "", "", sum{p in Product} data[p,"CPU"] * x[p], sum{p in Product} data[p,"RAM"] * x[p], sum{p in Product} data[p,"DISK"] * x[p], "", sum{p in Product} data[p,"price"] * x[p];

data;

param data :    price  CPU     RAM     DISK    LAT :=
DO_MINI        5.00    1      512      20       2 
DO_SMALL      10.00    2     1024      30       2
DO_MEDIUM     15.00    2     2048      40       2
DO_LARGE      25.00    3     4096      75       2
SW_MINI        5.00    1     1024      10       3 
SW_SMALL      10.00    2     1024      15       3
SW_MEDIUM     15.00    2     2048      25       3
SW_LARGE      25.00    3     4096      50       3
BP_LARGE       5.00    3     4096      50       20
;

param latdata : LAT :=
DO_MINI         2  
DO_SMALL        2
DO_MEDIUM       2
DO_LARGE        2
SW_MINI         3  
SW_SMALL        3
SW_MEDIUM       3
SW_LARGE        3
BP_LARGE        20 
;

set AllProducts :=
DO_MINI   
DO_SMALL  
DO_MEDIUM 
DO_LARGE  
SW_MINI   
SW_SMALL  
SW_MEDIUM 
SW_LARGE  
BP_LARGE  
;

param minrequired :=
CPU                15
RAM             64000
DISK             1250
;

param maxallowed :=
LAT                 5
;

set Qualities :=
CPU
RAM
DISK
;

end;

Solution

  • You can keep all the data in one table by allowing "LAT" in the data parameter:

    param data{prod in AllProducts, {"price", "LAT"} union Qualities};
    

    Then latdata can simply copy the LAT data from it:

    param latdata{prod in AllProducts} = data[prod, "LAT"];
    

    This will solve the out of domain error because ('DO_MINI', 'LAT') will be in the indexing set of data making this data statement valid:

    param data :    price  CPU     RAM     DISK    LAT :=
    DO_MINI        5.00    1      512      20       2  # <- data[DO_MINI, LAT]
    ...