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;
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]
...