File: gmpl_es.tex

package info (click to toggle)
glpk 5.0-1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm, bullseye, sid, trixie
  • size: 11,608 kB
  • sloc: ansic: 78,038; sh: 11,184; fortran: 207; makefile: 205; sql: 142; cs: 83
file content (3231 lines) | stat: -rw-r--r-- 162,959 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
2739
2740
2741
2742
2743
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
2902
2903
2904
2905
2906
2907
2908
2909
2910
2911
2912
2913
2914
2915
2916
2917
2918
2919
2920
2921
2922
2923
2924
2925
2926
2927
2928
2929
2930
2931
2932
2933
2934
2935
2936
2937
2938
2939
2940
2941
2942
2943
2944
2945
2946
2947
2948
2949
2950
2951
2952
2953
2954
2955
2956
2957
2958
2959
2960
2961
2962
2963
2964
2965
2966
2967
2968
2969
2970
2971
2972
2973
2974
2975
2976
2977
2978
2979
2980
2981
2982
2983
2984
2985
2986
2987
2988
2989
2990
2991
2992
2993
2994
2995
2996
2997
2998
2999
3000
3001
3002
3003
3004
3005
3006
3007
3008
3009
3010
3011
3012
3013
3014
3015
3016
3017
3018
3019
3020
3021
3022
3023
3024
3025
3026
3027
3028
3029
3030
3031
3032
3033
3034
3035
3036
3037
3038
3039
3040
3041
3042
3043
3044
3045
3046
3047
3048
3049
3050
3051
3052
3053
3054
3055
3056
3057
3058
3059
3060
3061
3062
3063
3064
3065
3066
3067
3068
3069
3070
3071
3072
3073
3074
3075
3076
3077
3078
3079
3080
3081
3082
3083
3084
3085
3086
3087
3088
3089
3090
3091
3092
3093
3094
3095
3096
3097
3098
3099
3100
3101
3102
3103
3104
3105
3106
3107
3108
3109
3110
3111
3112
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
3123
3124
3125
3126
3127
3128
3129
3130
3131
3132
3133
3134
3135
3136
3137
3138
3139
3140
3141
3142
3143
3144
3145
3146
3147
3148
3149
3150
3151
3152
3153
3154
3155
3156
3157
3158
3159
3160
3161
3162
3163
3164
3165
3166
3167
3168
3169
3170
3171
3172
3173
3174
3175
3176
3177
3178
3179
3180
3181
3182
3183
3184
3185
3186
3187
3188
3189
3190
3191
3192
3193
3194
3195
3196
3197
3198
3199
3200
3201
3202
3203
3204
3205
3206
3207
3208
3209
3210
3211
3212
3213
3214
3215
3216
3217
3218
3219
3220
3221
3222
3223
3224
3225
3226
3227
3228
3229
3230
3231
%* gmpl_es.tex *%

%***********************************************************************
%  This code is part of GLPK (GNU Linear Programming Kit).
%
%  Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
%  2009, 2010, 2011, 2013, 2014, 2015 Andrew Makhorin, Department for
%  Applied Informatics, Moscow Aviation Institute, Moscow, Russia. All
%  rights reserved. E-mail: <mao@gnu.org>.
%
%  GLPK is free software: you can redistribute it and/or modify it
%  under the terms of the GNU General Public License as published by
%  the Free Software Foundation, either version 3 of the License, or
%  (at your option) any later version.
%
%  GLPK is distributed in the hope that it will be useful, but WITHOUT
%  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
%  or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
%  License for more details.
%
%  You should have received a copy of the GNU General Public License
%  along with GLPK. If not, see <http://www.gnu.org/licenses/>.
%***********************************************************************

\documentclass[11pt,spanish]{report}
\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}
\usepackage{lmodern}
\usepackage{amssymb}
\usepackage[dvipdfm,linktocpage,colorlinks,linkcolor=blue,
urlcolor=blue]{hyperref}
\usepackage{indentfirst}

\setlength{\textwidth}{6.5in}
\setlength{\textheight}{8.5in}
\setlength{\oddsidemargin}{0in}
\setlength{\topmargin}{0in}
\setlength{\headheight}{0in}
\setlength{\headsep}{0in}
\setlength{\footskip}{0.5in}
\setlength{\parindent}{16pt}
\setlength{\parskip}{5pt}
\setlength{\topsep}{0pt}
\setlength{\partopsep}{0pt}
\setlength{\itemsep}{\parskip}
\setlength{\parsep}{0pt}
\setlength{\leftmargini}{\parindent}
\renewcommand{\labelitemi}{---}

\def\para#1{\noindent{\bf#1}}

\renewcommand\contentsname{\sf\bfseries Contenidos}
\renewcommand\chaptername{\sf\bfseries Capítulo}
\renewcommand\appendixname{\sf\bfseries Apéndice}

\begin{document}

\thispagestyle{empty}

\begin{center}

\vspace*{1.5in}

\begin{huge}
\sf\bfseries Lenguaje de Modelado GNU MathProg
\end{huge}

\vspace{0.5in}

\begin{LARGE}
\sf Referencia del Lenguaje
\end{LARGE}

\vspace{0.5in}

\begin{LARGE}
\sf para GLPK Versión 4.57
\end{LARGE}

\vspace{0.5in}
\begin{Large}
\sf (BORRADOR, octubre del 2015)
\end{Large}

\end{center}

\newpage

\vspace*{1in}

\vfill

\noindent
El paquete GLPK es parte del Proyecto GNU distribuido bajo la égida de GNU

\noindent
Copyright \copyright{} 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2013, 2014, 2015 Andrew Makhorin, Department for Applied Informatics, Moscow Aviation Institute, Moscow, Russia. Todos los derechos reservados.

\noindent
Título original en inglés: Modeling Language GNU MathProg - Language Reference for GLPK Version 4.50

\noindent
Traducción: Pablo Yapura, Facultad de Ciencias Agrarias y Forestales, Universidad Nacional de La Plata, La Plata, Argentina.

\noindent
Copyright \copyright{} 2013, 2014, 2015 Pablo Yapura, para esta traducción. Todos los derechos reservados.

\noindent
Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
MA 02110-1301, USA.

\noindent
Se permite realizar y distribuir copias textuales de este manual siempre que se preserve este aviso de permiso y el aviso del copyright en todas las copias.

\noindent
Se permite copiar y distribuir versiones modificadas de este manual bajo las condiciones de copias textuales, siempre que también se distribuya íntegro el trabajo derivado resultante bajo los términos de un aviso de permiso idéntico al presente.

\noindent
Se permite copiar y distribuir traducciones de este manual en otro idioma bajo las condiciones establecidas arriba para versiones modificadas.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\newpage

{\setlength{\parskip}{0pt}
\tableofcontents
}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\chapter{Introducción}

{\it GNU MathProg} es un lenguaje de modelado diseñado para describir modelos lineales de programación matemática.\footnote{El lenguaje GNU MathProg es un subconjunto del lenguaje AMPL. Su implementación en GLPK está basada principalmente en el paper: {\it Robert Fourer}, {\it David M. Gay} \& {\it Brian W. Kernighan}, ``A Modeling Language for Mathematical Programming.'' {\it Management Science} 36 (1990), pp.~519-554.}

La descripción del modelo escrita en el lenguaje GNU MathProg consiste en un conjunto de sentencias y bloques de datos construidos por el usuario a partir de los elementos del lenguaje que se describen en este documento.

En un proceso que se denomina {\it traducción}, un programa denominado {\it traductor del modelo} analiza la descripción del modelo y la traduce en una estructura interna de datos, la que puede ser usada tanto para generar una instancia de un problema de programación matemática, como para obtener directamente una solución numérica del problema mediante un programa denominado {\it solver}.

\section{El problema de la programación lineal}
\label{problem}

En MathProg el problema de la programación lineal (PL) se expresa como sigue:

\medskip

\noindent\hspace{1in}minimizar (o maximizar)
$$z=c_1x_1+c_2x_2+\dots+c_nx_n+c_0\eqno(1.1)$$
\noindent\hspace{1in}sujeto a las restricciones lineales
$$
\begin{array}{l@{\ }c@{\ }r@{\ }c@{\ }r@{\ }c@{\ }r@{\ }c@{\ }l}
L_1&\leq&a_{11}x_1&+&a_{12}x_2&+\dots+&a_{1n}x_n&\leq&U_1\\
L_2&\leq&a_{21}x_1&+&a_{22}x_2&+\dots+&a_{2n}x_n&\leq&U_2\\
\multicolumn{9}{c}{.\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .}\\
L_m&\leq&a_{m1}x_1&+&a_{m2}x_2&+\dots+&a_{mn}x_n&\leq&U_m\\
\end{array}\eqno(1.2)
$$
\noindent\hspace{1in}y a las cotas de las variables
$$
\begin{array}{l@{\ }c@{\ }c@{\ }c@{\ }l}
l_1&\leq&x_1&\leq&u_1\\
l_2&\leq&x_2&\leq&u_2\\
\multicolumn{5}{c}{.\ \ .\ \ .\ \ .\ \ .}\\
l_n&\leq&x_n&\leq&u_n\\
\end{array}\eqno(1.3)
$$

\noindent
donde $x_1$, $x_2$, \dots, $x_n$ son variables; $z$ es la función objetivo; $c_1$, $c_2$, \dots, $c_n$ son coeficientes de la función objetivo; $c_0$ es el término constante (``de traslación'') de la función objetivo; $a_{11}$,
$a_{12}$, \dots, $a_{mn}$ son coeficientes de las restricciones; $L_1$, $L_2$,
\dots, $L_m$ son cotas inferiores de las restricciones; $U_1$, $U_2$, \dots, $U_m$ son cotas superiores de las restricciones; $l_1$, $l_2$, \dots, $l_n$ son cotas inferiores de las variables y $u_1$, $u_2$, \dots, $u_n$ son cotas superiores de las variables.

Las cotas de las variables y las cotas de las restricciones pueden ser tanto finitas como infinitas. Además, las cotas inferiores pueden ser iguales a las correspondientes cotas superiores. Entonces, están permitidos los siguientes tipos de variables y restricciones:

\medskip

{\def\arraystretch{1.4}
\noindent\hspace{54pt}
\begin{tabular}{@{}r@{\ }c@{\ }c@{\ }c@{\ }l@{\hspace*{39.5pt}}l}
$-\infty$&$<$&$x$&$<$&$+\infty$&Variable libre (no acotada)\\
$l$&$\leq$&$x$&$<$&$+\infty$&Variable con cota inferior\\
$-\infty$&$<$&$x$&$\leq$&$u$&Variable con cota superior\\
$l$&$\leq$&$x$&$\leq$&$u$&Variable doblemente acotada\\
$l$&$=$&$x$&=&$u$&Variable fija\\
\end{tabular}

\noindent\hspace{54pt}
\begin{tabular}{@{}r@{\ }c@{\ }c@{\ }c@{\ }ll}
$-\infty$&$<$&$\sum a_jx_j$&$<$&$+\infty$&Forma lineal libre (no acotada)\\
$L$&$\leq$&$\sum a_jx_j$&$<$&$+\infty$&Restricción de inecuación ``mayor o igual que''\\
$-\infty$&$<$&$\sum a_jx_j$&$\leq$&$U$&Restricción de inecuación ``menor o igual que''\\
$L$&$\leq$&$\sum a_jx_j$&$\leq$&$U$&Restricción de inecuación doblemente acotada\\
$L$&$=$&$\sum a_jx_j$&=&$U$&Restricción de igualdad\\
\end{tabular}
}

\medskip

Además de problemas puros de PL, MathProg también permite problemas de programación entera lineal mixta (PEM), en los que algunas o todas las variables se han restringido a ser enteras o binarias.

\section{Objetos del modelo}

En MathProg el modelo se describe mediante conjuntos, parámetros, variables, restricciones y objetivos, los que se denominan {\it objetos del modelo}.

El usuario introduce objetos particulares del modelo usando las sentencias del lenguaje. Cada objeto del modelo está provisto de un nombre simbólico que lo identifica de manera única y está pensado con propósitos de referencia.

\newpage

Los objetos del modelo, incluyendo los conjuntos, pueden ser arreglos multidimensionales construidos sobre conjuntos indizantes. Formalmente, el arreglo $n$-dimensional $A$ es el mapeo $$A:\Delta\rightarrow\Xi,\eqno(1.4)$$ donde $\Delta\subseteq C_1\times\dots\times C_n$ es el subconjunto del producto cartesiano de los conjuntos indizantes, $\Xi$ es el conjunto de los miembros del arreglo. En MathProg, el conjunto $\Delta$ se denomina {\it dominio del subíndice}. Sus miembros son los $n$-tuplos $(i_1,\dots,i_n)$, donde
$i_1\in C_1$, \dots, $i_n\in C_n$.

Si $n=0$, el producto cartesiano tiene exactamente un miembro (específicamente, un 0-tuplo), de forma tal que es conveniente pensar en los objetos escalares como arreglos 0-dimensionales que tienen un solo miembro.

El tipo de los miembros del arreglo se determina por el tipo del objeto del modelo correspondiente como sigue:

\medskip

\noindent\hfil
\begin{tabular}{@{}ll@{}}
Objeto del modelo&Miembro del arreglo\\
\hline
Conjunto&Conjunto plano elemental\\
Parámetro&Número o símbolo\\
Variable&Variable elemental\\
Restricción&Restricción elemental\\
Objetivo&Objetivo elemental\\
\end{tabular}

\medskip

Para referir al miembro particular de un objeto, el mismo debe estar provisto de {\it subíndices}. Por ejemplo, si $a$ es un parámetro 2-dimensional definido sobre $I\times J$, una referencia a sus miembros particulares se puede escribir como $a[i,j]$, donde $i\in I$ y $j\in J$. Se sobreentiende que los objetos escalares no necesitan subíndices por ser 0-dimensionales.

\section{Estructura de la descripción del modelo}

A veces es deseable escribir un modelo que, en distintos momentos, puede requerir diferentes datos para solucionar cada instancia del problema usando el modelo. Por esta razón, en MathProg la descripción del modelo consta de dos partes: la {\it sección del modelo} y la {\it sección de los datos}.

La sección del modelo es la parte principal de la descripción del modelo que contiene las declaraciones de los objetos del modelo; es común a todos los problemas basados en el modelo correspondiente.

La sección de los datos es una parte opcional de la descripción del modelo que contiene los datos específicos para una instancia particular del problema.

Dependiendo de lo que sea más conveniente, las secciones del modelo y de los datos pueden disponerse en el mismo archivo o en dos archivos separados. Esta última característica permite tener un número arbitrario de secciones con datos diferentes para ser usadas con la misma sección del modelo.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\newpage

\chapter{Codificación de la descripción del modelo}
\label{coding}

La descripción del modelo se codifica en formato de texto plano usando el juego de caracteres ASCII. Los caracteres válidos en la descripción del modelo son los siguientes:

\begin{itemize}
\item caracteres alfabéticos:\\
\verb|A B C D E F G H I J K L M N O P Q R S T U V W X Y Z|\\
\verb|a b c d e f g h i j k l m n o p q r s t u v w x y z _|
\item caracteres numéricos:\\
\verb|0 1 2 3 4 5 6 7 8 9|
\item caracteres especiales:\\
\verb?! " # & ' ( ) * + , - . / : ; < = > [ ] ^ { | } ~?
\item caracteres no imprimibles:\\
\verb|SP HT CR NL VT FF|
\end{itemize}

Dentro de los literales de cadena y de los comentarios, cualquier carácter ASCII (excepto los caracteres de control) son válidos.

Los caracteres no imprimibles no son significativos. Se pueden usar libremente entre las unidades léxicas para mejorar la legibilidad de la descripción del modelo. También se usan para separar unidades léxicas entre sí, en caso de no existir otra forma de hacerlo.

Sintácticamente, la descripción del modelo es una secuencia de unidades léxicas de las siguientes categorías:

\begin{itemize}
\item nombres simbólicos;
\item literales numéricos;
\item literales de cadena;
\item palabras clave;
\item delimitadores;
\item comentarios.
\end{itemize}

Las unidades léxicas del lenguaje se discuten a continuación.

\section{Nombres simbólicos}

Un {\it nombre simbólico} consiste de caracteres alfabéticos y numéricos, el primero de los cuales debe ser alfabético. Todos los nombres simbólicos deben ser distintos (sensibilidad a las mayúsculas).

\para{Ejemplos}

\begin{verbatim}
alfa123
Esto_es_un_nombre
_P123_abc_321
\end{verbatim}

Los nombres simbólicos se usan para identificar los objetos del modelo (conjuntos, parámetros, variables, restricciones y objetivos) y los índices.

Todos los nombres simbólicos (exceptuando los nombres de los índices) deben ser únicos, {\it i.e.} la descripción del modelo no debe tener objetos distintos con el mismo nombre. Los nombres simbólicos de los índices deben ser únicos dentro del alcance en el que son válidos.

\section{Literales numéricos}

Un {\it literal numérico} sigue la forma {\it xx}{\tt E}{\it syy}, donde {\it xx} es un número con punto decimal optativo, {\it s} es el signo {\tt+} o {\tt-} e {\it yy} es un exponente decimal. La letra {\tt E} es insensible a las mayúsculas y se puede codificar como {\tt e}.

\para{Ejemplos}

\begin{verbatim}
123
3.14159
56.E+5
.78
123.456e-7
\end{verbatim}

Los literales numéricos se usan para representar cantidades numéricas y tienen significado fijo obvio.

\section{Literales de cadena}

Un {\it literal de cadena} es una secuencia arbitraria de caracteres encerrados entre comillas, tanto simples como dobles. Ambas formas son equivalentes.

Si una comilla simple es parte de un literal de cadena encerrado entre comillas simples, se debe codificar dos veces. Análogamente, si una comilla doble es parte de un literal de cadena encerrado entre comillas dobles, se debe codificar dos veces.

\para{Ejemplos}

\begin{verbatim}
'Esta es una cadena'
"Esta es otra cadena"
'No debe usarse los 20''s'
"""Hola, che"" cantaba Favio."
\end{verbatim}

Los literales de cadena se usan para representar cantidades simbólicas.

\section{Palabras clave}

Una {\it palabra clave} es una secuencia de caracteres alfabéticos y posiblemente algunos caracteres especiales.

Todas la palabras clave caen en alguna de dos categorías: las {\it palabras clave reservadas}, que no pueden usarse como nombres simbólicos, y las {\it palabras clave no reservadas}, que son reconocidas por el contexto y entonces pueden usarse como nombres simbólicos.

Las palabras clave reservadas son las siguientes:

\noindent\hfil
\begin{tabular}{@{}p{.7in}p{.7in}p{.7in}p{.7in}@{}}
{\tt and}&{\tt else}&{\tt mod}&{\tt union}\\
{\tt by}&{\tt if}&{\tt not}&{\tt within}\\
{\tt cross}&{\tt in}&{\tt or}\\
{\tt diff}&{\tt inter}&{\tt symdiff}\\
{\tt div}&{\tt less}&{\tt then}\\
\end{tabular}

Las palabras clave no reservadas se describen en secciones posteriores.

Todas las palabras clave tienen un significado fijo, el que se explicará en las discusiones de las correspondientes construcciones sintácticas donde las palabras claves sean usadas.

\section{Delimitadores}

Un {\it delimitador} es tanto un carácter especial individual como una secuencia de dos caracteres especiales, como sigue:

\noindent\hfil
\begin{tabular}{@{}p{.3in}p{.3in}p{.3in}p{.3in}p{.3in}p{.3in}p{.3in}
p{.3in}p{.3in}@{}}
{\tt+}&{\tt**}&{\tt<=}&{\tt>}&{\tt\&\&}&{\tt:}&{\tt|}&{\tt[}&{\tt>}{\tt>}\\
{\tt-}&{\tt\textasciicircum}&{\tt=}&{\tt<>}&{\tt||}&{\tt;}&{\tt\char126}
&{\tt]}&{\tt<-}\\
{\tt*}&{\tt\&}&{\tt==}&{\tt!=}&{\tt.}&{\tt:=}&{\tt(}&{\tt\{}\\
{\tt/}&{\tt<}&{\tt>=}&{\tt!}&{\tt,}&{\tt..}&{\tt)}&{\tt\}}\\
\end{tabular}

Si el delimitador está compuesto por dos caracteres, no debe haber espacios entre ellos.

Todos los delimitadores tienen un significado fijo, el que se explicará en las discusiones de las correspondientes construcciones sintácticas donde los delimitadores sean usados.

\section{Comentarios}

Con propósitos de documentación, la descripción del modelo puede ser provista de {\it comentarios}, los que pueden ser de dos formas diferentes. La primera es un {\it comentario de una línea individual}, el que debe comenzar con el carácter {\tt\#} y se extiende hasta el final de la línea. La segunda forma es un {\it comentario en secuencia}, el que consiste en una secuencia de caracteres cualesquiera encerrados entre {\tt/*} y {\tt*/}.

\para{Ejemplos}

\begin{verbatim}
param n := 10; # Esto es un comentario
/* Esto es otro comentario */
\end{verbatim}

Los comentarios son ignorados por el traductor del modelo y pueden aparecer en cualquier sitio de la descripción del modelo en la que que se permitan caracteres no imprimibles.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\newpage

\chapter{Expresiones}

Una {\it expresión} es una regla para calcular un valor. En la descripción de un modelo, las expresiones se usan como constituyentes de ciertas sentencias.

En general, las expresiones están compuestas por operandos y operadores.

Dependiendo del tipo del valor resultante, todas las expresiones pertenecen a alguna de las siguientes categorías:

\vspace*{-8pt}

\begin{itemize}
\item expresiones numéricas;
\item expresiones simbólicas;
\item expresiones indizantes;
\item expresiones de conjuntos;
\item expresiones lógicas;
\item expresiones lineales.
\end{itemize}

\vspace*{-8pt}

\section{Expresiones numéricas}

Una {\it expresión numérica} es una regla para calcular un valor numérico individual representado como un número de punto flotante.

La expresión numérica primaria puede ser un literal numérico, un índice, un parámetro no-indizado, un parámetro indizado, una función interna de referencia, una expresión numérica iterada, una expresión numérica condicional u otra expresión numérica encerrada entre paréntesis.

\newpage

\para{Ejemplos}

\noindent
\begin{tabular}{@{}ll@{}}
\verb|1.23|&(literal numérico)\\
\verb|j|&(índice)\\
\verb|tiempo|&(parámetro no-indizado)\\
\verb|a['Mayo de 2003',j+1]|&(parámetro indizado)\\
\verb|abs(b[i,j])|&(función de referencia)\\
\verb|sum{i in S diff T} alfa[i] * b[i,j]|&(expresión iterada)\\
\verb|if i in I then 2 * p else q[i+1]|&(expresión condicional)\\
\verb|(b[i,j] + .5 * c)|&(expresión parentética)\\
\end{tabular}

Empleando ciertos operadores aritméticos se pueden construir expresiones numéricas más generales conteniendo dos o más expresiones numéricas primarias.

\para{Ejemplos}

\begin{verbatim}
j+1
2 * a[i-1,j+1] - b[i,j]
sum{j in J} a[i,j] * x[j] + sum{k in K} b[i,k] * x[k]
(if i in I and p >= 1 then 2 * p else q[i+1]) / (a[i,j] + 1.5)
\end{verbatim}

\subsection{Literales numéricos}

Si la expresión numérica primaria es un literal numérico, el valor resultante es obvio.

\subsection{Índices}

Si la expresión numérica primaria es un índice, el valor resultante es el valor corriente asignado al índice.

\subsection{Parámetros no-indizados}

Si la expresión numérica primaria es un parámetro no-indizado (el que debe ser 0-dimensional), el valor resultante es el valor del parámetro.

\subsection{Parámetros indizados}

La expresión numérica primaria que se refiere a parámetros indizados tiene la siguiente forma sintáctica:
$$
\mbox{{\it nombre}{\tt[}$i_1${\tt,} $i_2${\tt,} \dots{\tt,} $i_n${\tt]}}
$$
donde {\it nombre} es el nombre simbólico del parámetro e $i_1$, $i_2$,
\dots, $i_n$ son subíndices.

Cada subíndice debe ser una expresión numérica o simbólica. El número de subíndices en la lista de subíndices debe ser igual a la dimensión del parámetro con el cual está asociada la lista de subíndices.

Los valores reales de las expresiones de subíndices se usan para identificar al miembro particular del parámetro que determina el valor resultante de la expresión primaria.

\subsection{Funciones de referencia}

En MathProg existen las siguientes funciones internas, las que se pueden usar en expresiones numéricas:

\begin{tabular}{@{}p{112pt}p{328pt}@{}}
{\tt abs(}$x${\tt)}&$|x|$, valor absoluto de $x$\\
{\tt atan(}$x${\tt)}&$\arctan x$, valor principal del arcotangente de
$x$ (en radianes)\\
{\tt atan(}$y${\tt,} $x${\tt)}&$\arctan y/x$, valor principal del arcotangente de $y/x$ (en radianes). En este caso, los signos de ambos argumentos, $y$ y $x$, se usan para determinar el cuadrante del valor resultante\\
{\tt card(}$X${\tt)}&$|X|$, el cardinal (número de elementos) del conjunto $X$\\
{\tt ceil(}$x${\tt)}&$\lceil x\rceil$, el menor entero no menor que $x$ (``techo de $x$'')\\
{\tt cos(}$x${\tt)}&$\cos x$, coseno de $x$ (en radianes)\\
{\tt exp(}$x${\tt)}&$e^x$, exponencial en base $e$ de $x$\\
{\tt floor(}$x${\tt)}&$\lfloor x\rfloor$, el mayor entero no mayor que $x$ (``piso de $x$'')\\
{\tt gmtime()}&el número de segundos transcurridos desde las 00:00:00 del 1 de enero de 1970, Tiempo Universal Coordinado (para los detalles ver la Sección \ref{gmtime}, página \pageref{gmtime})\\
{\tt length(}$c${\tt)}&$|c|$, longitud de la cadena de caracteres $c$\\
{\tt log(}$x${\tt)}&$\log x$, logaritmo natural de $x$\\
{\tt log10(}$x${\tt)}&$\log_{10}x$, logaritmo común (decimal) de $x$\\
{\tt max(}$x_1${\tt,} $x_2${\tt,} \dots{\tt,} $x_n${\tt)}&el mayor de los valores $x_1$, $x_2$, \dots, $x_n$\\
{\tt min(}$x_1${\tt,} $x_2${\tt,} \dots{\tt,} $x_n${\tt)}&el menor de los valores $x_1$, $x_2$, \dots, $x_n$\\
{\tt round(}$x${\tt)}&redondeo de $x$ al entero más próximo\\
{\tt round(}$x${\tt,} $n${\tt)}&redondeo de $x$ a $n$ dígitos decimales\\
{\tt sin(}$x${\tt)}&$\sin x$, seno de $x$ (en radianes)\\
{\tt sqrt(}$x${\tt)}&$\sqrt{x}$, raíz cuadrada no-negativa de $x$\\
{\tt str2time(}$c${\tt,} $f${\tt)}&conversión de la cadena de caracteres $c$ a tiempo calendario (para los detalles ver la Sección \ref{str2time}, página \pageref{str2time})\\
{\tt trunc(}$x${\tt)}&truncado de $x$ al entero más próximo\\
{\tt trunc(}$x${\tt,} $n${\tt)}&truncado de $x$ a $n$ dígitos decimales\\
{\tt Irand224()}&generación de un entero pseudo-aleatorio uniformemente distribuido en $[0,2^{24})$\\
{\tt Uniform01()}&generación de un número pseudo-aleatorio uniformemente distribuido en $[0,1)$\\
{\tt Uniform(}$a${\tt,} $b${\tt)}&generación de un número pseudo-aleatorio uniformemente distribuido en $[a,b)$\\
{\tt Normal01()}&generación de una variable gaussiana pseudo-aleatoria con $\mu=0$ y $\sigma=1$\\
{\tt Normal(}$\mu${\tt,} $\sigma${\tt)}&generación de una variable gaussiana pseudo-aleatoria con $\mu$ y $\sigma$ dadas\\
\end{tabular}

Los argumentos de todas la funciones internas, excepto {\tt card}, {\tt length} y {\tt str2time}, deben ser expresiones numéricas. El argumento de {\tt card} debe ser una expresión de conjunto. El argumento de {\tt length} y ambos argumentos de {\tt str2time} deben ser expresiones simbólicas.

El valor resultante de una expresión numérica que es una función de referencia es el resultado de aplicar la función a sus argumentos.

Se debe notar que cada función generadora pseudo-aleatoria tiene un argumento latente ({\it i.e.} algún estado interno) que cambia cada vez que se aplica la función. Así, si la función se aplica repetidamente, aún con argumentos idénticos, debido al efecto colateral siempre se producirán valores resultantes diferentes.

\subsection{Expresiones iteradas}
\label{itexpr}

Una {\it expresión numérica iterada} es una expresión numérica primaria que tiene la siguiente forma sintáctica:
$$\mbox{\it operador-iterado expresión-indizante integrando}$$
donde {\it operador-iterado} es el nombre simbólico del operador iterado que se ejecutará (ver más adelante), {\it expresión-indizante} es una expresión indizante que introduce índices y controla la iteración e {\it integrando} es una expresión numérica que participa en la operación.

En MathProg existen cuatro operadores iterados que se pueden usar en expresiones numéricas:

{\def\arraystretch{2}
\noindent\hfil
\begin{tabular}{@{}lll@{}}
{\tt sum}&sumatoria&$\displaystyle\sum_{(i_1,\dots,i_n)\in\Delta}
f(i_1,\dots,i_n)$\\
{\tt prod}&multiplicatoria&$\displaystyle\prod_{(i_1,\dots,i_n)\in\Delta}
f(i_1,\dots,i_n)$\\
{\tt min}&mínimo&$\displaystyle\min_{(i_1,\dots,i_n)\in\Delta}
f(i_1,\dots,i_n)$\\
{\tt max}&máximo&$\displaystyle\max_{(i_1,\dots,i_n)\in\Delta}
f(i_1,\dots,i_n)$\\
\end{tabular}
}

\noindent donde $i_1$, \dots, $i_n$ son índices introducidos en la expresión indizante, $\Delta$ es el dominio, el conjunto de los $n$-tuplos especificados en la expresión indizante que define valores particulares asignados a los índices para ejecutar la operación iterada y $f(i_1,\dots,i_n)$ es el integrando, una expresión numérica cuyo valor resultante depende de los índices.

El valor resultante de una expresión numérica iterada es el resultado de aplicar el operador iterado a sus integrandos a través de todos los $n$-tuplos contenidos en el dominio.

\subsection{Expresiones condicionales}
\label{ifthen}

Una {\it expresión numérica condicional} es una expresión numérica primaria que tiene una de las dos formas sintácticas siguientes:
$$
{\def\arraystretch{1.4}
\begin{array}{l}
\mbox{{\tt if} $b$ {\tt then} $x$ {\tt else} $y$}\\
\mbox{{\tt if} $b$ {\tt then} $x$}\\
\end{array}
}
$$
donde $b$ es una expresión lógica, mientras que $x$ e $y$ son expresiones numéricas.

El valor resultante de un expresión condicional depende del valor de la expresión lógica que sigue a la palabra clave {\tt if}. Si toma el valor {\it verdadero}, el valor de la expresión condicional es el valor de la expresión que sigue a la palabra clave {\tt then}. De otro modo, si la expresión lógica toma el valor {\it falso}, el valor de la expresión condicional es el valor de la expresión que sigue a la palabra clave {\tt else}. Si se usa la segunda forma sintáctica, la reducida, y la expresión lógica toma el valor {\it falso}, el valor resultante de la expresión condicional será cero.

\subsection{Expresiones parentéticas}

Cualquier expresión numérica puede ser encerrada entre paréntesis, lo que las torna sintácticamente en una expresión numérica primaria.

Los paréntesis pueden usarse en expresiones numéricas, como en el álgebra, para especificar el orden deseado en el cual se ejecutarán las operaciones. Cuando se usan paréntesis, la expresión entre paréntesis se evalúa antes que el valor resultante sea usado.

El valor resultante de la expresión parentética es idéntico al valor de la expresión encerrada entre paréntesis.

\subsection{Operadores aritméticos}

En MathProg existen los siguientes operadores aritméticos, los que se pueden usar en expresiones numéricas:

\begin{tabular}{@{}ll@{}}
{\tt +} $x$&más unario\\
{\tt -} $x$&menos unario\\
$x$ {\tt +} $y$&adición\\
$x$ {\tt -} $y$&sustracción\\
$x$ {\tt less} $y$&diferencia positiva (si $x<y$ entonces 0, de otro modo $x-y$)\\
$x$ {\tt *} $y$&multiplicación\\
$x$ {\tt /} $y$&división\\
$x$ {\tt div} $y$&cociente de la división exacta\\
$x$ {\tt mod} $y$&resto de la división exacta\\
$x$ {\tt **} $y$, $x$ {\tt\textasciicircum} $y$&exponenciación (elevación a una potencia)\\
\end{tabular}

\noindent donde $x$ e $y$ son expresiones numéricas.

Si la expresión incluye más de un operador aritmético, todos los operadores se ejecutan de izquierda a derecha, de acuerdo con la jerarquía de las operaciones (ver más adelante), con la única excepción del operador de exponenciación que se ejecuta de derecha a izquierda.

El valor resultante de la expresión que contiene operadores aritméticos es el resultado de aplicar los operadores a sus operandos.

\subsection{Jerarquía de las operaciones}
\label{hierarchy}

La siguiente lista muestra la jerarquía de las operaciones en expresiones numéricas:

\noindent\hfil
\begin{tabular}{@{}ll@{}}
Operación&Jerarquía\\
\hline
Evaluación de funciones ({\tt abs}, {\tt ceil}, etc.)&
1.{\textsuperscript{\b{a}}}\\
Exponenciación ({\tt**}, {\tt\textasciicircum})&
2.{\textsuperscript{\b{a}}}\\
Más y menos unario ({\tt+}, {\tt-})&
3.{\textsuperscript{\b{a}}}\\
Multiplicación y división ({\tt*}, {\tt/}, {\tt div}, {\tt mod})&
4.{\textsuperscript{\b{a}}}\\
Operaciones iteradas ({\tt sum}, {\tt prod}, {\tt min}, {\tt max})&
5.{\textsuperscript{\b{a}}}\\
Adición y sustracción ({\tt+}, {\tt-}, {\tt less})&
6.{\textsuperscript{\b{a}}}\\
Evaluación condicional ({\tt if} \dots {\tt then} \dots {\tt else})&
7.{\textsuperscript{\b{a}}}\\
\end{tabular}

Esta jerarquía se usa para determinar cual de dos operaciones consecutivas se realizará primero. Si el primer operador tiene jerarquía mayor o igual que el segundo, la primera operación se realiza. En caso contrario, el segundo operador es comparado con el tercero y así sucesivamente. Cuando se alcanza el final de la expresión, todas las operaciones restantes se realizan en el orden inverso.

\section{Expresiones simbólicas}

Una {\it expresión simbólica} es una regla para calcular un valor simbólico individual representado como una cadena de caracteres.

La expresión simbólica primaria puede ser un literal de cadena, un índice, un parámetro no-indizado, un parámetro indizado, una función interna de referencia, una expresión simbólica condicional u otra expresión simbólica encerrada entre paréntesis.

También está permitido usar una expresión numérica como la expresión simbólica primaria, en cuyo caso el valor resultante de la expresión numérica se convierte automáticamente al tipo simbólico.

\para{Ejemplos}

\noindent
\begin{tabular}{@{}ll@{}}
\verb|'Mayo de 2003'|&(literal de cadena)\\
\verb|j|&(índice)\\
\verb|p|&(parámetro no-indizado)\\
\verb|s['abc',j+1]|&(parámetro indizado)\\
\verb|substr(nombre[i],k+1,3)|&(función de referencia)\\
\verb|if i in I then s[i,j] & "..." else t[i+1]|& (expresión condicional) \\
\verb|((10 * b[i,j]) & '.bis')|&(expresión parentética)\\
\end{tabular}

Empleando el operador de concatenación se pueden construir expresiones simbólicas más generales conteniendo dos o más expresiones simbólicas primarias.

\para{Ejemplos}

\begin{verbatim}
'abc[' & i & ',' & j & ']'
"desde " & ciudad[i] " hasta " & ciudad[j]
\end{verbatim}

Los principios de evaluación de las expresiones simbólicas son enteramente análogos a los dados para las expresiones numéricas (ver más atrás).

\subsection{Funciones de referencia}

En MathProg existen las siguientes funciones internas que pueden ser usadas en expresiones simbólicas:

\begin{tabular}{@{}p{112pt}p{328pt}@{}}
{\tt substr(}$c${\tt,} $x${\tt)}&subcadena de $c$ empezando en la posición $x$\\
{\tt substr(}$c${\tt,} $x${\tt,} $y${\tt)}&subcadena de $c$ empezando en la posición $x$ con longitud $y$\\
{\tt time2str(}$t${\tt,} $f${\tt)}&conversión de tiempo calendario a una cadena de caracteres (para los detalles, ver Sección \ref{time2str}, página
\pageref{time2str})\\
\end{tabular}

El primer argumento de {\tt substr} debe ser una expresión simbólica, mientras que el segundo y el tercero (opcional) deben ser expresiones numéricas.

El primer argumento de {\tt time2str} debe ser una expresión numérica y su segundo argumento debe ser una expresión simbólica.

El valor resultante de una expresión simbólica que es una función de referencia es el resultado de aplicar la función a sus argumentos.

\subsection{Operadores simbólicos}

Actualmente, en MathProg existe un único operador simbólico:
$$\mbox{\tt c \& t}$$
donde $c$ y $t$ son expresiones simbólicas. Este operador implica la concatenación de sus dos operandos simbólicos, los que son cadenas de caracteres.

\subsection{Jerarquía de las operaciones}

La siguiente lista muestra la jerarquía de las operaciones en expresiones simbólicas:

\noindent\hfil
\begin{tabular}{@{}ll@{}}
Operación&Jerarquía\\
\hline
Evaluación de operaciones numéricas&
1.{\textsuperscript{\b{a}}}-7.{\textsuperscript{\b{a}}}\\
Concatenación ({\tt\&})&
8.{\textsuperscript{\b{a}}}\\
Evaluación condicional ({\tt if} \dots {\tt then} \dots {\tt else})&
9.{\textsuperscript{\b{a}}}\\
\end{tabular}

Esta jerarquía tiene el mismo significado que se explicó anteriormente para expresiones numéricas (ver Subsección \ref{hierarchy}, página \pageref{hierarchy}).

\section{Expresiones de indización e índices}
\label{indexing}

Una {\it expresión indizante} es una construcción auxiliar que especifica un conjunto plano de $n$-tuplos e introduce índices. Tiene dos formas sintácticas:
$$
{\def\arraystretch{1.4}
\begin{array}{l}
\mbox{{\tt\{} {\it entrada}$_1${\tt,} {\it entrada}$_2${\tt,} \dots{\tt,}
{\it entrada}$_m$ {\tt\}}}\\
\mbox{{\tt\{} {\it entrada}$_1${\tt,} {\it entrada}$_2${\tt,} \dots{\tt,}
{\it entrada}$_m$ {\tt:} {\it predicado} {\tt\}}}\\
\end{array}
}
$$
donde {\it entrada}{$_1$}, {\it entrada}{$_2$}, \dots, {\it entrada}{$_m$}
son entradas indizantes y {\it predicado} es una expresión lógica que especifica un predicado opcional (condición lógica).

Cada {\it entrada indizante} en la expresión indizante puede tomar una de las tres formas siguientes:
$$
{\def\arraystretch{1.4}
\begin{array}{l}
\mbox{$i$ {\tt in} $C$}\\
\mbox{{\tt(}$i_1${\tt,} $i_2${\tt,} \dots{\tt,}$i_n${\tt)} {\tt in}
$C$}\\
\mbox{$C$}\\
\end{array}
}
$$
donde $i_1$, $i_2$, \dots, $i_n$ son índices y $C$ es una expresión de conjunto (discutida en la próxima sección) que especifica el conjunto básico.

El número de índices de la entrada indizante debe coincidir con la dimensión del conjunto básico $C$, {\it i.e.} si $C$ consiste de 1-tuplos, se debe usar la primera forma y, si $C$ consiste de $n$-tuplos, siendo $n>1$, la segunda forma es la que debe usarse.

Si se usa la primera forma de la entrada indizante, el índice $i$ sólo puede ser un índice (ver más adelante). Si se usa la segunda forma, los índices $i_1$, $i_2$, \dots, $i_n$ pueden ser indistintamente índices o alguna expresión numérica o simbólica, siempre que al menos uno de los índices sea un índice. La tercera forma, reducida, de la entrada indizante tiene el mismo efecto que si
$i$ (si $C$ es 1-dimensional) o $i_1$, $i_2$, \dots, $i_n$ (si $C$ es $n$-dimensional) se hubieran especificado todos como índices.

Un {\it índice} es un objeto auxiliar del modelo que actúa como una variable individual. Los valores asignados a los índices son componentes de los $n$-tuplos de conjuntos básicos, {\it i.e.} algunas cantidades numéricas y simbólicas.

Para referenciarlos, los índices pueden ser provistos con nombres simbólicos. Sin embargo, a diferencia de otros objetos del modelo (conjuntos, parámetros, etc.), los índices no necesitan ser declarados explícitamente. Cada nombre simbólico {\it no-declarado} que se usa en una posición indizante de alguna entrada indizante es reconocido como el nombre simbólico correspondiente al índice.

Los nombre simbólicos de los índices son válidos solamente dentro del alcance de la expresión indizante en la que se introdujo el índice. Más allá del alcance, estos índices son completamente inaccesibles, de modo que los mismos nombres simbólicos se pueden usar para diferentes propósitos, en particular para representar índices en otras expresiones indizantes.

El alcance de la expresión indizante, en el que las declaraciones implícitas de los índices son válidas, depende del contexto en que se usa la expresión indizante:

\vspace*{-8pt}

\begin{itemize}
\item Si la expresión indizante se usa en un operador-iterado, su alcance se extiende hasta el final del integrando;
\item Si la expresión indizante se usa como una expresión de conjunto primaria, su alcance se extiende hasta el final de esta expresión indizante;
\item Si la expresión indizante se usa para definir el dominio del subíndice en la declaración de algún objeto del modelo, su alcance se extiende hasta el final de la correspondiente sentencia.
\end{itemize}

\vspace*{-8pt}

El mecanismo de indización implementado mediante las expresiones indizantes se explica mejor con algunos ejemplos que se discuten a continuación.

Sean tres conjuntos:
$$
{\def\arraystretch{1.4}
\begin{array}{l}
A=\{4,7,9\},\\
B=\{(1,Ene),(1,Feb),(2,Mar),(2,Abr),(3,May),(3,Jun)\},\\
C=\{a,b,c\},\\
\end{array}
}
$$
donde $A$ y $C$ consisten de 1-tuplos (singletones) y $B$ consiste de
2-tuplos (duplos). Considérese la siguiente expresión indizante:
$$\mbox{{\tt\{i in A, (j,k) in B, l in C\}}}$$
donde {\tt i}, {\tt j}, {\tt k} y {\tt l} son índices.

Aunque MathProg no es un lenguaje de programación por procedimientos, para cualquier expresión indizante se puede dar una descripción algorítmica equivalente. En particular, la descripción algorítmica de la expresión indizante anterior se vería como sigue:

\noindent\hfil
\begin{tabular}{@{}l@{}}
{\bf para todo} $i\in A$ {\bf ejecutar}\\
\hspace{16pt}{\bf para todo} $(j,k)\in B$ {\bf ejecutar}\\
\hspace{32pt}{\bf para todo} $l\in C$ {\bf ejecutar}\\
\hspace{48pt}{\it acción};\\
\end{tabular}

\noindent donde los índices $i$, $j$, $k$ y $l$ son asignados consecutivamente a los correspondientes componentes de los $n$-tuplos a partir de los conjuntos básicos $A$, $B$ y $C$ y {\it acción} es alguna acción que depende del contexto en el que se esté usando la expresión indizante. Por ejemplo, si la acción fuese imprimir los valores corrientes de los índices, la impresión se vería como sigue:

\noindent\hfil
\begin{tabular}{@{}llll@{}}
$i=4$&$j=1$&$k=Ene$&$l=a$\\
$i=4$&$j=1$&$k=Ene$&$l=b$\\
$i=4$&$j=1$&$k=Ene$&$l=c$\\
$i=4$&$j=1$&$k=Feb$&$l=a$\\
$i=4$&$j=1$&$k=Feb$&$l=b$\\
\multicolumn{4}{c}{.\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .}\\
$i=9$&$j=3$&$k=Jun$&$l=b$\\
$i=9$&$j=3$&$k=Jun$&$l=c$\\
\end{tabular}

Sea la expresión indizante del ejemplo usada en la siguiente operación iterada:
$$\mbox{{\tt sum\{i in A, (j,k) in B, l in C\} p[i,j,k,l]}}$$
donde {\tt p} es un parámetro numérico 4-dimensional o alguna expresión numérica cuyos valores resultantes dependan de {\tt i}, {\tt j}, {\tt k} y {\tt l}. En este caso la acción es la sumatoria, de modo que el valor resultante de la expresión numérica primaria es:
$$\sum_{i\in A,(j,k)\in B,l\in C}(p_{ijkl}).$$

Ahora, sea la expresión indizante del ejemplo usada como una expresión de conjunto primaria. En este caso, la acción es reunir a todos los 4-tuplos (cuádruplos) de la forma $(i,j,k,l)$ en un conjunto, de modo que el valor resultante de tal operación es simplemente el producto cartesiano de los conjuntos básicos:
$$A\times B\times C=\{(i,j,k,l):i\in A,(j,k)\in B,l\in C\}.$$
Se debe notar que, en este caso, la misma expresión indizante podría escribirse en la forma reducida:
$$\mbox{{\tt\{A, B, C\}}}$$
ya que los índices $i$, $j$, $k$ y $l$ no son referenciados y, consecuentemente, sus nombres simbólicos no necesitan ser especificados.

Finalmente, sea la expresión indizante del ejemplo usada como el dominio del subíndice en la declaración de algún objeto 4-dimensional del modelo, por ejemplo un parámetro numérico:
$$\mbox{{\tt param p\{i in A, (j,k) in B, l in C\}} \dots {\tt;}}$$

\noindent En este caso la acción es generar los miembros del parámetro, donde cada uno de los cuales tiene la forma $p[i,j,k,l]$.

Como se dijo anteriormente, algunos índices en la segunda forma de las entradas indizantes pueden ser expresiones numéricas o simbólicas, no solamente índices. En este caso, los valores resultantes de tales expresiones desempeñan el papel de algunas condiciones lógicas para seleccionar, solamente, aquellos $n$-tuplos del producto cartesiano de los conjuntos básicos que satisfacen estas condiciones.

Considérese, por ejemplo, la siguiente expresión indizante:
$$\mbox{{\tt\{i in A, (i-1,k) in B, l in C\}}}$$
donde {\tt i}, {\tt k} y {\tt l} son índices e {\tt i-1} es una expresión numérica. La descripción algorítmica de esta expresión indizante sería la siguiente:

\noindent\hfil
\begin{tabular}{@{}l@{}}
{\bf para todo} $i\in A$ {\bf ejecutar}\\
\hspace{16pt}{\bf para todo} $(j,k)\in B$ {\bf y} $j=i-1$ {\bf ejecutar}\\
\hspace{32pt}{\bf para todo} $l\in C$ {\bf ejecutar}\\
\hspace{48pt}{\it acción};\\
\end{tabular}

\noindent Así, si la expresión indizante se usara como una expresión de conjunto primaria, el conjunto resultante sería el siguiente:
$$\{(4,May,a),(4,May,b),(4,May,c),(4,Jun,a),(4,Jun,b),(4,Jun,c)\}.$$
Debe notarse que, en este caso, el conjunto resultante consistirá de 3-tuplos y no de 4-tuplos, puesto que en la expresión indizante no hay un índice que corresponda al primer componente de los 2-tuplos del conjunto $B$.

La regla general es: el número de componentes de los $n$-tuplos definido por una expresión indizante es igual al número de índices de tal expresión, en la que la correspondencia entre los índices y los componentes de los $n$-tuplos en el conjunto resultante es posicional, {\it i.e.} el primer índice se corresponde con el primer componente, el segundo índice se corresponde con el segundo componente, etc.

En algunos casos es necesario seleccionar un subconjunto del producto cartesiano de algunos conjuntos. Esto se puede lograr mediante el empleo de un predicado lógico opcional, el que se especifica en la expresión indizante.

Considérese, por ejemplo, la siguiente expresión indizante:
$$\mbox{{\tt\{i in A, (j,k) in B, l in C: i <= 5 and k <> 'Mar'\}}}$$
donde la expresión lógica que sigue a los dos puntos es un predicado. La descripción algorítmica de tal expresión indizante sería la siguiente:

\noindent\hfil
\begin{tabular}{@{}l@{}}
{\bf para todo} $i\in A$ {\bf ejecutar}\\
\hspace{16pt}{\bf para todo} $(j,k)\in B$ {\bf ejecutar}\\
\hspace{32pt}{\bf para todo} $l\in C$ {\bf ejecutar}\\
\hspace{48pt}{\bf si} $i\leq 5$ {\bf y} $k\neq`Mar'$ {\bf entonces}\\
\hspace{64pt}{\it acción};\\
\end{tabular}

\noindent Así, si esta expresión indizante se usara como una expresión de conjunto primaria, el conjunto resultante sería el siguiente:
$$\{(4,1,Ene,a),(4,1,Feb,a),(4,2,Abr,a),\dots,(4,3,Jun,c)\}.$$

Si no se especifica un predicado en la expresión indizante, se asume uno que toma el valor {\it verdadero}.

\section{Expresiones de conjunto}

Una {\it expresión de conjunto} es una regla para calcular un conjunto elemental, {\it i.e.} una colección de $n$-tuplos cuyos componentes son cantidades numéricas y simbólicas.

La expresión de conjunto primaria puede ser un conjunto de literales, un conjunto no-indizado, un conjunto indizado, un conjunto ``aritmético'', una expresión indizante, una expresión de conjunto iterada, una expresión de conjunto condicional u otra expresión de conjunto encerrada entre paréntesis.

\para{Ejemplos}

\noindent
\begin{tabular}{@{}ll@{}}
\verb|{(123,'aaa'), (i+1,'bbb'), (j-1,'ccc')}| &(conjunto de literales)\\
\verb|I| &(conjunto no-indizado)\\
\verb|S[i-1,j+1]| &(conjunto indizado)\\
\verb|1..t-1 by 2| &(conjunto ``aritmético'')\\
\verb|{t in 1..T, (t+1,j) in S: (t,j) in F}| &(expresión indizante)\\
\verb|setof{i in I, j in J}(i+1,j-1)| &(expresión de conjunto iterada)\\
\verb|if i < j then S[i,j] else F diff S[i,j]| &(expresión de conjunto condicional)\\
\verb|(1..10 union 21..30)| &(expresión de conjunto parentética)\\
\end{tabular}

Empleando ciertos operadores de conjunto se pueden construir expresiones de conjunto más generales conteniendo dos o más expresiones de conjunto primarias.

\newpage

\para{Ejemplos}

\begin{verbatim}
(A union B) inter (I cross J)
1..10 cross (if i < j then {'a', 'b', 'c'} else {'d', 'e', 'f'})
\end{verbatim}

\subsection{Conjuntos de literales}

Un {\it conjunto de literales} es una expresión de conjunto primaria que tiene las dos formas sintácticas siguientes:
$$
{\def\arraystretch{1.4}
\begin{array}{l}
\mbox{{\tt\{}$e_1${\tt,} $e_2${\tt,} \dots{\tt,} $e_m${\tt\}}}\\
\mbox{{\tt\{(}$e_{11}${\tt,} \dots{\tt,} $e_{1n}${\tt),}
{\tt(}$e_{21}${\tt,} \dots{\tt,} $e_{2n}${\tt),} \dots{\tt,}
{\tt(}$e_{m1}${\tt,} \dots{\tt,} $e_{mn}${\tt)\}}}\\
\end{array}
}
$$
donde $e_1$, \dots, $e_m$, $e_{11}$, \dots, $e_{mn}$ son expresiones numéricas o simbólicas.

Si se usa la primera forma, el conjunto resultante consiste de 1-tuplos (singletones), enumerados entre las llaves. Se permite especificar un conjunto vacío como {\tt\{\ \}}, el que no tiene 1-tuplos. Si se usa la segunda forma, el conjunto resultante consiste de $n$-tuplos enumerados entre las llaves, donde cada $n$-tuplo particular está compuesto por los correspondientes componentes enumerados entre los paréntesis. Todos los $n$-tuplos deben tener el mismo número de componentes.

\subsection{Conjuntos no-indizados}

Si la expresión de conjunto primaria es un conjunto no-indizado (el que debe ser 0-dimensional), el conjunto resultante es un conjunto elemental asociado con el objeto conjunto correspondiente.

\subsection{Conjuntos indizados}

La expresión de conjunto primaria que se refiere a un conjunto indizado tiene la siguiente forma sintáctica:
$$\mbox{{\it nombre}{\tt[}$i_1${\tt,} $i_2${\tt,} \dots{\tt,}
$i_n${\tt]}}$$
donde {\it nombre} es el nombre simbólico del objeto conjunto e $i_1$, $i_2$,
\dots, $i_n$ son subíndices.

Cada subíndice debe ser una expresión numérica o simbólica. El número de subíndices en la lista de subíndices debe coincidir con la dimensión del objeto conjunto al cual está asociada la lista de subíndices.

Los valores corrientes de las expresiones de los subíndices se usan para identificar un miembro particular del objeto conjunto que determina el conjunto resultante.

\subsection{Conjuntos ``aritméticos''}

La expresión de conjunto primaria que constituye un conjunto ``aritmético'' tiene las dos formas sintácticas siguientes:
$$
{\def\arraystretch{1.4}
\begin{array}{l}
\mbox{$t_0$ {\tt..} $t_1$ {\tt by} $\delta t$}\\
\mbox{$t_0$ {\tt..} $t_1$}\\
\end{array}
}
$$
donde $t_0$, $t_1$ y $\delta t$ son expresiones numéricas (el valor de
$\delta t$ no debe ser cero). La segunda forma es equivalente a la primera con $\delta t=1$.

Si $\delta t>0$, el conjunto resultante se determina como sigue:
$$\{t:\exists k\in{\cal Z}(t=t_0+k\delta t,\ t_0\leq t\leq t_1)\}.$$
De otro modo, si $\delta t<0$, el conjunto resultante se determina como sigue:
$$\{t:\exists k\in{\cal Z}(t=t_0+k\delta t,\ t_1\leq t\leq t_0)\}.$$

\subsection{Expresiones de indización}

Si la expresión de conjunto primaria es una expresión indizante, el conjunto resultante se determina como se ha descripto anteriormente en la Sección \ref{indexing}, página \pageref{indexing}.

\subsection{Expresiones iteradas}

Una {\it expresión de conjunto iterada} es una expresión de conjunto primaria que tiene la siguiente forma sintáctica:
$$\mbox{{\tt setof} {\it expresión-indizante} {\it integrando}}$$
donde {\it expresión-indizante} es una expresión indizante  que introduce índices y controla la iteración e {\it integrando} es tanto una expresión numérica o simbólica individual como una lista de expresiones numéricas o simbólicas separadas por coma y encerradas entre paréntesis.

Si el integrando es una expresión numérica o simbólica individual, el conjunto resultante está compuesto por 1-tuplos y se determina como sigue:
$$\{x:(i_1,\dots,i_n)\in\Delta\},$$
\noindent donde $x$ es un valor del integrando, $i_1$, \dots, $i_n$ son índices introducidos en la expresión indizante y $\Delta$ es el dominio, un conjunto de $n$-tuplos especificados por la expresión indizante que define los valores particulares asignados a los índices para realizar la operación iterada.

Si el integrando es una lista conteniendo $m$ expresiones numéricas y simbólicas, el conjunto resultante está compuesto por $m$-tuplos y se determina como sigue:
$$\{(x_1,\dots,x_m):(i_1,\dots,i_n)\in\Delta\},$$
donde $x_1$, \dots, $x_m$ son valores de las expresiones en la lista de integrandos e $i_1$, \dots, $i_n$ y $\Delta$ tienen el mismo significado anterior.

\subsection{Expresiones condicionales}

Una {\it expresión de conjunto condicional} es una expresión de conjunto primaria que tiene la siguiente forma sintáctica:
$$\mbox{{\tt if} $b$ {\tt then} $X$ {\tt else} $Y$}$$
donde $b$ es una expresión lógica y $X$ e $Y$ son expresiones de conjunto que deben definir conjuntos de igual dimensión.

El valor resultante de la expresión condicional depende del valor de la expresión lógica que sigue a la palabra clave {\tt if}. Si toma el valor {\it verdadero}, el conjunto resultante es el valor de la expresión que sigue a la palabra clave {\tt then}. De otro modo, si la expresión lógica toma el valor {\it falso}, el conjunto resultante es el valor de la expresión que sigue a la palabra clave {\tt else}.

\subsection{Expresiones parentéticas}

Cualquier expresión de conjunto puede encerrarse entre paréntesis, lo que la convierte sintácticamente en una expresión de conjunto primaria.

Los paréntesis pueden usarse en expresiones de conjunto, como en el álgebra, para especificar el orden deseado en el cual se ejecutarán las operaciones. Cuando se usan paréntesis, la expresión entre paréntesis se evalúa antes que el valor resultante sea usado.

El valor resultante de la expresión parentética es idéntico al valor de la expresión encerrada entre paréntesis.

\subsection{Operadores de conjunto}

En MathProg existen los siguientes operadores de conjunto, los que se pueden usar en expresiones de conjunto:

\begin{tabular}{@{}ll@{}}
$X$ {\tt union} $Y$&union $X\cup Y$\\
$X$ {\tt diff} $Y$&diferencia $X\backslash Y$\\
$X$ {\tt symdiff} $Y$&diferencia simétrica $X\oplus Y=(X\backslash Y)\cup(Y\backslash X)$\\
$X$ {\tt inter} $Y$&intersección $X\cap Y$\\
$X$ {\tt cross} $Y$&producto cartesiano (``cruzado'') $X\times Y$\\
\end{tabular}

\noindent donde $X$ e $Y$ son expresiones de conjunto que deben definir conjuntos de la misma dimensión (excepto para el producto cartesiano).

Si la expresión incluye más de un operador de conjunto, todos los operadores se ejecutan de izquierda a derecha, de acuerdo con la jerarquía de las operaciones (ver más adelante).

El valor resultante de la expresión que contiene operadores de conjunto es el resultado de aplicar los operadores a sus operandos.

La dimensión del conjunto resultante, {\it i.e.} la dimensión de los $n$-tuplos de los que consiste el conjunto resultante, es la dimensión de los operandos, excepto en el producto cartesiano, en la que la dimensión del conjunto resultante es la suma de las dimensiones de sus operandos.

\subsection{Jerarquía de las operaciones}

La siguiente lista muestra la jerarquía de las operaciones en expresiones de conjunto:

\noindent\hfil
\begin{tabular}{@{}ll@{}}
Operación&Jerarquía\\
\hline
Evaluación de operaciones numéricas&
1.{\textsuperscript{\b{a}}}-7.{\textsuperscript{\b{a}}}\\
Evaluación de operaciones simbólicas&
8.{\textsuperscript{\b{a}}}-9.{\textsuperscript{\b{a}}}\\
Evaluación de conjuntos iterados o ``aritméticos'' ({\tt setof}, {\tt..})&
10.{\textsuperscript{\b{a}}}\\
Producto cartesiano ({\tt cross})&
11.{\textsuperscript{\b{a}}}\\
Intersección ({\tt inter})&
12.{\textsuperscript{\b{a}}}\\
Unión y diferencia ({\tt union}, {\tt diff}, {\tt symdiff})&
13.{\textsuperscript{\b{a}}}\\
Evaluación condicional ({\tt if} \dots {\tt then} \dots {\tt else})&
14.{\textsuperscript{\b{a}}}\\
\end{tabular}

Esta jerarquía tiene el mismo significado que se explicó anteriormente para expresiones numéricas (ver Subsección \ref{hierarchy}, página \pageref{hierarchy}).

\section{Expresiones lógicas}

Una {\it expresión lógica} es una regla para calcular un valor lógico individual, el que puede ser tanto {\it verdadero} como {\it falso}.

La expresión lógica primaria puede ser una expresión numérica, una expresión relacional, una expresión lógica iterada u otra expresión lógica encerrada entre paréntesis.

\para{Ejemplos}

\noindent
\begin{tabular}{@{}ll@{}}
\verb|i+1| &(expresión numérica)\\
\verb|a[i,j] < 1.5| &(expresión relacional)\\
\verb|s[i+1,j-1] <> 'Mar' & anho | &(expresión relacional)\\
\verb|(i+1,'Ene') not in I cross J| &(expresión relacional)\\
\verb|S union T within A[i] inter B[j]| &(expresión relacional)\\
\verb|forall{i in I, j in J} a[i,j] < .5 * b[i]| &(expresión lógica iterada)\\
\verb|(a[i,j] < 1.5 or b[i] >= a[i,j])| &(expresión lógica parentética)\\
\end{tabular}

Empleando ciertos operadores lógicos se pueden construir expresiones lógicas más generales conteniendo dos o más expresiones lógicas primarias.

\para{Ejemplos}

\begin{verbatim}
not (a[i,j] < 1.5 or b[i] >= a[i,j]) and (i,j) in S
(i,j) in S or (i,j) not in T diff U
\end{verbatim}

\vspace*{-8pt}

\subsection{Expresiones numéricas}

El valor resultante de una expresión lógica primaria, cuando es una expresión numérica, es {\it verdadero} si el valor resultante de la expresión numérica es distinto de cero. De otro modo, el valor resultante de la expresión lógica es {\it falso}.

\vspace*{-8pt}

\subsection{Operadores relacionales}

En MathProg existen los siguientes operadores relacionales, los que se pueden usar en expresiones lógicas:

\begin{tabular}{@{}ll@{}}
$x$ {\tt<} $y$&comprueba si $x<y$\\
$x$ {\tt<=} $y$&comprueba si $x\leq y$\\
$x$ {\tt=} $y$, $x$ {\tt==} $y$&comprueba si $x=y$\\
$x$ {\tt>=} $y$&comprueba si $x\geq y$\\
$x$ {\tt>} $y$&comprueba si $x>y$\\
$x$ {\tt<>} $y$, $x$ {\tt!=} $y$&comprueba si $x\neq y$\\
$x$ {\tt in} $Y$&comprueba si $x\in Y$\\
{\tt(}$x_1${\tt,}\dots{\tt,}$x_n${\tt)} {\tt in} $Y$&comprueba si
$(x_1,\dots,x_n)\in Y$\\
$x$ {\tt not} {\tt in} $Y$, $x$ {\tt!in} $Y$&comprueba si $x\not\in Y$\\
{\tt(}$x_1${\tt,}\dots{\tt,}$x_n${\tt)} {\tt not} {\tt in} $Y$,
{\tt(}$x_1${\tt,}\dots{\tt,}$x_n${\tt)} {\tt !in} $Y$&comprueba si
$(x_1,\dots,x_n)\not\in Y$\\
$X$ {\tt within} $Y$&comprueba si $X\subseteq Y$\\
$X$ {\tt not} {\tt within} $Y$, $X$ {\tt !within} $Y$&comprueba si
$X\not\subseteq Y$\\
\end{tabular}

\noindent donde $x$, $x_1$, \dots, $x_n$ e $y$ son expresiones numéricas o simbólicas, mientras que $X$ e $Y$ son expresiones de conjunto.

Notas:

1. En las operaciones {\tt in}, {\tt not in} y {\tt !in} el número de componentes del primer operando debe ser igual a la dimensión del segundo operando.

2. En las operaciones {\tt within}, {\tt not within} y {\tt !within} ambos operandos deben tener la misma dimensión.

Todos los operadores relacionales listados anteriormente tienen su significado matemático convencional. El valor resultante es {\it verdadero} si los operandos satisfacen la correspondiente relación, o es {\it falso} en caso contrario. (Debe notarse que los valores simbólicos se ordenan lexicográficamente y que cualquier valor numérico precede a cualquier valor simbólico.)

\subsection{Expresiones iteradas}

Una {\it expresión lógica iterada} es una expresión lógica primaria que tiene la siguiente forma sintáctica:
$$\mbox{{\it operador-iterado} {\it expresión-indizante}
{\it integrando}}$$
donde {\it operador-iterado} es el nombre simbólico del operador iterado que se ejecutará (ver más adelante), {\it expresión-indizante} es una expresión indizante que introduce índices y controla la iteración e {\it integrando} es una expresión lógica que participa en la operación.

En MathProg existen dos operadores iterados que se pueden usar en expresiones lógicas:

{\def\arraystretch{1.4}
\noindent\hfil
\begin{tabular}{@{}lll@{}}
{\tt forall}&cuantificador-$\forall$&$\displaystyle
\forall(i_1,\dots,i_n)\in\Delta[f(i_1,\dots,i_n)],$\\
{\tt exists}&cuantificador-$\exists$&$\displaystyle
\exists(i_1,\dots,i_n)\in\Delta[f(i_1,\dots,i_n)],$\\
\end{tabular}
}

\noindent donde $i_1$, \dots, $i_n$ son índices introducidos en la expresión indizante, $\Delta$ es el dominio, un conjunto de $n$-tuplos especificados por la expresión indizante que define los valores particulares asignados a los índices para ejecutar la operación iterada y $f(i_1,\dots,i_n)$ es el integrando, una expresión lógica cuyo valor resultante depende de los índices.

Para el cuantificador-$\forall$, el valor resultante de la expresión lógica iterada es {\it verdadero} si el valor del integrando es {\it verdadero} para todos los $n$-tuplos contenidos en el dominio, de otro modo es {\it falso}.

Para el cuantificador-$\exists$, el valor resultante de la expresión lógica iterada es {\it falso} si el valor del integrando es {\it falso} para todos los $n$-tuplos contenidos en el dominio, de otro modo es {\it verdadero}.

\subsection{Expresiones parentéticas}

Cualquier expresión lógica puede encerrarse entre paréntesis, lo que la convierte sintácticamente en una expresión lógica primaria.

Los paréntesis pueden usarse en expresiones lógicas, como en el álgebra, para especificar el orden deseado en el cual se ejecutarán las operaciones. Cuando se usan paréntesis, la expresión entre paréntesis se evalúa antes que el valor resultante sea usado.

El valor resultante de la expresión parentética es idéntico al valor de la expresión encerrada entre paréntesis.

\subsection{Operadores lógicos}

En MathProg existen los siguientes operadores lógicos, los que se pueden usar en expresiones lógicas:

\begin{tabular}{@{}ll@{}}
{\tt not} $x$, {\tt!}$x$&negación $\neg\ x$\\
$x$ {\tt and} $y$, $x$ {\tt\&\&} $y$&conjunción (``y'' lógico)
$x\;\&\;y$\\
$x$ {\tt or} $y$, $x$ {\tt||} $y$&disyunción (``o'' lógico)
$x\vee y$\\
\end{tabular}

\noindent donde $x$ e $y$ son expresiones lógicas.

Si la expresión incluye más de un operador lógico, todos los operadores se ejecutan de izquierda a derecha, de acuerdo con la jerarquía de las operaciones (ver más adelante). El valor resultante de la expresión que contiene operadores lógicos es el resultado de aplicar los operadores a sus operandos.

\subsection{Jerarquía de las operaciones}

La siguiente lista muestra la jerarquía de las operaciones en expresiones lógicas:

\noindent\hfil
\begin{tabular}{@{}ll@{}}
Operación&Jerarquía\\
\hline
Evaluación de operaciones numéricas&
1.{\textsuperscript{\b{a}}}-7.{\textsuperscript{\b{a}}}\\
Evaluación de operaciones simbólicas&
8.{\textsuperscript{\b{a}}}-9.{\textsuperscript{\b{a}}}\\
Evaluación de operaciones de conjuntos&
10.{\textsuperscript{\b{a}}}-14.{\textsuperscript{\b{a}}}\\
Operaciones relacionales ({\tt<}, {\tt<=}, etc.)&
15.{\textsuperscript{\b{a}}}\\
Negación ({\tt not}, {\tt!})&
16.{\textsuperscript{\b{a}}}\\
Conjunción ({\tt and}, {\tt\&\&})&
17.{\textsuperscript{\b{a}}}\\
Cuantificación-$\forall$ y -$\exists$ ({\tt forall}, {\tt exists})&
18.{\textsuperscript{\b{a}}}\\
Disyunción ({\tt or}, {\tt||})&
19.{\textsuperscript{\b{a}}}\\
\end{tabular}

Esta jerarquía tiene el mismo significado que se explicó anteriormente para expresiones numéricas (ver Subsección \ref{hierarchy}, página \pageref{hierarchy}).

\section{Expresiones lineales}

Una {\it expresión lineal} es una regla para calcular la denominada {\it forma lineal}, que es una función lineal (o afín) de variables elementales.

La expresión lineal primaria puede ser una variable no-indizada, una variable indizada, una expresión lineal iterada, una expresión lineal condicional u otra expresión lineal encerrada entre paréntesis.

También está permitido usar una expresión numérica como una expresión lineal primaria, en cuyo caso el valor resultante de la expresión numérica se convierte automáticamente a una forma lineal que incluye el término constante solamente.

\para{Ejemplos}

\noindent
\begin{tabular}{@{}ll@{}}
\verb|z| &(variable no-indizada)\\
\verb|x[i,j]| &(variable indizada)\\
\verb|sum{j in J} (a[i,j] * x[i,j] + 3 * y[i-1])| &
(expresión lineal iterada)\\
\verb|if i in I then x[i,j] else 1.5 * z + 3.25| &
(expresión lineal condicional)\\
\verb|(a[i,j] * x[i,j] + y[i-1] + .1)| &
(expresión lineal parentética)\\
\end{tabular}

Empleando ciertos operadores aritméticos se pueden construir expresiones lineales más generales conteniendo dos o más expresiones lineales primarias.

\para{Ejemplos}

\begin{verbatim}
2 * x[i-1,j+1] + 3.5 * y[k] + .5 * z
(- x[i,j] + 3.5 * y[k]) / sum{t in T} abs(d[i,j,t])
\end{verbatim}

\vspace*{-5pt}

\subsection{Variables no-indizadas}

Si la expresión lineal primaria es una variable no-indizada (que debe ser 0-dimensional), la forma lineal resultante es aquella variable no-indizada.

\vspace*{-5pt}

\subsection{Variables indizadas}

La expresión lineal primaria que se refiere a una variable indizada tiene la siguiente forma sintáctica:
$$\mbox{{\it nombre}{\tt[}$i_1${\tt,} $i_2${\tt,} \dots{\tt,}
$i_n${\tt]}}$$
donde {\it nombre} es el nombre simbólico de la variable del modelo e $i_1$,
$i_2$, \dots, $i_n$ son subíndices.

Cada subíndice debe ser una expresión numérica o simbólica. El número de subíndices en la lista de subíndices debe ser igual a la dimensión de la variable del modelo con la cual está asociada la lista de subíndices.

Los valores corrientes de las expresiones de los subíndices se usan para identificar un miembro particular de la variable del modelo que determina la forma lineal resultante, la cual es una variable elemental asociada con el miembro correspondiente.

\vspace*{-5pt}

\subsection{Expresiones iteradas}

Una {\it expresión lineal iterada} es una expresión lineal primaria que tiene la siguiente forma sintáctica:
$$\mbox{{\tt sum} {\it expresión-indizante} {\it integrando}}$$
donde {\it expresión-indizante} es una expresión indizante que introduce índices y controla la iteración e {\it integrando} es una expresión lineal que participa en la operación.

La expresión lineal iterada se evalúa exactamente de la misma manera que la expresión numérica iterada (ver Subsección \ref{itexpr}, página
\pageref{itexpr}), excepto que el integrando participante en la sumatoria es una forma lineal y no un valor numérico.

\vspace*{-5pt}

\subsection{Expresiones condicionales}

Una {\it expresión lineal condicional} es una expresión lineal primaria que tiene alguna de las dos formas sintácticas siguientes:
$$
{\def\arraystretch{1.4}
\begin{array}{l}
\mbox{{\tt if} $b$ {\tt then} $f$ {\tt else} $g$}\\
\mbox{{\tt if} $b$ {\tt then} $f$}\\
\end{array}
}
$$
donde $b$ es una expresión lógica, mientras que $f$ y $g$ son expresiones lineales.

La expresión lineal condicional se evalúa exactamente de la misma manera que la expresión numérica condicional (ver Subsección \ref{ifthen}, página \pageref{ifthen}), excepto que los operandos participantes en la operación son formas lineales y no valores numéricos.

\subsection{Expresiones parentéticas}

Cualquier expresión lineal puede encerrarse entre paréntesis, lo que la convierte sintácticamente en una expresión lineal primaria.

Los paréntesis pueden usarse en expresiones lineales, como en el álgebra, para especificar el orden deseado en el cual se ejecutarán las operaciones. Cuando se usan paréntesis, la expresión entre paréntesis se evalúa antes que el valor resultante sea usado.

El valor resultante de la expresión parentética es idéntico al valor de la expresión encerrada entre paréntesis.

\subsection{Operadores aritméticos}

En MathProg existen los siguientes operadores aritméticos, los que se pueden usar en expresiones lineales:

\begin{tabular}{@{}ll@{}}
{\tt+} $f$&más unario\\
{\tt-} $f$&menos unario\\
$f$ {\tt+} $g$&adición\\
$f$ {\tt-} $g$&sustracción\\
$x$ {\tt*} $f$, $f$ {\tt*} $x$&multiplicación\\
$f$ {\tt/} $x$&división
\end{tabular}

\noindent donde $f$ y $g$ son expresiones lineales, mientras que $x$ es una expresión numérica (más precisamente, una expresión lineal conteniendo únicamente el término constante).

Si la expresión incluye más de un operador aritmético, todos los operadores se ejecutan de izquierda a derecha, de acuerdo con la jerarquía de las operaciones (ver más adelante). El valor resultante de la expresión que contiene operadores aritméticos es el resultado de aplicar los operadores a sus operandos.

\subsection{Jerarquía de las operaciones}

La jerarquía de las operaciones aritméticas usadas en las expresiones lineales es la misma que en las expresiones numéricas (ver Subsección \ref{hierarchy},
página \pageref{hierarchy}).

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\chapter{Sentencias}

Las {\it sentencias} son unidades básicas de la descripción del modelo. En MathProg todas las sentencias se clasifican en dos categorías: sentencias declarativas y sentencias funcionales.

Las {\it sentencias declarativas} (sentencia {\it set}, sentencia {\it parameter}, sentencia {\it variable}, sentencia {\it constraint} y sentencia {\it objective}) se usan para declarar objetos de cierto tipo del modelo y definir ciertas propiedades de tales objetos.

Las {\it sentencias funcionales} (sentencia {\it solve}, sentencia {\it check}, sentencia {\it display}, sentencia {\it printf}, sentencia {\it loop} y sentencia {\it table}) están ideadas para ejecutar ciertas acciones específicas.

Debe notarse que las sentencias declarativas pueden seguir cualquier orden arbitrario, lo cual no afecta el resultado de la traducción. Sin embargo, todos los objetos del modelo deben ser declarados antes de ser referenciados en otras sentencias.

\section{Sentencia set}

\noindent
\framebox[468pt][l]{
\parbox[c][24pt]{468pt}{
\hspace{6pt} {\tt set} {\it nombre} {\it alias} {\it dominio} {\tt,}
{\it atributo} {\tt,} \dots {\tt,} {\it atributo} {\tt;}
}}

\medskip

\noindent
{\it nombre} es el nombre simbólico del conjunto;

\noindent
{\it alias} es un literal de cadena opcional que especifica un alias para el conjunto;

\noindent
{\it dominio} es una expresión-indizante opcional que especifica el dominio del subíndice del conjunto;

\noindent
{\it atributo}, \dots, {\it atributo} son atributos opcionales del conjunto (las comas que preceden a los atributos se pueden omitir).

\para{Atributos opcionales}

\vspace*{-8pt}

\begin{description}
\item[{\tt dimen} $n$]\hspace*{0pt}\\
especifica la dimensión de los $n$-tuplos de los que consiste el conjunto;
\item[{\tt within} {\it expresión}]\hspace*{0pt}\\
especifica un superconjunto que restringe al conjunto o a todos sus miembros (conjuntos elementales) a estar incluido en aquel superconjunto;
\item[{\tt:=} {\it expresión}]\hspace*{0pt}\\
especifica un conjunto elemental asignado al conjunto o sus miembros;
\item[{\tt default} {\it expresión}]\hspace*{0pt}\\
especifica un conjunto elemental asignado al conjunto o sus miembros cuando no haya datos apropiados disponibles en la sección de datos.
\end{description}

\vspace*{-8pt}

\para{Ejemplos}

\begin{verbatim}
set nodos;
set arcos within nodos cross nodos;
set paso{p in 1..maxiter} dimen 2 := if p = 1 then arcos else paso[p-1]
   union setof{k in nodos, (i,k) in paso[p-1], (k,j) in paso[p-1]}(i,j);
set A{i in I, j in J}, within B[i+1] cross C[j-1], within D diff E,
   default {('abc',123), (321,'cba')};
\end{verbatim}

La sentencia set declara un conjunto. Si no se especifica el dominio del subíndice, el conjunto será simple, de otro modo será un arreglo de conjuntos elementales.

El atributo {\tt dimen} especifica la dimensión de los $n$-tuplos de los que consiste el conjunto (si es un conjunto simple) o sus miembros (si el conjunto es un arreglo de conjuntos elementales), en la que $n$ debe ser un entero sin signo desde 1 hasta 20. Como mucho se puede especificar un atributo {\tt dimen}. Si no se especifica el atributo {\tt dimen}, la dimensión de los $n$-tuplos se determina implícitamente por otros atributos (por ejemplo, si hay una expresión de conjunto que sigue a {\tt :=} o a la palabra clave {\tt default}, se usará la dimensión de los $n$-tuplos del correspondiente conjunto elemental). Si no hay información disponible sobre la dimensión, se asume {\tt dimen 1}.

El atributo {\tt within} especifica una expresión de conjunto cuyo valor resultante es un superconjunto usado para restringir al conjunto (si es un conjunto simple) o a sus miembros (si el conjunto es un arreglo de conjuntos elementales) a estar incluido en aquel superconjunto. Se puede especificar un número arbitrario de atributos {\tt within} en la misma sentencia set.

El atributo de asignación ({\tt :=}) especifica una expresión de conjunto usada para evaluar conjuntos elementales asignados al conjunto (si es un conjunto simple) o sus miembros (si el conjunto es un arreglo de conjuntos elementales). Si se especifica el atributo de asignación, el conjunto es {\it calculable} y consecuentemente no es necesario proveerle datos en la sección de datos. Si no se especifica el atributo de asignación, entonces se deben proveer datos para el conjunto en la sección de datos. Como mucho, se puede especificar una asignación o un atributo {\tt default} para el mismo conjunto.

El atributo {\tt default} especifica una expresión de conjunto usada para evaluar conjuntos elementales asignados al conjunto (si es un conjunto simple) o sus miembros (si el conjunto es un arreglo de conjuntos elementales) toda vez que no haya datos apropiados disponibles en la sección de datos. Si no se especifica una asignación o un atributo {\tt default}, la carencia de datos causará un error.

\newpage

\section{Sentencia parameter}

\noindent
\framebox[468pt][l]{
\parbox[c][24pt]{468pt}{
\hspace{6pt} {\tt param} {\it nombre} {\it alias} {\it dominio} {\tt,}
{\it atributo} {\tt,} \dots {\tt,} {\it atributo} {\tt;}
}}

\medskip

\noindent
{\it nombre} es el nombre simbólico del parámetro;

\noindent
{\it alias} es un literal de cadena opcional que especifica un alias para el parámetro;

\noindent
{\it dominio} es una expresión indizante opcional que especifica el dominio del subíndice del parámetro;

\noindent
{\it atributo}, \dots, {\it atributo} son atributos opcionales del parámetro (las comas que preceden a los atributos se pueden omitir).

\para{Atributos opcionales}

\vspace*{-8pt}

\begin{description}
\item[{\tt integer}]\hspace*{0pt}\\
especifica que el parámetro es entero;
\item[{\tt binary}]\hspace*{0pt}\\
especifica que el parámetro es binario;
\item[{\tt symbolic}]\hspace*{0pt}\\
especifica que el parámetro es simbólico;
\item[{\it relación expresión}]\hspace*{0pt}\\
(donde {\it relación} es alguno de: {\tt<}, {\tt<=}, {\tt=}, {\tt==},
{\tt>=}, {\tt>}, {\tt<>}, {\tt!=})\\
especifica una condición que restringe al parámetro o a sus miembros a satisfacer aquella condición;
\item[{\tt in} {\it expresión}]\hspace*{0pt}\\
especifica un superconjunto que restringe al parámetro o a sus miembros a estar incluidos en aquel superconjunto;
\item[{\tt:=} {\it expresión}]\hspace*{0pt}\\
especifica un valor asignado al parámetro o a sus miembros;
\item[{\tt default} {\it expresión}]\hspace*{0pt}\\
especifica un valor asignado al parámetro o a sus miembros cuando no haya datos apropiados disponibles en la sección de datos.
\end{description}

\vspace*{-8pt}

\para{Ejemplos}

\begin{verbatim}
param unidades{insumo,producto} >= 0;
param ganancia{producto, 1..T+1};
param N := 20 integer >= 0 <= 100;
param combinacion 'n elige k' {n in 0..N, k in 0..n} :=
   if k = 0 or k = n then 1 else combinacion[n-1,k-1] + combinacion[n-1,k];
param p{i in I, j in J}, integer, >= 0, <= i+j, in A[i] symdiff B[j],
   in C[i,j], default 0.5 * (i + j);
param mes symbolic default 'May' in {'Mar', 'Abr', 'May'};
\end{verbatim}

La sentencia parameter declara un parámetro. Si el dominio del subíndice no se especifica, el parámetro es un parámetro simple (escalar); de otro modo es un arreglo $n$-dimensional.

Los atributos de tipo {\tt integer}, {\tt binary} y {\tt symbolic} califican el tipo de valores que se le puede asignar al parámetro como se muestra a continuación:

\noindent\hfil
\begin{tabular}{@{}ll@{}}
Atributo de tipo&Valores asignado\\
\hline
(no especificado)&Cualquier valor numérico\\
{\tt integer}&Solamente valores numéricos enteros\\
{\tt binary}&Tanto 0 como 1\\
{\tt symbolic}&Cualquier valor numérico y simbólico\\
\end{tabular}

El atributo {\tt symbolic} no se puede especificar junto con otros atributos de tipo. Cuando se especifica debe preceder a todos los demás atributos.

El atributo de condición especifica una condición opcional que restringe los valores asignados al parámetro a satisfacer esta condición. Este atributo tiene las siguientes formas sintácticas:

\begin{tabular}{@{}ll@{}}
{\tt<} $v$&comprueba si $x<v$\\
{\tt<=} $v$&comprueba si $x\leq v$\\
{\tt=} $v$, {\tt==} $v$&comprueba si $x=v$\\
{\tt>=} $v$&comprueba si $x\geq v$\\
{\tt>} $v$&comprueba si $x\geq v$\\
{\tt<>} $v$, {\tt!=} $v$&comprueba si $x\neq v$\\
\end{tabular}

\noindent donde $x$ es un valor asignado al parámetro y $v$ es el valor resultante de una expresión numérica o simbólica especificada en el atributo de condición. Se puede especificar un número arbitrario de atributos de condición para el mismo parámetro. Si el valor que se está asignando al parámetro durante la evaluación del modelo viola al menos una de las condiciones especificadas, se producirá un error. (Debe notarse que los valores simbólicos se ordenan lexicográficamente y que cualquier valor numérico precede a cualquier valor simbólico.)

El atributo {\tt in} es semejante al atributo de condición y especifica una expresión de conjunto cuyo valor resultante es un superconjunto usado para restringir los valores numéricos o simbólicos asignados al parámetro a estar incluidos en aquel superconjunto. Se puede especificar un número arbitrario de atributos {\tt in} para el mismo parámetro. Si el valor que se está asignando al parámetro durante la evaluación del modelo no pertenece al menos a uno de los superconjuntos especificados, se producirá un error.

El atributo de asignación ({\tt:=}) especifica una expresión numérica o simbólica usada para calcular un valor asignado al parámetro (si es un parámetro simple) o a sus miembros (si el parámetro es un arreglo). Si se especifica el atributo de asignación, el parámetro es {\it calculable} y consecuentemente no es necesario proveer datos en la sección de datos. Si no se especifica el atributo de asignación, entonces se deben proveer datos para el parámetro en la sección de datos. Como mucho, se puede especificar una asignación o un atributo {\tt default} para el mismo conjunto.

El atributo {\tt default} especifica una expresión numérica o simbólica que se usa para calcular un valor asignado al parámetro o a sus miembros, toda vez que no haya datos apropiados disponibles en la sección de datos. Si no se especifica una asignación ni un atributo {\tt default}, la carencia de datos causará un error.

\section{Sentencia variable}

\noindent
\framebox[468pt][l]{
\parbox[c][24pt]{468pt}{
\hspace{6pt} {\tt var} {\it nombre} {\it alias} {\it dominio} {\tt,}
{\it atributo} {\tt,} \dots {\tt,} {\it atributo} {\tt;}
}}

\medskip

\noindent
{\it nombre} es el nombre simbólico de la variable;

\noindent
{\it alias} es un literal de cadena opcional que especifica un alias para la variable;

\noindent
{\it dominio} es una expresión indizante opcional que especifica el dominio del subíndice de la variable;

\noindent
{\it atributo}, \dots, {\it atributo} son atributos opcionales de la variable (las comas que preceden a los atributos se pueden omitir).

\para{Atributos opcionales}

\vspace*{-8pt}

\begin{description}
\item[{\tt integer}]\hspace*{0pt}\\
restringe la variable a ser entera;
\item[{\tt binary}]\hspace*{0pt}\\
restringe la variable a ser binaria;
\item[{\tt>=} {\it expresión}]\hspace*{0pt}\\
especifica una cota inferior para la variable;
\item[{\tt<=} {\it expresión}]\hspace*{0pt}\\
especifica una cota superior para la variable;
\item[{\tt=} {\it expresión}]\hspace*{0pt}\\
especifica un valor fijo para la variable.
\end{description}

\vspace*{-8pt}

\para{Ejemplos}

\begin{verbatim}
var x >= 0;
var y{I,J};
var elaborar{p in producto}, integer, >= compromiso[p], <= mercado[p];
var almacenar{insumo, 1..T+1} >= 0;
var z{i in I, j in J} >= i+j;
\end{verbatim}

La sentencia variable declara una variable. Si no se especifica el dominio del subíndice, la variable es una variable simple (escalar); de otro modo es un arreglo $n$-dimensional de variables elementales.

Las variables elementales asociadas con una variable del modelo (si es una variable simple) o sus miembros (si es un arreglo) corresponde a las variables en la formulación del problema de PL/PEM (ver Sección \ref{problem}, página \pageref{problem}). Debe notarse que sólo variables elementales realmente referenciadas en algunas restricciones y/u objetivos se incluirán en la instancia del problema de PL/PEM que se generará.

Los atributos de tipo {\tt integer} y {\tt binary} restringen la variable a ser entera o binaria, respectivamente. Si no se especifica un atributo de tipo, la variable será continua. Si todas las variables en el modelo son continuas, el problema correspondiente será de la clase PL. Si hay al menos una variable entera o binaria, el problema será de la clase PEM.

El atributo de cota inferior ({\tt>=}) especifica una expresión numérica para calcular la cota inferior de la variable. Se puede especificar una cota inferior como máximo. Por defecto, todas las variables no tienen cota inferior (excepto las binarias), de modo que si se requiere que sea no-negativa, su cota inferior cero debe especificarse explícitamente.

El atributo de cota superior ({\tt<=}) especifica una expresión numérica para calcular la cota superior de la variable. Se puede especificar una cota superior como máximo.

El atributo de valor fijo ({\tt=}) especifica una expresión numérica para calcular el valor en el cual se fijará la variable. Este atributo no puede especificarse junto con los atributos de cota.

\section{Sentencia constraint}

\noindent
\framebox[468pt][l]{
\parbox[c][106pt]{468pt}{
\hspace{6pt} {\tt s.t.} {\it nombre} {\it alias} {\it dominio} {\tt:}
{\it expresión} {\tt,} {\tt=} {\it expresión} {\tt;}

\medskip

\hspace{6pt} {\tt s.t.} {\it nombre} {\it alias} {\it dominio} {\tt:}
{\it expresión} {\tt,} {\tt<=} {\it expresión} {\tt;}

\medskip

\hspace{6pt} {\tt s.t.} {\it nombre} {\it alias} {\it dominio} {\tt:}
{\it expresión} {\tt,} {\tt>=} {\it expresión} {\tt;}

\medskip

\hspace{6pt} {\tt s.t.} {\it nombre} {\it alias} {\it dominio} {\tt:}
{\it expresión} {\tt,} {\tt<=} {\it expresión} {\tt,} {\tt<=}
{\it expresión} {\tt;}

\medskip

\hspace{6pt} {\tt s.t.} {\it nombre} {\it alias} {\it dominio} {\tt:}
{\it expresión} {\tt,} {\tt>=} {\it expresión} {\tt,} {\tt>=}
{\it expresión} {\tt;}
}}

\medskip

\noindent
{\it nombre} es el nombre simbólico de la restricción;

\noindent
{\it alias} es un literal de cadena opcional que especifica un alias para la restricción;

\noindent
{\it dominio} es una expresión indizante opcional que especifica el dominio del subíndice de la restricción;

\noindent
{\it expresión} es una expresión lineal usada para calcular un componente de la restricción (las comas que siguen a las expresiones pueden omitirse).

\noindent
(La palabra clave {\tt s.t.} se puede escribir como {\tt subject to}, o como {\tt subj to} o ser completamente omitida.)

\para{Ejemplos}

\begin{verbatim}
s.t. r: x + y + z, >= 0, <= 1;
limite{t in 1..T}: sum{j in producto} elaborar[j,t] <= max_producto;
subject to balance{i in insumo, t in 1..T}:
   almacenar[i,t+1] = almacenar[i,t] -
   sum{j in producto} unidades[i,j] * elaborar[j,t];
subject to ltn 'limite tiempo normal' {t in tiempo}:
   sum{p in producto} pt[p] * rprd[p,t] <= 1.3 * dpp[t] * brigadas[t];
\end{verbatim}

La sentencia constraint declara una restricción. Si no se especifica el dominio del subíndice, la restricción es una restricción simple (escalar); de otro modo, es un arreglo $n$-dimensional de restricciones elementales.

Las restricciones elementales asociadas con la restricción del modelo (si es una restricción simple) o sus miembros (si es un arreglo) corresponde a las restricciones lineales en la formulación del problema de PL/PEM (ver Sección \ref{problem}, página \pageref{problem}).

Si la restricción tiene la forma de una igualdad o desigualdad simple, {\it i.e.} incluye dos expresiones, una de las cuales está a continuación de los dos puntos y la otra está a continuación del signo relacional {\tt=}, {\tt<=} o {\tt>=}, ambas expresiones de la sentencia pueden ser expresiones lineales. Si la restricción tiene la forma de una doble desigualdad, {\it i.e.} incluye tres expresiones, la expresión del medio puede ser una expresión lineal mientras que la de la izquierda y la de la derecha sólo pueden ser expresiones numéricas.

Generar el modelo es, groseramente hablando, generar sus restricciones, las que son siempre evaluadas para todo el dominio del subíndice. A su vez, la evaluación de las restricciones lleva a la evaluación de otros objetos del modelo tales como los conjuntos, los parámetros y las variables.

La construcción de una restricción lineal real incluida en la instancia del problema, la cual corresponde a una restricción elemental particular, se realiza como sigue.

Si la restricción tiene la forma de una igualdad o desigualdad simple, la evaluación de ambas expresiones lineales resulta en dos formas lineales:
$$\begin{array}{r@{\ }c@{\ }r@{\ }c@{\ }r@{\ }c@{\ }r@{\ }c@{\ }r}
f&=&a_1x_1&+&a_2x_2&+\dots+&a_nx_n&+&a_0,\\
g&=&b_1x_1&+&b_2x_2&+\dots+&b_nx_n&+&b_0,\\
\end{array}$$
donde $x_1$, $x_2$, \dots, $x_n$ son variables elementales; $a_1$, $a_2$,
\dots, $a_n$, $b_1$, $b_2$, \dots, $b_n$ son coeficientes numéricos y
$a_0$ y $b_0$ son términos constantes. Luego, todos los términos lineales de $f$ y $g$ se llevan al lado izquierdo y los términos constantes se llevan al lado derecho, para dar la restricción elemental final en forma estándar:
$$(a_1-b_1)x_1+(a_2-b_2)x_2+\dots+(a_n-b_n)x_n\left\{
\begin{array}{@{}c@{}}=\\\leq\\\geq\\\end{array}\right\}b_0-a_0.$$

Si la restricción tiene la forma de una doble desigualdad, la evaluación de la expresión lineal del medio resulta en una forma lineal:
$$f=a_1x_1+a_2x_2+\dots+a_nx_n+a_0,$$
y la evaluación de las expresiones numéricas de la izquierda y de la derecha dará dos valores numéricos $l$ y $u$, respectivamente. Luego, el término constante de la forma lineal se lleva tanto a la izquierda como a la derecha para dar la restricción elemental final en forma estándar:
$$l-a_0\leq a_1x_1+a_2x_2+\dots+a_nx_n\leq u-a_0.$$

\section{Sentencia objective}

\noindent
\framebox[468pt][l]{
\parbox[c][44pt]{468pt}{
\hspace{6pt} {\tt minimize} {\it nombre} {\it alias} {\it dominio} {\tt:}
{\it expresión} {\tt;}

\medskip

\hspace{6pt} {\tt maximize} {\it nombre} {\it alias} {\it dominio} {\tt:}
{\it expresión} {\tt;}
}}

\medskip

\noindent
{\it nombre} es el nombre simbólico del objetivo;

\noindent
{\it alias} es un literal de cadena opcional que especifica un alias para el objetivo;

\noindent
{\it dominio} es una expresión indizante opcional que especifica el dominio del subíndice del objetivo;

\noindent
{\it expresión} es una expresión lineal usada para calcular la forma lineal del objetivo.

\para{Ejemplos}

\begin{verbatim}
minimize objetivo: x + 1.5 * (y + z);
maximize ganancia_total: sum{p in producto} ganancia[p] * elaborar[p];
\end{verbatim}

La sentencia objective declara un objetivo. Si no se especifica el dominio del subíndice, el objetivo es un objetivo simple (escalar); de otro modo, es un arreglo $n$-dimensional de objetivos elementales.

Los objetivos elementales asociados con el objetivo del modelo (si es un objetivo simple) o sus miembros (si es un arreglo) corresponden a restricciones lineales generales en la formulación del problema de PL/PEM (ver Sección \ref{problem}, página \pageref{problem}). Sin embargo, a diferencia de las restricciones, las correspondientes formas lineales son libres (no tienen cota).

La construcción de una restricción lineal real incluida en la instancia del problema, la cual corresponde a una restricción elemental particular, se realiza como sigue. La expresión lineal especificada en la sentencia objective se evalúa para resultar en una forma lineal:
$$f=a_1x_1+a_2x_2+\dots+a_nx_n+a_0,$$
donde $x_1$, $x_2$, \dots, $x_n$ son variables elementales; $a_1$, $a_2$,
\dots, $a_n$ son coeficientes numéricos y $a_0$ es el término constante. Luego se usa la forma lineal para construir la restricción elemental final en forma estándar:
$$-\infty<a_1x_1+a_2x_2+\dots+a_nx_n+a_0<+\infty.$$

Como norma, la descripción del modelo contiene solamente una sentencia objective para definir la función objetivo usada en la instancia del problema. Sin embargo, se permite declarar un número arbitrario de objetivos, en cuyo caso la función objetivo real es el primer objetivo que se encuentra en la descripción del modelo. Otros objetivos también se incluyen en la instancia del problema pero ellos no afectan la función objetivo.

\section{Sentencia solve}

\noindent
\framebox[468pt][l]{
\parbox[c][24pt]{468pt}{
\hspace{6pt} {\tt solve} {\tt;}
}}

\medskip

La sentencia solve es opcional y puede usarse solamente una vez. Si no se usa la sentencia solve, se asume una al final de la sección del modelo.

La sentencia solve provoca que el modelo sea resuelto, lo que significa calcular los valores numéricos de todas las variables del modelo. Esto permite usar variables en sentencias luego de la sentencia solve, de la misma forma que si fuesen parámetros numéricos.

Debe notarse que las sentencias variable, constraint y objective no pueden usarse luego de la sentencia solve, {\it i.e.} todos los componentes principales del modelo deben ser declarados antes de la sentencia solve.

\section{Sentencia check}

\noindent
\framebox[468pt][l]{
\parbox[c][24pt]{468pt}{
\hspace{6pt} {\tt check} {\it dominio} {\tt:} {\it expresión} {\tt;}
}}

\medskip

\noindent
{\it dominio} es una expresión indizante opcional que especifica el dominio del subíndice de la sentencia check;

\noindent
{\it expresión} es una expresión lógica que especifica una condición lógica para ser comprobada (los dos puntos que preceden a {\it expresión} pueden omitirse).

\para{Ejemplos}

\begin{verbatim}
check: x + y <= 1 and x >= 0 and y >= 0;
check sum{i in ORIGEN} oferta[i] = sum{j in DESTINO} demanda[j];
check{i in I, j in 1..10}: S[i,j] in U[i] union V[j];
\end{verbatim}

El sentencia check permite comprobar el valor resultante de una expresión lógica especificada en la sentencia. Si el valor es {\it falso} se reporta un error.

Si el dominio del subíndice no se especifica, la comprobación se ejecuta solamente una vez. Especificar el dominio del subíndice permite ejecutar múltiples comprobaciones para cada $n$-tuplo en el conjunto dominio. En este último caso, la expresión lógica puede incluir índices introducidos en la correspondiente expresión indizante.

\section{Sentencia display}

\noindent
\framebox[468pt][l]{
\parbox[c][24pt]{468pt}{
\hspace{6pt} {\tt display} {\it dominio} {\tt:} {\it ítem} {\tt,}
\dots {\tt,} {\it ítem} {\tt;}
}}

\medskip

\noindent
{\it dominio} es una expresión indizante opcional que especifica el dominio del subíndice de la sentencia display;

\noindent
{\it ítem}, \dots, {\it ítem} son ítems que se mostrarán (los dos puntos que preceden al primer ítem pueden omitirse).

\para{Ejemplos}

\begin{verbatim}
display: 'x =', x, 'y =', y, 'z =', z;
display sqrt(x ** 2 + y ** 2 + z ** 2);
display{i in I, j in J}: i, j, a[i,j], b[i,j];
\end{verbatim}

La sentencia display  evalúa todos los ítems especificados en la sentencia y escribe sus valores en la salida estándar (terminal) en formato de texto plano.

Si el dominio del subíndice no se especifica, los ítems son evaluados y mostrados solamente una vez. Especificar el dominio del subíndice produce que los ítems sean evaluados y mostrados para cada $n$-tuplo en el conjunto dominio. En este último caso, los ítems pueden incluir índices introducidos en la correspondiente expresión indizante.

Un ítem a ser mostrado puede ser un objeto del modelo (conjunto, parámetro, variable, restricción u objetivo) o una expresión.

Si el ítem es un objeto calculable ({\it i.e.} un conjunto o parámetro provisto con el atributo de asignación), el mismo es evaluado a través de todo su dominio y luego se muestra su contenido ({\it i.e.} el contenido del arreglo de objetos). De otro modo, si el ítem no es un objeto calculable, solamente se muestra su contenido corriente ({\it i.e.} los miembros realmente generados durante la evaluación del modelo).

Si el ítem es una expresión, la misma se evalúa y se muestra su valor resultante.

\section{Sentencia printf}

\noindent
\framebox[468pt][l]{
\parbox[c][64pt]{468pt}{
\hspace{6pt} {\tt printf} {\it dominio} {\tt:} {\it formato} {\tt,}
{\it expresión} {\tt,} \dots {\tt,} {\it expresión} {\tt;}

\medskip

\hspace{6pt} {\tt printf} {\it dominio} {\tt:} {\it formato} {\tt,}
{\it expresión} {\tt,} \dots {\tt,} {\it expresión} {\tt>}
{\it archivo} {\tt;}

\medskip

\hspace{6pt} {\tt printf} {\it dominio} {\tt:} {\it formato} {\tt,}
{\it expresión} {\tt,} \dots {\tt,} {\it expresión} {\tt>}{\tt>}
{\it archivo} {\tt;}
}}

\medskip

\noindent
{\it dominio} es una expresión indizante opcional que especifica el dominio del subíndice de la sentencia printf;

\noindent
{\it formato} es una expresión simbólica cuyo valor especifica una cadena de control de formato (los dos puntos que preceden a la expresión de formato pueden omitirse).

\noindent
{\it expresión}, \dots, {\it expresión} son cero o más expresiones cuyos valores deben ser formateados e impresos. Cada expresión debe ser de tipo numérico, simbólico o lógico.

\noindent
{\it archivo} es una expresión simbólica cuyo valor especifica el nombre de un archivo de texto al cual se redirigirá la salida. La señal {\tt>} significa la creación de un archivo nuevo y vacío, mientras que la señal {\tt>}{\tt>} significa anexar la salida a un archivo existente. Si no se especifica un nombre de archivo, la salida se escribe en la salida estándar (terminal).

\para{Ejemplos}

\begin{verbatim}
printf 'Hola, mundo!\n';
printf: "x = %.3f; y = %.3f; z = %.3f\n", x, y, z > "resultado.txt";
printf{i in I, j in J}: "el flujo desde %s hacia %s es %d\n", i, j, x[i,j]
   >> archivo_resultados & ".txt";
printf{i in I} 'el flujo total de %s es %g\n', i, sum{j in J} x[i,j];
printf{k in K} "x[%s] = " & (if x[k] < 0 then "?" else "%g"),
   k, x[k];
\end{verbatim}

La sentencia printf es semejante a la sentencia display; sin embargo, la misma permite formatear los datos que se escribirán.

Si el dominio del subíndice no se especifica, la sentencia printf es ejecutada solamente una vez. Especificar el dominio del subíndice produce que la sentencia printf sea ejecutada para cada $n$-tuplo en el conjunto dominio. En este último caso, el formato y la expresión pueden incluir índices introducidos en la correspondiente expresión indizante.

La cadena de control de formato es el valor de la expresión simbólica {\it formato} especificado en la sentencia printf. Se compone con cero o más directivas como sigue: caracteres ordinarios (no {\tt\%}), que son copiados sin modificación al flujo de salida, y especificaciones de conversión, cada una de las cuales provoca la evaluación de la expresión correspondiente especificada en la sentencia printf, su formateo y la escritura del valor resultante en el flujo de salida.

Las especificaciones de conversión que se pueden usar en la cadena de control de formato son las siguientes: {\tt d}, {\tt i}, {\tt f}, {\tt F}, {\tt e}, {\tt E}, {\tt g}, {\tt G} y {\tt s}. Estas especificaciones tienen la misma semántica y sintaxis que en el lenguaje de programación C.

\section{Sentencia for}

\noindent
\framebox[468pt][l]{
\parbox[c][44pt]{468pt}{
\hspace{6pt} {\tt for} {\it dominio} {\tt:} {\it sentencia} {\tt;}

\medskip

\hspace{6pt} {\tt for} {\it dominio} {\tt:} {\tt\{} {\it sentencia}
\dots {\it sentencia} {\tt\}} {\tt;}
}}

\medskip

\noindent
{\it dominio} es una expresión indizante opcional que especifica el dominio del subíndice de la sentencia for (los dos puntos a continuación de la expresión indizante pueden omitirse);

\noindent
{\it sentencia} es una sentencia que será ejecutada bajo el control de la sentencia for;

\noindent
{\it sentencia}, \dots, {\it sentencia} es una secuencia de sentencias (encerrada entre llaves) que serán ejecutadas bajo el control de la sentencia for.

Solamente se pueden usar las siguientes sentencias dentro de la sentencia for: check, display, printf y otra sentencia for.

\para{Ejemplos}

\begin{verbatim}
for {(i,j) in E: i != j}
{  printf "el flujo desde %s hacia %s es %g\n", i, j, x[i,j];
   check x[i,j] >= 0;
}
for {i in 1..n}
{  for {j in 1..n} printf " %s", if x[i,j] then "Q" else ".";
   printf("\n");
}
for {1..72} printf("*");
\end{verbatim}

La sentencia for provoca que la sentencia o secuencia de sentencias especificadas como parte de la sentencia for sea ejecutada para cada $n$-tuplo en el conjunto dominio. De modo que las sentencias dentro de la sentencia for pueden incluir índices introducidos en la correspondiente expresión indizante.

\section{Sentencia table}

\noindent
\framebox[468pt][l]{
\parbox[c][80pt]{468pt}{
\hspace{6pt} {\tt table} {\it nombre} {\it alias} {\tt IN} {\it controlador}
{\it arg} \dots {\it arg} {\tt:}

\hspace{6pt} {\tt\ \ \ \ \ } {\it conjunto} {\tt<-} {\tt[} {\it cmp} {\tt,}
\dots {\tt,} {\it cmp} {\tt]} {\tt,} {\it par} {\tt\textasciitilde}
{\it cmp} {\tt,} \dots {\tt,} {\it par} {\tt\textasciitilde} {\it cmp}
{\tt;}

\medskip

\hspace{6pt} {\tt table} {\it nombre} {\it alias} {\it dominio} {\tt OUT}
{\it controlador} {\it arg} \dots {\it arg} {\tt:}

\hspace{6pt} {\tt\ \ \ \ \ } {\it expr} {\tt\textasciitilde} {\it cmp}
{\tt,} \dots {\tt,} {\it expr} {\tt\textasciitilde} {\it cmp} {\tt;}
}}

\medskip

\noindent
{\it nombre} es el nombre simbólico de la tabla;

\noindent
{\it alias} es un literal de cadena opcional que especifica un alias para la tabla;

\noindent
{\it dominio} es una expresión indizante que especifica el dominio del subíndice de la tabla (de salida);

\noindent
{\tt IN} significa leer datos desde la tabla de entrada;

\noindent
{\tt OUT} significa escribir datos en la tabla de salida;

\noindent
{\it controlador} es una expresión simbólica que especifica el controlador usado para acceder a la tabla (para más detalles, ver Apéndice \ref{drivers}, página \pageref{drivers});

\noindent
{\it arg} es una expresión simbólica opcional que es un argumento pasado al controlador de la tabla. Esta expresión simbólica no debe incluir índices especificados en el dominio;

\noindent
{\it conjunto} es el nombre de un conjunto simple opcional llamado {\it conjunto de control}. Puede ser omitido junto con el delimitador {\tt<-};

\noindent
{\it cmp} es un nombre de campo. Entre corchetes se debe especificar al menos un campo. El nombre de campo a continuación de un nombre de parámetro o de una expresión es opcional y puede ser omitido junto con el delimitador~{\tt\textasciitilde}, en cuyo caso el nombre del objeto del modelo que corresponda se usará como el nombre de campo;

\noindent
{\it par} es el nombre simbólico de un parámetro del modelo;

\noindent
{\it expr} es una expresión numérica o simbólica.

\para{Ejemplos}

\begin{verbatim}
table datos IN "CSV" "datos.csv": M <- [DESDE,HACIA], d~DISTANCIA,
   c~COSTO;
table resultado{(s,h) in M} OUT "CSV" "resultado.csv": s~DESDE, h~HACIA,
   x[s,h]~FLUJO;
\end{verbatim}

La sentencia table permite leer datos desde una tabla y asignarlos a objetos del modelo tales como conjuntos y parámetros (no escalares), al igual que escribir datos del modelo en una tabla.

\subsection{Estructura de tablas}

Una {\it tabla de datos} es un conjunto (desordenado) de {\it registros}, en el que cada registro consiste del mismo número de {\it campos}, y cada campo está provisto de un nombre simbólico único denominado {\it nombre de campo}. Por ejemplo:

\bigskip

\begin{tabular}{@{\hspace*{51mm}}c@{\hspace*{9mm}}c@{\hspace*{10mm}}c
@{\hspace*{7mm}}c}
Primer&Segundo&&Último\\
campo&campo&.\ \ .\ \ .&campo\\
$\downarrow$&$\downarrow$&&$\downarrow$\\
\end{tabular}

\begin{tabular}{ll@{}}
Encabezado de tabla&$\rightarrow$\\
Primer registro&$\rightarrow$\\
Segundo registro&$\rightarrow$\\
\\
\hfil .\ \ .\ \ .\\
\\
Último registro&$\rightarrow$\\
\end{tabular}
\begin{tabular}{|l|l|c|c|}
\hline
{\tt DESDE}&{\tt HACIA}&{\tt DISTANCIA}&{\tt COSTO}\\
\hline
{\tt Seattle}  &{\tt New-York}&{\tt 2.5}&{\tt 0.12}\\
{\tt Seattle}  &{\tt Chicago} &{\tt 1.7}&{\tt 0.08}\\
{\tt Seattle}  &{\tt Topeka}  &{\tt 1.8}&{\tt 0.09}\\
{\tt San-Diego}&{\tt New-York}&{\tt 2.5}&{\tt 0.15}\\
{\tt San-Diego}&{\tt Chicago} &{\tt 1.8}&{\tt 0.10}\\
{\tt San-Diego}&{\tt Topeka}  &{\tt 1.4}&{\tt 0.07}\\
\hline
\end{tabular}

\subsection{Lectura de datos desde una tabla de entrada}

La sentencia table de entrada produce la lectura de los datos desde la tabla especificada, registro por registro.

Una vez que se ha leído el próximo registro, los valores numéricos o simbólicos de los campos cuyos nombres se han encerrado entre corchetes en la sentencia table se reúnen en un $n$-tuplo y, si se ha especificado el conjunto de control en la sentencia table, este $n$-tuplo es agregado al mismo. Además, un valor numérico o simbólico de cada campo asociado con un parámetro del modelo se asigna al miembro del parámetro identificado por subíndices, los cuales son componentes del $n$-tuplo que se acaba de leer.

Por ejemplo, la siguiente sentencia table de entrada:

\noindent\hfil
\verb|table datos IN "...": M <- [DESDE,HACIA], d~DISTANCIA, c~COSTO;|

\noindent
produce la lectura de valores de cuatro campos llamados {\tt DESDE}, {\tt HACIA}, {\tt DISTANCIA} y {\tt COSTO} de cada registro de la tabla especificada. Los valores de los campos {\tt DESDE} y {\tt HACIA} proveen un par $(s,h)$ que se agrega al conjunto de control {\tt M}. El valor del campo {\tt DISTANCIA} se asigna al miembro del parámetro ${\tt d}[s,h]$ y el valor del campo {\tt COSTO} se asigna al miembro del parámetro ${\tt c}[s,h]$.

Debe notarse que la tabla de entrada puede contener campos adicionales cuyos nombres no sean especificados en la sentencia table, en cuyo caso los valores de estos campos serán ignorados al leer la tabla.

\subsection{Escritura de datos en una tabla de salida}

La sentencia table de salida produce la escritura de datos en la tabla especificada. Debe notarse que algunos controladores (concretamente CSV y xBASE) destruyen la tabla de salida antes de escribir los datos, {\it i.e.} borran todos sus registros existentes.

Cada $n$-tuplo en el conjunto dominio especificado genera un registro escrito en la tabla de salida. Los valores de los campos son valores numéricos o simbólicos de las correspondientes expresiones especificadas en la sentencia table. Estas expresiones se evalúan para cada $n$-tuplo en el conjunto dominio y, de este modo, puede incluir índices que se introdujeron en la correspondiente expresión indizante.

Por ejemplo, la siguiente sentencia table de salida:

\noindent\hfil
\verb|table resultado{(s,h) in M} OUT "...": s~DESDE, h~HACIA, x[s,h]~FLUJO;|

\noindent
produce la escritura de registros en la tabla de salida, a razón de un registro por cada par $(s,h)$ en el conjunto {\tt M}, en el que cada registro consiste de tres campos llamados {\tt DESDE}, {\tt HACIA} y {\tt FLUJO}. Los valores escritos en los campos {\tt DESDE} y {\tt HACIA} son los valores corrientes de los índices {\tt s} y {\tt h}, y el valor escrito en el campo {\tt FLUJO} es un valor del miembro ${\tt x}[s,h]$ del correspondiente parámetro o variable indexada.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\chapter{Datos del modelo}

Los {\it datos del modelo} incluyen conjuntos elementales, los cuales son ``valores'' de los conjuntos del modelo, y valores simbólicos y numéricos de los parámetros del modelo.

En MathProg hay dos maneras diferentes de proveer valores para los conjuntos y parámetros del modelo. Una manera es simplemente proveyendo los datos necesarios mediante el atributo de asignación. Sin embargo, en muchos casos es más práctico separar el modelo en sí mismo de los datos particulares necesarios para el modelo. Por esta última razón, en MathProg hay otra manera que consiste en separar la descripción del modelo en dos partes: la sección del modelo y la sección de los datos.

La {\it sección del modelo} es la parte principal de la descripción del modelo que contiene las declaraciones de todos los objetos del modelo y es común a todos los problemas basados en tal modelo.

La {\it sección de los datos} es una parte opcional de la descripción del modelo que contiene datos específicos para un problema particular.

En MathProg las secciones del modelo y de los datos se pueden ubicar tanto en un único archivo de texto, como en dos archivos de texto separados.

1. Si ambas secciones se ubican en un archivo, este debe componerse como sigue:

\bigskip

\noindent\hfil
\framebox{\begin{tabular}{l}
{\it sentencia}{\tt;}\\
{\it sentencia}{\tt;}\\
\hfil.\ \ .\ \ .\\
{\it sentencia}{\tt;}\\
{\tt data;}\\
{\it bloque de datos}{\tt;}\\
{\it bloque de datos}{\tt;}\\
\hfil.\ \ .\ \ .\\
{\it bloque de datos}{\tt;}\\
{\tt end;}
\end{tabular}}

\newpage

2. Si ambas secciones se ubican en dos archivos separados, los archivos se componen como sigue:

\bigskip

\noindent\hfil
\begin{tabular}{@{}c@{}}
\framebox{\begin{tabular}{l}
{\it sentencia}{\tt;}\\
{\it sentencia}{\tt;}\\
\hfil.\ \ .\ \ .\\
{\it sentencia}{\tt;}\\
{\tt end;}\\
\end{tabular}}\\
\\\\Archivo del modelo\\
\end{tabular}
\hspace{32pt}
\begin{tabular}{@{}c@{}}
\framebox{\begin{tabular}{l}
{\tt data;}\\
{\it bloque de datos}{\tt;}\\
{\it bloque de datos}{\tt;}\\
\hfil.\ \ .\ \ .\\
{\it bloque de datos}{\tt;}\\
{\tt end;}\\
\end{tabular}}\\
\\Archivo de datos\\
\end{tabular}

\bigskip

Nota: si la sección de datos se ubica en un archivo separado, la palabra clave {\tt data} es opcional y puede omitirse, al igual que el punto y coma que le sigue.

\section{Codificación de la sección de los datos}

La {\it sección de los datos} es una secuencia de bloques de datos en varios formatos que se discuten en las siguientes secciones. El orden que siguen los bloques de datos en la sección de los datos puede ser arbitrario, no necesariamente el mismo que se siguió en la sección del modelo para sus correspondientes objetos.

Las reglas para codificar la sección de los datos comúnmente son las mismas reglas que para codificar la descripción del modelo (ver Sección \ref{coding}, página \pageref{coding}), {\it i.e.} los bloques de datos se componen con unidades léxicas básicas como nombres simbólicos, literales numéricos y de cadena, palabras clave, delimitadores y comentarios. Sin embargo, por conveniencia y para mejorar la legibilidad hay una desviación de la regla común: si un literal de cadena consiste únicamente de caracteres alfanuméricos (incluyendo el carácter de subrayado), los signos {\tt+} y {\tt-} y/o el punto decimal, el mismo puede codificarse sin comillas delimitadoras (simples o dobles).

Todo el material numérico y simbólico provisto en la sección de los datos se codifica en la forma de números y símbolos, {\it i.e.} a diferencia de la sección del modelo, en la sección de los datos no se permiten expresiones. Sin embargo, los signos {\tt+} y {\tt-} pueden preceder a literales numéricos para permitir la codificación de cantidades numéricas con signo, en cuyo caso no debe haber caracteres de espacio en blanco entre el signo y el literal numérico que le sigue (si hay al menos un espacio en blanco, el signo y el literal numérico que le sigue serán reconocidos como dos unidades léxicas diferentes).

\newpage

\section{Bloque de datos de conjunto}

\noindent
\framebox[468pt][l]{
\parbox[c][44pt]{468pt}{
\hspace{6pt} {\tt set} {\it nombre} {\tt,} {\it registro} {\tt,} \dots
{\tt,} {\it registro} {\tt;}

\medskip

\hspace{6pt} {\tt set} {\it nombre} {\tt[} {\it símbolo} {\tt,} \dots
{\tt,} {\it símbolo} {\tt]} {\tt,} {\it registro} {\tt,} \dots {\tt,}
{\it registro} {\tt;}
}}

\medskip

\noindent
{\it nombre} es el nombre simbólico del conjunto;

\noindent
{\it símbolo}, \dots, {\it símbolo} son subíndices que especifican un miembro particular del conjunto (si el conjunto es un arreglo, {\it i.e.} un conjunto de conjuntos);

\noindent
{\it registro}, \dots, {\it registro} son registros.

\noindent
Las comas que preceden a los registros pueden omitirse.

\para{Registros}

\vspace*{-8pt}

\begin{description}
\item[{\tt :=}]\hspace*{0pt}\\
es un elemento de asignación de registro no-significativo que puede ser usado libremente para mejorar la legibilidad;
\item[{\tt(} {\it porción} {\tt)}]\hspace*{0pt}\\
especifica una porción;
\item[{\it datos-simples}]\hspace*{0pt}\\
especifica los datos del conjunto en formato simple;
\item[{\tt:} {\it datos-matriciales}]\hspace*{0pt}\\
especifica los datos del conjunto en formato matricial;
\item[{\tt(tr)} {\tt:} {\it datos-matriciales}]\hspace*{0pt}\\
especifica los datos del conjunto en formato matricial traspuesto (en este caso, los dos puntos que siguen a la palabra clave {\tt(tr)} pueden omitirse).
\end{description}

\vspace*{-8pt}

\para{Ejemplos}

\begin{verbatim}
set mes := Ene Feb Mar Abr May Jun;
set mes "Ene", "Feb", "Mar", "Abr", "May", "Jun";
set A[3,Mar] := (1,2) (2,3) (4,2) (3,1) (2,2) (4,4) (3,4);
set A[3,'Mar'] := 1 2 2 3 4 2 3 1 2 2 4 4 3 4;
set A[3,'Mar'] : 1 2 3 4 :=
               1 - + - -
               2 - + + -
               3 + - - +
               4 - + - + ;
set B := (1,2,3) (1,3,2) (2,3,1) (2,1,3) (1,2,2) (1,1,1) (2,1,1);
set B := (*,*,*) 1 2 3, 1 3 2, 2 3 1, 2 1 3, 1 2 2, 1 1 1, 2 1 1;
set B := (1,*,2) 3 2 (2,*,1) 3 1 (1,2,3) (2,1,3) (1,1,1);
set B := (1,*,*) : 1 2 3 :=
                 1 + - -
                 2 - + +
                 3 - + -
         (2,*,*) : 1 2 3 :=
                 1 + - +
                 2 - - -
                 3 + - - ;
\end{verbatim}

\noindent(En estos ejemplos, {\tt mes} es un conjunto simple de singletones, {\tt A} es un arreglo 2-dimensional de duplos y {\tt B} es un conjunto simple de triplos. Los bloques de datos para el mismo conjunto son equivalentes en el sentido de que especifican los mismos datos en formatos distintos.

El {\it bloque de datos del conjunto} se usa para especificar un conjunto elemental completo, el que se asigna a un conjunto (si es un conjunto simple) o a uno de sus miembros (si el conjunto es un arreglo de conjuntos).\footnote{Hay otra forma de especificar datos para un conjunto simple junto con los datos para los parámetros. Esta característica se discute en la próxima sección.}

Los bloques de datos sólo pueden ser especificados para conjuntos no-calculables, {\it i.e.} para conjuntos que no tienen el atributo de asignación ({\tt:=}) en la correspondiente sentencia set.

Si el conjunto es un conjunto simple, sólo se debe especificar su nombre simbólico en el encabezado del bloque de datos. De otro modo, si el conjunto es un arreglo $n$-dimensional, su nombre simbólico debe proveerse con una lista completa de subíndices separados por coma y encerrados entre corchetes para especificar un miembro particular del arreglo de conjuntos. El número de subíndices debe ser igual a la dimensión del arreglo de conjuntos, en el que cada subíndice deben ser un número o símbolo.

Un conjunto elemental definido en el bloque de datos del conjunto se codifica como una secuencia de registros según se describe luego.\footnote{{Registro} es simplemente un término técnico. No significa que los mismos presenten algún formateo especial.}

\subsection{Asignación de registro}

La {\it asignación de registro} ({\tt:=}) es un elemento no-significativo. Se puede usar para mejorar la legibilidad de los bloques de datos.

\subsection{Registro en porción}

El {\it registro en porción} es un registro de control que especifica una {\it porción} del conjunto elemental definido en el bloque de datos. Tiene la siguiente forma sintáctica:
$$\mbox{{\tt(} $p_1$ {\tt,} $p_2$ {\tt,} \dots {\tt,} $p_n$ {\tt)}}$$
donde $p_1$, $p_2$, \dots, $p_n$ son componentes de la porción.

Cada componente de la porción puede ser un número o un símbolo o el asterisco ({\tt*}). El número de componentes de la porción debe coincidir con la dimensión de los $n$-tuplos del conjunto elemental que se define. Por ejemplo, si el conjunto elemental contiene 4-tuplos (cuádruplos), la porción debe tener cuatro componentes. El número de asteriscos en la porción se denomina la {\it dimensión de la porción}.

El efecto de usar las porciones es como sigue: si se especifica una porción $m$-dimensional ({\it i.e.} una porción que tiene $m$ asteriscos) en el bloque de datos, todos los registros subsecuentes deben especificar tuplos de dimensión $m$. Cuando se encuentra un $m$-tuplo, cada asterisco en la porción se reemplaza por los correspondientes componentes del $m$-tuplo para dar el $n$-tuplo resultante, el que es incluido en el conjunto elemental que se define. Por ejemplo, si está vigente la porción $(a,*,1,2,*)$ y se encuentra el duplo $(3,b)$ en el registro subsecuente, el 5-tuplo resultante que se incluye en el conjunto elemental es $(a,3,1,2,b)$.

Las porciones que no tienen asteriscos en si mismas, definen un $n$-tuplo completo que se incluye en el conjunto elemental.

Una vez especificada una porción, la misma está vigente hasta que aparezca una nueva porción o bien hasta que se encuentra el final del bloque de datos. Debe notarse que si no se especifica una porción en el bloque de datos, se asume una cuyos componentes son asteriscos en todas las posiciones.

\subsection{Registro simple}

El {\it registro simple} define un $n$-tuplo en formato simple y tiene la siguiente forma sintáctica:
$$\mbox{$t_1$ {\tt,} $t_2$ {\tt,} \dots {\tt,} $t_n$}$$
donde $t_1$, $t_2$, \dots, $t_n$ son componentes del $n$-tuplo. Cada componente puede ser un número o símbolo. Las comas entre componentes son opcionales y pueden omitirse.

\subsection{Registro matricial}

El {\it registro matricial} define varios 2-tuplos (duplos) en formato matricial y tiene la siguiente forma sintáctica:
$$\begin{array}{cccccc}
\mbox{{\tt:}}&c_1&c_2&\dots&c_n&\mbox{{\tt:=}}\\
f_1&a_{11}&a_{12}&\dots&a_{1n}&\\
f_2&a_{21}&a_{22}&\dots&a_{2n}&\\
\multicolumn{5}{c}{.\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .}&\\
f_m&a_{m1}&a_{m2}&\dots&a_{mn}&\\
\end{array}$$
donde $f_1$, $f_2$, \dots, $f_m$ son números y/o símbolos que corresponden a filas de la matriz; $c_1$, $c_2$, \dots, $c_n$ son números y/o símbolos que corresponden a columnas de la matriz, mientras que $a_{11}$, $a_{12}$, \dots, $a_{mn}$ son los elementos de la matriz, los cuales pueden ser tanto {\tt+} como {\tt-}. (En este registro, el delimitador {\tt:} que precede a la lista de columnas y el delimitador {\tt:=} a continuación de la lista de columnas, no pueden ser omitidos.)

Cada elemento $a_{ij}$ del bloque de datos matricial (donde $1\leq i\leq m$,
$1\leq j\leq n$) corresponde a 2-tuplos $(f_i,c_j)$. Si en $a_{ij}$ se indica el signo más ({\tt+}), el correspondiente 2-tuplo (o un $n$-tuplo más largo si se usa una porción) se incluye en el conjunto elemental. De otro modo, si en $a_{ij}$ se indica el signo menos ({\tt-}) el 2-tuplo no se incluye en el conjunto elemental.

Puesto que el registro matricial define 2-tuplos, ya sea el conjunto elemental o bien la porción vigente en uso deben ser 2-dimensionales.

\subsection{Registro matricial traspuesto}

El {\it registro matricial traspuesto} tiene la siguiente forma sintáctica:
$$\begin{array}{cccccc}
\mbox{{\tt(tr) :}}&c_1&c_2&\dots&c_n&\mbox{{\tt:=}}\\
f_1&a_{11}&a_{12}&\dots&a_{1n}&\\
f_2&a_{21}&a_{22}&\dots&a_{2n}&\\
\multicolumn{5}{c}{.\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .}&\\
f_m&a_{m1}&a_{m2}&\dots&a_{mn}&\\
\end{array}$$
(En este caso el delimitador {\tt:} a continuación de la palabra clave {\tt (tr)} es opcional y puede omitirse.)

Este registro es completamente análogo al registro matricial (ver anteriormente) con la única excepción, en este caso, de que cada elemento $a_{ij}$ de la matriz corresponde al 2-tuplo $(c_j,f_i)$ en vez de a $(f_i,c_j)$.

Una vez especificado, el indicador {\tt(tr)} tiene alcance en todos los registros subsecuentes hasta que se encuentra otra porción o bien el fin del bloque de datos.

\section{Bloque de datos de parámetro}

\noindent
\framebox[468pt][l]{
\parbox[c][88pt]{468pt}{
\hspace{6pt} {\tt param} {\it nombre} {\tt,} {\it registro} {\tt,} \dots
{\tt,} {\it registro} {\tt;}

\medskip

\hspace{6pt} {\tt param} {\it nombre} {\tt default} {\it valor} {\tt,}
{\it registro} {\tt,} \dots {\tt,} {\it registro} {\tt;}

\medskip

\hspace{6pt} {\tt param} {\tt:} {\it datos-tabulación} {\tt;}

\medskip

\hspace{6pt} {\tt param} {\tt default} {\it valor} {\tt:}
{\it datos-tabulación} {\tt;}
}}

\medskip

\noindent
{\it nombre} es el nombre simbólico del parámetro;

\noindent
{\it valor} es un valor por defecto opcional del parámetro;

\noindent
{\it registro}, \dots, {\it registro} son registros.

\noindent
{\it datos-tabulación} especifica los datos del parámetro en el formato tabulación.

\noindent
Las comas que preceden a los registros pueden omitirse.

\para{Registros}

\vspace*{-8pt}

\begin{description}
\item[{\tt :=}]\hspace*{0pt}\\
es un elemento de asignación de registro no-significativo que puede ser usado libremente para mejorar la legibilidad;
\item[{\tt[} {\it porción} {\tt]}]\hspace*{0pt}\\
especifica una porción;
\item[{\it datos-planos}]\hspace*{0pt}\\
especifica los datos del parámetro en formato plano;
\item[{\tt:} {\it datos-tabulares}]\hspace*{0pt}\\
especifica los datos del parámetro en formato tabular;
\item[{\tt(tr)} {\tt:} {\it datos-tabulares}]\hspace*{0pt}\\
especifica los datos del parámetro en formato matricial traspuesto (en este caso, los dos puntos que siguen a la palabra clave {\tt(tr)} pueden omitirse).
\end{description}

\vspace*{-8pt}

\para{Ejemplos}

\begin{verbatim}
param T := 4;
param mes := 1 Ene 2 Feb 3 Mar 4 Abr 5 May;
param mes := [1] 'Ene', [2] 'Feb', [3] 'Mar', [4] 'Abr', [5] 'May';
param stock_inicial := hierro 7.32 niquel 35.8;
param stock_inicial [*] hierro 7.32, niquel 35.8;
param costo [hierro] .025 [niquel] .03;
param valor := hierro -.1, niquel .02;
param       : stock_inicial  costo  valor :=
      hierro      7.32       .025    -.1
      niquel     35.8        .03      .02 ;
param : insumo : stock_inicial  costo  valor :=
        hierro       7.32       .025    -.1
        niquel      35.8        .03      .02 ;
param demanda default 0 (tr)
       :    FRA  DET  LAN  WIN  STL  FRE  LAF :=
   laminas  300   .   100   75   .   225  250
   rollos   500  750  400  250   .   850  500
   cintas   100   .    .    50  200   .   250 ;
param costo_transporte :=
   [*,*,laminas]:  FRA  DET  LAN  WIN  STL  FRE  LAF :=
         GARY      30   10    8   10   11   71    6
         CLEV      22    7   10    7   21   82   13
         PITT      19   11   12   10   25   83   15
   [*,*,rollos]:   FRA  DET  LAN  WIN  STL  FRE  LAF :=
         GARY      39   14   11   14   16   82    8
         CLEV      27    9   12    9   26   95   17
         PITT      24   14   17   13   28   99   20
   [*,*,cintas]:   FRA  DET  LAN  WIN  STL  FRE  LAF :=
         GARY      41   15   12   16   17   86    8
         CLEV      29    9   13    9   28   99   18
         PITT      26   14   17   13   31  104   20  ;
\end{verbatim}

El {\it bloque de datos del parámetro} se usa para especificar datos completos a un parámetro (o a varios parámetros si los datos se especifican en el formato tabulaciones)

Los bloques de datos sólo pueden ser especificados para parámetros no-calculables, {\it i.e.} para parámetros que no tienen el atributo de asignación({\tt:=}) en la correspondiente sentencia parameter.

Los datos definidos en el bloque de datos del parámetro se codifican como una secuencia de registros descriptos luego. Adicionalmente, el bloque de datos puede ser provisto con el atributo opcional {\tt default}, el cual especifica un valor numérico o simbólico por defecto para el parámetro (parámetros). Este valor por defecto se asigna al parámetro, o a sus miembros, cuando no se definen valores apropiados en el bloque de datos del parámetro. El atributo {\tt default} no se puede usar si ya se ha especificado en la correspondiente sentencia parameter.

\subsection{Asignación de registro}

La {\it asignación de registro} ({\tt:=}) es un elemento no-significativo. Se puede usar para mejorar la legibilidad de los bloques de datos.

\subsection{Registro en porción}

El {\it registro en porción} es un registro de control que especifica una {\it porción} del arreglo de parámetros. Tiene la siguiente forma sintáctica:
$$\mbox{{\tt[} $p_1$ {\tt,} $p_2$ {\tt,} \dots {\tt,} $p_n$ {\tt]}}$$
donde $p_1$, $p_2$, \dots, $p_n$ son componentes de la porción.

Cada componente de la porción puede ser un número o un símbolo o el asterisco ({\tt*}). El número de componentes de la porción debe coincidir con la dimensión del parámetro. Por ejemplo, si el parámetro es un arreglo 4-dimensional, la porción debe tener cuatro componentes. El número de asteriscos en la porción se denomina la {\it dimensión de la porción}.

El efecto de usar las porciones es como sigue: si se especifica una porción $m$-dimensional ({\it i.e.} una porción que tiene $m$ asteriscos) en el bloque de datos, todos los registros subsecuentes deben especificar los subíndices de los miembros del parámetro como si el parámetro fuese $m$-dimensional y no $n$-dimensional.

Cuando se encuentran los $m$ subíndices, cada asterisco en la porción se reemplaza por el correspondiente subíndice para dar los $n$ subíndices, los cuales definen al miembro corriente del parámetro. Por ejemplo, si está vigente la porción $(a,*,1,2,*)$ y se encuentran los subíndices 3 y $b$ en el registro subsecuente, la lista completa de subíndices que se usa para elegir un miembro del parámetro es $(a,3,1,2,b)$.

Se permite especificar una porción que no tenga asteriscos. Tal porción, en sí misma define una lista completa de subíndices, en cuyo caso el próximo registro debe definir solamente un valor individual del correspondiente miembro del parámetro.

Una vez especificada una porción, la misma está vigente hasta que aparezca una nueva porción o bien hasta que se encuentra el final del bloque de datos. Debe notarse que si no se especifica una porción en el bloque de datos, se asume una cuyos componentes son todos asteriscos.

\subsection{Registro plano}

El {\it registro plano} define la lista de subíndices y un valor individual en el formato plano. Este registro tiene la siguiente forma sintáctica:
$$\mbox{$t_1$ {\tt,} $t_2$ {\tt,} \dots {\tt,} $t_n$ {\tt,} $v$}$$
donde $t_1$, $t_2$, \dots, $t_n$ son subíndices y $v$ es un valor. Cada subíndice, al igual que el valor, puede ser un número o un símbolo. Las comas que siguen a los subíndices son opcionales y pueden omitirse.

En el caso de parámetros o porciones 0-dimensionales, el registro plano no tiene subíndice y consiste solamente de un valor individual.

\subsection{Registro tabular}

El {\it registro tabular} define varios valores, cada uno de los cuales viene provisto con dos subíndices. Este registro tiene la siguiente forma sintáctica:
$$\begin{array}{cccccc}
\mbox{{\tt:}}&c_1&c_2&\dots&c_n&\mbox{{\tt:=}}\\
f_1&a_{11}&a_{12}&\dots&a_{1n}&\\
f_2&a_{21}&a_{22}&\dots&a_{2n}&\\
\multicolumn{5}{c}{.\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .}&\\
f_m&a_{m1}&a_{m2}&\dots&a_{mn}&\\
\end{array}$$
donde los $f_1$, $f_2$, \dots, $f_m$ son números y/o símbolos que corresponden a filas de la tabla; $c_1$, $c_2$, \dots, $c_n$ son números y/o símbolos que corresponden a columnas de la tabla; mientras que $a_{11}$, $a_{12}$, \dots, $a_{mn}$ son elementos de la tabla. Cada elemento puede ser un número o símbolo o el punto decimal ({\tt.}) solo (en este registro, el delimitador {\tt:} que precede a la lista de columnas y el delimitador {\tt:=} a continuación de la lista de columnas, no pueden ser omitidos.).

Cada elemento $a_{ij}$ del bloque de datos tabulares ($1\leq i\leq m$,
$1\leq j\leq n$) define dos subíndices, siendo el primero $f_i$ y el segundo $c_j$. Estos subíndices se usan junto con la porción vigente para formar la lista completa de subíndices que identifica a un miembro particular del arreglo de parámetros. Si $a_{ij}$ es un número o símbolo, tal valor se asigna al miembro del parámetro. Sin embargo, si $a_{ij}$ es un punto decimal solo, el miembro recibe el valor por defecto especificado ya sea en el bloque de datos del parámetro o en la sentencia parameter, o si no hay un valor por defecto especificado, el miembro permanece indefinido.

Puesto que el registro tabular provee dos subíndices para cada valor, ya sea el parámetro o bien la porción vigente en uso deben ser 2-dimensionales.

\subsection{Registro tabular traspuesto}

El {\it registro tabular traspuesto} tiene la siguiente forma sintáctica:
$$\begin{array}{cccccc}
\mbox{{\tt(tr) :}}&c_1&c_2&\dots&c_n&\mbox{{\tt:=}}\\
f_1&a_{11}&a_{12}&\dots&a_{1n}&\\
f_2&a_{21}&a_{22}&\dots&a_{2n}&\\
\multicolumn{5}{c}{.\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .\ \ .}&\\
f_m&a_{m1}&a_{m2}&\dots&a_{mn}&\\
\end{array}$$
(En este caso el delimitador {\tt:} a continuación de la palabra clave {\tt (tr)} es opcional y puede omitirse.)

Este registro es completamente análogo al registro tabular (ver anteriormente), con la única excepción de que el primer subíndice definido por el elemento $a_{ij}$ es $c_j$ mientras que el segundo es $f_i$.

Una vez especificado, el indicador {\tt(tr)} tiene alcance en todos los registros subsecuentes hasta que se encuentre otra porción o bien el fin del bloque de datos.

\subsection{Formato de datos tabulación}

El bloque de datos del parámetro en el {\it formato tabulación} tiene la siguiente forma sintáctica:
$$
\begin{array}{*{8}{l}}
\multicolumn{4}{l}
{{\tt param}\ {\tt default}\ valor\ {\tt :}\ c\ {\tt :}}&
p_1\ \ \verb|,|&p_2\ \ \verb|,|&\dots\ \verb|,|&p_f\ \ \verb|:=|\\
f_{11}\ \verb|,|& f_{12}\ \verb|,|& \dots\ \verb|,|& f_{1n}\ \verb|,|&
a_{11}\ \verb|,|& a_{12}\ \verb|,|& \dots\ \verb|,|& a_{1f}\ \verb|,|\\
f_{21}\ \verb|,|& f_{22}\ \verb|,|& \dots\ \verb|,|& f_{2n}\ \verb|,|&
a_{21}\ \verb|,|& a_{22}\ \verb|,|& \dots\ \verb|,|& a_{2f}\ \verb|,|\\
\dots & \dots & \dots & \dots & \dots & \dots & \dots & \dots \\
f_{m1}\ \verb|,|& f_{m2}\ \verb|,|& \dots\ \verb|,|& f_{mn}\ \verb|,|&
a_{m1}\ \verb|,|& a_{m2}\ \verb|,|& \dots\ \verb|,|& a_{mf}\ \verb|;|\\
\end{array}
$$

1. La palabra clave {\tt default} puede omitirse junto con el valor que le sigue.

2. El nombre simbólico $c$ puede omitirse junto con los dos puntos que le siguen.

3. Todas las comas son opcionales y pueden omitirse.

El bloque de datos en el formato tabulación mostrado arriba es exactamente equivalente a los siguientes bloques de datos:

\verb|set| $c$\ \verb|:=|\ $
\verb|(|f_{11}\verb|,|f_{12}\verb|,|\dots\verb|,|f_{1n}\verb|) |
\verb|(|f_{21}\verb|,|f_{22}\verb|,|\dots\verb|,|f_{2n}\verb|) |
\dots
\verb| (|f_{m1}\verb|,|f_{m2}\verb|,|\dots\verb|,|f_{mn}\verb|);|$

\verb|param| $p_1$\ \verb|default|\ $valor$\ \verb|:=|

$\verb|   |
\verb|[|f_{11}\verb|,|f_{12}\verb|,|\dots\verb|,|f_{1n}\verb|] |a_{11}
\verb| [|f_{21}\verb|,|f_{22}\verb|,|\dots\verb|,|f_{2n}\verb|] |a_{21}
\verb| |\dots
\verb| [|f_{m1}\verb|,|f_{m2}\verb|,|\dots\verb|,|f_{mn}\verb|] |a_{m1}
\verb|;|
$

\verb|param| $p_2$\ \verb|default|\ $valor$\ \verb|:=|

$\verb|   |
\verb|[|f_{11}\verb|,|f_{12}\verb|,|\dots\verb|,|f_{1n}\verb|] |a_{12}
\verb| [|f_{21}\verb|,|f_{22}\verb|,|\dots\verb|,|f_{2n}\verb|] |a_{22}
\verb| |\dots
\verb| [|f_{m1}\verb|,|f_{m2}\verb|,|\dots\verb|,|f_{mn}\verb|] |a_{m2}
\verb|;|
$

\verb|   |.\ \ \ .\ \ \ .\ \ \ .\ \ \ .\ \ \ .\ \ \ .\ \ \ .\ \ \ .

\verb|param| $p_f$\ \verb|default|\ $valor$\ \verb|:=|

$\verb|   |
\verb|[|f_{11}\verb|,|f_{12}\verb|,|\dots\verb|,|f_{1n}\verb|] |a_{1f}
\verb| [|f_{21}\verb|,|f_{22}\verb|,|\dots\verb|,|f_{2n}\verb|] |a_{2f}
\verb| |\dots
\verb| [|f_{m1}\verb|,|f_{m2}\verb|,|\dots\verb|,|f_{mn}\verb|] |a_{mf}
\verb|;|
$

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\appendix

\chapter{Uso de sufijos}

\vspace*{-12pt}

Se pueden usar sufijos para recuperar valores adicionales relacionados con las variables, restricciones y objetivos del modelo.

Un {\it sufijo} consiste de un punto ({\tt.}) seguido de una palabra clave no-reservada. Por ejemplo, si {\tt x} es una variable bidimensional, {\tt x[i,j].lb} es un valor numérico igual a la cota inferior de la variable elemental {\tt x[i,j]} que se puede usar como un parámetro numérico dondequiera que sea en expresiones.

Para las variables del modelo, los sufijos tienen los siguientes significados:

\begin{tabular}{@{}ll@{}}
{\tt.lb}&cota inferior\\
{\tt.ub}&cota superior\\
{\tt.status}&estatus en la solución:\\
&0 --- indefinida\\
&1 --- básica\\
&2 --- no-básica en la cota inferior\\
&3 --- no-básica en la cota superior\\
&4 --- variable no-básica libre (no acotada)\\
&5 --- variable no-básica fija\\
{\tt.val}&valor primal en la solución\\
{\tt.dual}&valor dual (costo reducido) en la solución\\
\end{tabular}

Para las restricciones y objetivos del modelo, los sufijos tienen los siguientes significados:

\begin{tabular}{@{}ll@{}}
{\tt.lb}&cota inferior de la forma lineal\\
{\tt.ub}&cota superior de la forma lineal\\
{\tt.status}&estatus en la solución:\\
&0 --- indefinida\\
&1 --- no-limitante\\
&2 --- limitante en la cota inferior\\
&3 --- limitante en la cota superior\\
&4 --- fila limitante libre (no-acotada)\\
&5 --- restricción de igualdad limitante\\
{\tt.val}&valor primal de la forma lineal en la solución\\
{\tt.dual}&valor dual (costo reducido) de la forma lineal en la solución\\
\end{tabular}

Debe notarse que los sufijos {\tt.status}, {\tt.val} y {\tt.dual} solamente pueden usarse luego de la sentencia solve.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\chapter{Funciones de fecha y hora}

\noindent\hfil
\begin{tabular}{c}
por Andrew Makhorin \verb|<mao@gnu.org>|\\
y Heinrich Schuchardt \verb|<heinrich.schuchardt@gmx.de>|\\
\end{tabular}

\section{Obtención del tiempo calendario corriente}
\label{gmtime}

Para obtener el tiempo calendario\footnote{N. del T.: el tiempo calendario es un punto en el {\it continuum} del tiempo, por ejemplo 4 de noviembre de 1990 a las 18:02.5 UTC. A veces se lo llama ``tiempo absoluto''. La definición está tomada de {\it Sandra Loosemore}, {\it Richard M. Stallman}, {\it Roland McGrath}, {\it Andrew Oram} \& {\it Ulrich Drepper}, ``The GNU C Library Reference Manual - for version 2.17'', Free Software Foundation, Inc, 2012.} corriente en MathProg existe la función {\tt gmtime}. No tiene argumentos y devuelve el número de segundos transcurridos desde las 00:00:00 del 1 de enero de 1970, Tiempo Universal Coordinado (UTC). Por ejemplo:

\begin{verbatim}
      param utc := gmtime();
\end{verbatim}

MathPro no tiene una función para convertir el tiempo UTC devuelto por la función {\tt gmtime} a tiempo calendario {\it local}. Entonces, si se necesita determinar el tiempo calendario local corriente, se debe agregar al tiempo UTC devuelto la diferencia horaria con respecto al UTC expresada en segundos. Por ejemplo, la hora en Berlín durante el invierno está una hora adelante del UTC, lo que corresponde una diferencia horaria de +1~hora~= +3600~segundos, de modo que el tiempo calendario corriente del invierno en Berlín se puede determinar como sigue:

\begin{verbatim}
      param ahora := gmtime() + 3600;
\end{verbatim}

\noindent Análogamente, el horario de verano en Chicago (Zona Horaria Central) está cinco horas por detrás del UTC, de modo que el correspondiente tiempo calendario local corriente se puede determinar como sigue:

\begin{verbatim}
      param ahora := gmtime() - 5 * 3600;
\end{verbatim}

Debe notarse que el valor devuelto por {\tt gmtime} es volátil, {\it i.e.} si se la invoca varias veces, esta función devolverá valores diferentes.

\section{Conversión de una cadena de caracteres a un tiempo calendario}
\label{str2time}

La función {\tt str2time(}{\it c}{\tt,} {\it f}{\tt)} convierte una cadena de caracteres (una {\it estampa de la fecha y hora}) especificada por su primer argumento {\it c}, la que debe ser una expresión simbólica, a un tiempo calendario apropiado para cálculos aritméticos. La conversión se controla mediante la especificación de una cadena de formato {\it f} (el segundo argumento), la que también debe ser una expresión simbólica.

El resultado de la conversión devuelto por {\tt str2time} tiene el mismo significado que los valores devueltos por la función {\tt gmtime} (ver Subsección \ref{gmtime}, página \pageref{gmtime}). Debe notarse que {\tt str2time} {\it no corrige} el tiempo calendario devuelto para considerar la zona horaria local, {\it i.e.} si se aplica a las 00:00:00 del 1 de enero de 1970, siempre devolverá 0.

Por ejemplo, las sentencias del modelo

\begin{verbatim}
      param c, symbolic, := "07/14/98 13:47";
      param t := str2time(c, "%m/%d/%y %H:%M");
      display t;
\end{verbatim}

\noindent imprime lo siguiente en la salida estándar:

\begin{verbatim}
      t = 900424020
\end{verbatim}

\noindent donde el tiempo calendario mostrado corresponde a las 13:47:00 del 14 de julio de 1998.

La cadena de formato que se pasa a la función {\tt str2time} consiste de especificadores de conversión y caracteres ordinarios. Cada especificador de conversión empieza con un carácter de porcentaje ({\tt\%}) seguido por una letra.

Los siguientes especificadores de conversión se pueden usar en la cadena de formato\footnote{N. del T.: en todas las funciones de fecha y hora, nombre del mes y del día de la semana refiere a su denominación en inglés, {\it e.g.}: {\tt August}, {\tt Aug}, {\tt Wednesday}, {\tt We}.}:

\begin{tabular}{@{}p{20pt}p{421.5pt}@{}}
{\tt\%b}&El nombre del mes abreviado (insensible a mayúsculas). Al menos las tres primeras letras del nombre del mes deben aparecer en la cadena de entrada.\\
\end{tabular}

\begin{tabular}{@{}p{20pt}p{421.5pt}@{}}
{\tt\%d}&El día del mes como un número decimal (rango de 1 a 31). Se permite el cero como primer dígito, aunque no es requerido.\\
\end{tabular}

\begin{tabular}{@{}p{20pt}p{421.5pt}@{}}
{\tt\%h}&Lo mismo que {\tt\%b}.\\
\end{tabular}

\begin{tabular}{@{}p{20pt}p{421.5pt}@{}}
{\tt\%H}&La hora como un número decimal, empleando un reloj de 24 horas (rango de 0 a 23). Se permite el cero como primer dígito, aunque no es requerido.\\
\end{tabular}

\begin{tabular}{@{}p{20pt}p{421.5pt}@{}}
{\tt\%m}&El mes como un número decimal (rango de 1 a 12). Se permite el cero como primer dígito, aunque no es requerido.\\
\end{tabular}

\begin{tabular}{@{}p{20pt}p{421.5pt}@{}}
{\tt\%M}&El minuto como número decimal (rango de 0 a 59). Se permite el cero como primer dígito, aunque no es requerido.\\
\end{tabular}

\begin{tabular}{@{}p{20pt}p{421.5pt}@{}}
{\tt\%S}&El segundo como un número decimal (rango de 0 a 59). Se permite el cero como primer dígito, aunque no es requerido.\\
\end{tabular}

\begin{tabular}{@{}p{20pt}p{421.5pt}@{}}
{\tt\%y}&El año sin un siglo como un número decimal (rango de 0 a 99). Se permite el cero como primer dígito, aunque no es requerido. Los valores de entrada en el rango de 0 a 68 se consideran como los años 2000 al 2068, mientras que los valores del 69 al 99 como los años 1969 a 1999.\\
\end{tabular}

\begin{tabular}{@{}p{20pt}p{421.5pt}@{}}
{\tt\%z}&La diferencia horaria con respecto a GMT en formato ISO 8601.\\
\end{tabular}

\begin{tabular}{@{}p{20pt}p{421.5pt}@{}}
{\tt\%\%}&Un carácter {\tt\%} literal.\\
\end{tabular}

Todos los demás caracteres (ordinarios) en la cadena de formato deben tener un carácter de coincidencia con la cadena de entrada a ser convertida. Las excepciones son los espacios en la cadena de entrada, la cual puede coincidir con cero o más caracteres de espacio en la cadena de formato.

Si algún componente de la fecha y/u hora están ausentes en el formato y, consecuentemente, en la cadena de entrada, la función {\tt str2time} usa sus valores por defecto de las 00:00:00 del 1 de enero de 1970, es decir que el valor por defecto para el año es 1970, el valor por defecto para el mes es enero, etc.

La función {} es aplicable a todos los tiempos calendarios en el rango desde las 00:00:00 del 1 de enero del 0001 hasta las 23:59:59 del 31 de diciembre del 4000 del calendario gregoriano.

\section{Conversión de un tiempo calendario a una cadena de caracteres}
\label{time2str}

La función {\tt time2str(}{\it t}{\tt,} {\it f}{\tt)} convierte el tiempo calendario especificado por su primer argumento {\it t}, el que debe ser una expresión numérica, a una cadena de caracteres (valor simbólico). La conversión se controla con la cadena de formato {\it f} especificada (el segundo argumento), la que debe ser una expresión simbólica.

El tiempo calendario que se le pasa a {\tt time2str} tiene el mismo significado que el valor devuelto por la función {\tt gmtime} (ver Subsección \ref{gmtime}, página \pageref{gmtime}). Debe notarse que {\tt time2str} {\it no corrige} el tiempo calendario especificado para considerar la zona horaria local, {\it i.e.} el tiempo calendario 0 siempre corresponde a las 00:00:00 del 1 de enero de 1970.

Por ejemplo, las sentencias del modelo

\begin{verbatim}
      param c, symbolic, := time2str(gmtime(), "%FT%TZ");
      display c;
\end{verbatim}

\noindent puede producir la siguiente impresión:

\begin{verbatim}
      c = '2008-12-04T00:23:45Z'
\end{verbatim}

\noindent que es una estampa de una fecha y hora en el formato ISO.

La cadena de formato que se pasa a la función {\tt time2str} consiste de especificadores de conversión y caracteres ordinarios. Cada especificador de conversión empieza con un carácter de porcentaje ({\tt\%}) seguido por una letra.

Los siguientes especificadores de conversión se pueden usar en la cadena de formato:

\newpage

\begin{tabular}{@{}p{20pt}p{421.5pt}@{}}
{\tt\%a}&El nombre del día de la semana abreviado (2 caracteres).\\
\end{tabular}

\begin{tabular}{@{}p{20pt}p{421.5pt}@{}}
{\tt\%A}&El nombre del día de la semana completo.\\
\end{tabular}

\begin{tabular}{@{}p{20pt}p{421.5pt}@{}}
{\tt\%b}&El nombre del mes abreviado (3 caracteres).\\
\end{tabular}

\begin{tabular}{@{}p{20pt}p{421.5pt}@{}}
{\tt\%B}&El nombre del mes completo.\\
\end{tabular}

\begin{tabular}{@{}p{20pt}p{421.5pt}@{}}
{\tt\%C}&El siglo del año, es decir el mayor entero no mayor que el año dividido por~100.\\
\end{tabular}

\begin{tabular}{@{}p{20pt}p{421.5pt}@{}}
{\tt\%d}&El día del mes como un número decimal (rango de 01 a 31).\\
\end{tabular}

\begin{tabular}{@{}p{20pt}p{421.5pt}@{}}
{\tt\%D}&La fecha, usando el formato \verb|%m/%d/%y|.\\
\end{tabular}

\begin{tabular}{@{}p{20pt}p{421.5pt}@{}}
{\tt\%e}&El día del mes, como con \verb|%d|, pero rellenado con un espacio en blanco en vez de cero.\\
\end{tabular}

\begin{tabular}{@{}p{20pt}p{421.5pt}@{}}
{\tt\%F}&La fecha, usando el formato \verb|%Y-%m-%d|.\\
\end{tabular}

\begin{tabular}{@{}p{20pt}p{421.5pt}@{}}
{\tt\%g}&El año correspondiente al número de semana ISO, pero sin el siglo (rango de 00 a 99). Tiene el mismo formato y valor que \verb|%y|, excepto que si el número de semana ISO (ver \verb|%V|) pertenece al año previo o siguiente, se usa aquel año en su lugar.\\
\end{tabular}

\begin{tabular}{@{}p{20pt}p{421.5pt}@{}}
{\tt\%G}&El año correspondiente al número de semana ISO. Tiene el mismo formato y valor que \verb|%Y|, excepto que si el número de semana ISO (ver \verb|%V|) pertenece al año previo o siguiente, se usa aquel año en su lugar.\\
\end{tabular}

\begin{tabular}{@{}p{20pt}p{421.5pt}@{}}
{\tt\%h}&Lo mismo que \verb|%b|.\\
\end{tabular}

\begin{tabular}{@{}p{20pt}p{421.5pt}@{}}
{\tt\%H}&La hora como un número decimal, empleando un reloj de 24 horas (rango de 00 a 23).\\
\end{tabular}

\begin{tabular}{@{}p{20pt}p{421.5pt}@{}}
{\tt\%I}&La hora como un número decimal, empleando un reloj de 12 horas (rango de 01 a 12).\\
\end{tabular}

\begin{tabular}{@{}p{20pt}p{421.5pt}@{}}
{\tt\%j}&El día del año como un número decimal (rango de 001 a 366).\\
\end{tabular}

\begin{tabular}{@{}p{20pt}p{421.5pt}@{}}
{\tt\%k}&La hora como un número decimal, empleando un reloj de 24 horas como con \verb|%H|, pero rellenado con un espacio en blanco en vez de cero.\\
\end{tabular}

\begin{tabular}{@{}p{20pt}p{421.5pt}@{}}
{\tt\%l}&La hora como un número decimal, empleando un reloj de 12 horas como con \verb|%I|, pero rellenado con un espacio en blanco en vez de cero.\\
\end{tabular}

\begin{tabular}{@{}p{20pt}p{421.5pt}@{}}
{\tt\%m}&El mes como un número decimal (rango de 01 a 12).\\
\end{tabular}

\begin{tabular}{@{}p{20pt}p{421.5pt}@{}}
{\tt\%M}&El minuto como un número decimal (rango de 00 a 59).\\
\end{tabular}

\begin{tabular}{@{}p{20pt}p{421.5pt}@{}}
{\tt\%p}&Tanto {\tt AM} como {\tt PM}, de acuerdo con el valor horario dado. La medianoche es tratada como {\tt AM} y el mediodía como {\tt PM}.\\
\end{tabular}

\begin{tabular}{@{}p{20pt}p{421.5pt}@{}}
{\tt\%P}&Tanto {\tt am} como {\tt pm}, de acuerdo con el valor horario dado. La medianoche es tratada como {\tt am} y el mediodía como {\tt pm}.\\
\end{tabular}

\begin{tabular}{@{}p{20pt}p{421.5pt}@{}}
{\tt\%R}&La hora y los minutos en números decimales, usando el formato \verb|%H:%M|.\\
\end{tabular}

\begin{tabular}{@{}p{20pt}p{421.5pt}@{}}
{\tt\%S}&Los segundos como un número decimal (rango de 00 a 59).\\
\end{tabular}

\begin{tabular}{@{}p{20pt}p{421.5pt}@{}}
{\tt\%T}&La hora del día en números decimales, usando el formato \verb|%H:%M:%S|.\\
\end{tabular}

\begin{tabular}{@{}p{20pt}p{421.5pt}@{}}
{\tt\%u}&El día de la semana como un número decimal (rango de 1 a 7), siendo 1 el lunes.\\
\end{tabular}

\begin{tabular}{@{}p{20pt}p{421.5pt}@{}}
{\tt\%U}&El número de semana del año corriente como un número decimal (rango de 00 a 53), empezando con el primer domingo como el primer día de la primer semana. Se considera que los días del año anteriores al primer domingo son parte de la semana 00.\\
\end{tabular}

\begin{tabular}{@{}p{20pt}p{421.5pt}@{}}
{\tt\%V}&El número de semana ISO como un número decimal (rango 01 a 53). Las semanas de ISO empiezan los lunes y terminan los domingos. La semana 01 de un año es la primer semana que tiene la mayoría de sus días en ese año, lo cual es equivalente a la semana que contiene al 4 de enero. La semana 01 de un año puede contener días del año previo. La semana anterior a la semana 01 de un año es la última semana (52 o 53) del año previo, aún si esta contiene días del nuevo año. En otras palabras, si el 1 de enero cae en lunes, martes, miércoles o jueves, está en la semana 01; si el 1 de enero cae en viernes, sábado o domingo, está en la semana 52 o 53 del año previo.\\
\end{tabular}

\begin{tabular}{@{}p{20pt}p{421.5pt}@{}}
{\tt\%w}&El día de la semana como un número decimal (rango de 0 a 6), siendo 0 el domingo.\\
\end{tabular}

\begin{tabular}{@{}p{20pt}p{421.5pt}@{}}
{\tt\%W}&El número de semana del año corriente como un número decimal (rango de 00 a 53), empezando con el primer lunes como el primer día de la primer semana. Se considera que los días del año anteriores al primer lunes son parte de la semana 00.\\
\end{tabular}

\begin{tabular}{@{}p{20pt}p{421.5pt}@{}}
{\tt\%y}&El año sin el siglo como un número decimal (rango de 00 a 99), es decir año {\tt mod} 100.\\
\end{tabular}

\begin{tabular}{@{}p{20pt}p{421.5pt}@{}}
{\tt\%Y}&El año como un número decimal, usando el calendario gregoriano.\\
\end{tabular}

\begin{tabular}{@{}p{20pt}p{421.5pt}@{}}
{\tt\%\%}& Un carácter \verb|%| literal.\\
\end{tabular}

Todos los demás caracteres (ordinarios) en la cadena de formato simplemente se copian a la cadena resultante.

El primer argumento (tiempo calendario) que se le pasa a la función {\tt time2str} debe están en el rango entre $-62135596800$ y $+64092211199$, lo que corresponde al período desde las 00:00:00 del 1 de enero del 0001 hasta las 23:59:59 del 31 de diciembre del 4000 del calendario gregoriano.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\chapter{Controladores de tablas}
\label{drivers}

\noindent\hfil
\begin{tabular}{c}
por Andrew Makhorin \verb|<mao@gnu.org>|\\
y Heinrich Schuchardt \verb|<heinrich.schuchardt@gmx.de>|\\
\end{tabular}

\bigskip\bigskip

El {\it controlador de tablas} es un módulo del programa que permite la trasmisión de datos entre objetos de un modelo MathProg y tablas de datos.

Actualmente, el paquete GLPK tiene cuatro controladores de tablas:

\vspace*{-8pt}

\begin{itemize}
\item controlador interno de tablas CSV;
\item controlador interno de tablas xBASE;
\item controlador de tablas ODBC;
\item controlador de tablas MySQL.
\end{itemize}

\vspace*{-8pt}

\section{Controlador de tablas CSV}

El controlador de tablas CSV asume que la tabla de datos está representada en la forma de un archivo de texto plano, en el formato de archivo CSV (valores separados por coma) como se describe más adelante.

Para elegir el controlador de tablas CSV, su nombre en la sentencia table debe especificarse como \verb|"CSV"| y el único argumento debe especificar el nombre de un archivo de texto plano conteniendo la tabla. Por ejemplo:

\begin{verbatim}
      table datos IN "CSV" "datos.csv": ... ;
\end{verbatim}

El sufijo del nombre de archivo puede ser arbitrario; sin embargo, se recomienda usar el sufijo `\verb|.csv|'.

\newpage

Al leer tablas de entrada, el controlador de tablas CSV provee un campo implícito llamado \verb|RECNO|, el cual contiene el número del registro corriente. Este campo puede especificarse en la sentencia table de entrada, como si existiera un verdadero campo llamado \verb|RECNO| en el archivo CSV. Por ejemplo:

\begin{verbatim}
      table lista IN "CSV" "lista.csv": num <- [RECNO], ... ;
\end{verbatim}

\subsection*{Formato CSV\footnote{Este material está basado en el documento RFC 4180.}}

El formato CSV (valores separados por coma) es un formato de archivo de texto plano definido como sigue:

1. Cada registro se ubica en una línea separada, delimitada por un salto de línea. Por ejemplo:

\begin{verbatim}
      aaa,bbb,ccc\n
      xxx,yyy,zzz\n
\end{verbatim}

\noindent
donde \verb|\n| significa el carácter de control \verb|LF| ({\tt 0x0A}).

2. El último registro en el archivo puede tener un salto de línea final o no. Por ejemplo:

\begin{verbatim}
      aaa,bbb,ccc\n
      xxx,yyy,zzz
\end{verbatim}

3. Debería haber una línea de encabezado que aparezca en la primera línea del archivo, en el mismo formato que las líneas de registro normales. Este encabezado debería contener nombres que correspondan a los campos en el archivo. El número de nombres de campo en la línea de encabezado debe ser igual al número de campos de los registros en el archivo. Por ejemplo:

\begin{verbatim}
      nombre1,nombre2,nombre3\n
      aaa,bbb,ccc\n
      xxx,yyy,zzz\n
\end{verbatim}

4. Dentro del encabezado y de cada registro puede haber uno o más campos separados por comas. Cada línea debe contener el mismo número de campos a través de todo el archivo. Los espacios se consideran parte del campo y, consecuentemente, no son ignorados. El último campo en el registro no debe estar seguido de una coma. Por ejemplo:

\begin{verbatim}
      aaa,bbb,ccc\n
\end{verbatim}

5. Los campos pueden estar encerrados entre comillas dobles o no. Por ejemplo:

\begin{verbatim}
      "aaa","bbb","ccc"\n
      zzz,yyy,xxx\n
\end{verbatim}

6. Si el campo se encierra entre comillas dobles, cada comilla doble que sea parte del campo debe codificarse dos veces. Por ejemplo:

\begin{verbatim}
      "aaa","b""bb","ccc"\n
\end{verbatim}

\newpage

\para{Ejemplo}

\begin{verbatim}
DESDE,HACIA,DISTANCIA,COSTO
Seattle,New-York,2.5,0.12
Seattle,Chicago,1.7,0.08
Seattle,Topeka,1.8,0.09
San-Diego,New-York,2.5,0.15
San-Diego,Chicago,1.8,0.10
San-Diego,Topeka,1.4,0.07
\end{verbatim}

\section{Controlador de tablas xBASE}

El controlador de tablas xBASE asume que la tabla de datos se almacenó en formato de archivo .dbf.

Para elegir el controlador de tablas xBASE, su nombre en la sentencia table debe especificarse como \verb|"xBASE"| y el primer argumento debe especificar el nombre de un archivo .dbf que contenga la tabla. Para la tabla de salida, debe haber un segundo argumento definiendo el formato de la tabla en la forma \verb|"FF...F"|, donde \verb|F| es tanto {\tt C({\it n})}, el cual especifica un campo de caracteres de longitud $n$, como
 {\tt N({\it n}{\rm [},{\it p}{\rm ]})}, el cual especifica un campo numérico de longitud $n$ y precisión $p$ (por defecto, $p$ es 0).

El siguiente es un ejemplo simple que ilustra la creación y lectura de un archivo .dbf:

\begin{verbatim}
table tab1{i in 1..10} OUT "xBASE" "foo.dbf"
   "N(5)N(10,4)C(1)C(10)": 2*i+1 ~ B, Uniform(-20,+20) ~ A,
   "?" ~ FOO, "[" & i & "]" ~ C;
set M, dimen 4;
table tab2 IN "xBASE" "foo.dbf": M <- [B, C, RECNO, A];
display M;
end;
\end{verbatim}

\section{Controlador de tablas ODBC}

El controlador de tablas ODBC permite conexiones con bases de datos SQL usando una implementación de la interfaz ODBC basada en la Call Level Interface (CLI).\footnote{La norma de software correspondiente se define en ISO/IEC 9075-3:2003.}

\para{Debian GNU/Linux.}
Bajo Debian GNU/Linux, el controlador de tablas ODBC usa el paquete iODBC,\footnote{Ver {\tt<http://www.iodbc.org/>}.} el cual debe estar instalado antes de compilar el paquete GLPK. La instalación se puede efectuar con el siguiente comando:

\begin{verbatim}
      sudo apt-get install libiodbc2-dev
\end{verbatim}

Debe notarse que para la configuración del paquete GLPK para activar el uso de la librería iODBC, se debe pasar la opción `\verb|--enable-odbc|' al script de configuración.

Para su uso en todo el sistema, las bases de datos individuales deben ingresarse en \verb|/etc/odbc.ini| y \verb|/etc/odbcinst.ini|. Las conexiones de las bases de datos usadas por un usuario individual se especifican mediante archivos en el directorio home (\verb|.odbc.ini| y \verb|.odbcinst.ini|).

\para{Microsoft Windows.}
Bajo Microsoft Windows, el controlador de tablas ODBC usa la librería ODBC de Microsoft. Para activar esta característica, el símbolo:

\begin{verbatim}
      #define ODBC_DLNAME "odbc32.dll"
\end{verbatim}

\noindent
debe definirse en el archivo de configuración de GLPK `\verb|config.h|'.

Las fuentes de datos pueden crearse por intermedio de las Herramientas Administrativas del Panel de Control.

Para elegir el controlador de tablas ODBC, su nombre en la sentencia table debe especificarse como \verb|'ODBC'| o \verb|'iODBC'|.

La lista de argumentos se especifica como sigue.

El primer argumento es la cadena de conexión que se pasa a la librería ODBC, por ejemplo:

\verb|'DSN=glpk;UID=user;PWD=password'|, o

\verb|'DRIVER=MySQL;DATABASE=glpkdb;UID=user;PWD=password'|.

Las diferentes partes de la cadena se separan con punto y coma. Cada parte consiste de un par {\it nombre de campo} y {\it valor} separados por el signo igual. Los nombres de campo permitidos dependen de la librería ODBC. Típicamente, se permiten los siguientes nombres de campo:

\verb|DATABASE | base de datos;

\verb|DRIVER   | controlador ODBC;

\verb|DSN      | nombre de una fuente de datos;

\verb|FILEDSN  | nombre de un archivo de fuente de datos;

\verb|PWD      | clave de usuario;

\verb|SERVER   | base de datos;

\verb|UID      | nombre de usuario.

El segundo argumento, y todos los siguientes, son considerados como sentencias SQL.

Las sentencias SQL se pueden extender sobre múltiples argumentos. Si el último carácter de un argumento es un punto y coma, este indica el final de una sentencia SQL.

Los argumentos de una sentencia SQL se concatenan separados por espacios. El eventual punto y coma final será removido.

Todas las sentencias SQL, excepto la última, se ejecutarán directamente.

Para table-IN, la última sentencia SQL puede ser un comando SELECT que empieza con \verb|'SELECT '| en letras mayúsculas. Si la cadena no se inicia con \verb|'SELECT '|, se considera que es un nombre de tabla y automáticamente se genera una sentencia SELECT.

Para table-OUT, la última sentencia SQL puede contener uno o múltiples signos de interrogación. Si contiene un signo de interrogación, se considera como una plantilla para la rutina de escritura. De otro modo, la cadena es considerada un nombre de tabla y se genera automáticamente una plantilla INSERT.

La rutina de escritura usa la plantilla con el signo de interrogación y reemplaza al primer signo de interrogación con el primer parámetro de salida, el segundo signo de interrogación con el segundo parámetro de salida, y así sucesivamente. Luego se emite el comando SQL.

El siguiente es un ejemplo de la sentencia table de salida:

\begin{verbatim}
table ta { l in LOCALIDADES } OUT
   'ODBC'
   'DSN=glpkdb;UID=glpkuser;PWD=glpkpassword'
   'DROP TABLE IF EXISTS resultados;'
   'CREATE TABLE resultados ( ID INT, LOC VARCHAR(255), CANT DOUBLE );'
   'INSERT INTO resultados 'VALUES ( 4, ?, ? )' :
   l ~ LOC, cantidad[l] ~ CANT;
\end{verbatim}

\noindent
Alternativamente, se puede escribir como sigue:

\begin{verbatim}
table ta { l in LOCALIDADES } OUT
   'ODBC'
   'DSN=glpkdb;UID=glpkuser;PWD=glpkpassword'
   'DROP TABLE IF EXISTS resultados;'
   'CREATE TABLE resultados ( ID INT, LOC VARCHAR(255), CANT DOUBLE );'
   'resultados' :
   l ~ LOC, cantidad[l] ~ CANT, 4 ~ ID;
\end{verbatim}

El uso de plantillas con `\verb|?|' no sólo permite INSERT, sino también UPDATE, DELETE, etc. Por ejemplo:

\begin{verbatim}
table ta { l in LOCALIDADES } OUT
   'ODBC'
   'DSN=glpkdb;UID=glpkuser;PWD=glpkpassword'
   'UPDATE resultados SET FECHA = ' & fecha & ' WHERE ID = 4;'
   'UPDATE resultados SET CANT = ? WHERE LOC = ? AND ID = 4' :
   cantidad[l], l;
\end{verbatim}

\section{Controlador de tablas MySQL}

El controlador de tablas permite conexiones con bases de datos MySQL.

\para{Debian GNU/Linux.}
Bajo Debian GNU/Linux, el controlador de tablas MySQL usa el paquete MySQL,\footnote{Para descargar los archivos de desarrollo, ver
{\tt<http://dev.mysql.com/downloads/mysql/>}.} el cual debe estar instalado antes de compilar el paquete GLPK. La instalación se puede efectuar con el siguiente comando:

\begin{verbatim}
      sudo apt-get install libmysqlclient15-dev
\end{verbatim}

Debe notarse que para la configuración del paquete GLPK para activar el uso de la librería MySQL, se debe pasar la opción `\verb|--enable-mysql|' al script de configuración.

\para{Microsoft Windows.}
Bajo Microsoft Windows, el controlador de tablas MySQL también usa la librería MySQL. Para activar esta característica, el símbolo:

\begin{verbatim}
      #define MYSQL_DLNAME "libmysql.dll"
\end{verbatim}

\noindent
debe definirse en el archivo de configuración de GLPK `\verb|config.h|'.

Para elegir el controlador de tablas MySQL, su nombre en la sentencia table debe especificarse como \verb|'MySQL'|.

La lista de argumentos se especifica como sigue.

El primer argumento especifica como conectar la base de datos en el estilo DSN, por ejemplo:

\verb|'Database=glpk;UID=glpk;PWD=gnu'|.

Las diferentes partes de la cadena se separan con punto y coma. Cada parte consiste de un par {\it nombre de campo} y {\it valor} separados por el signo igual. Se permiten los siguientes nombres de campo:

\verb|Server   | servidor corriendo la base de datos (localhost por defecto);

\verb|Database | nombre de la base de datos;

\verb|UID      | nombre de usuario;

\verb|PWD      | clave de usuario;

\verb|Port     | puerto usado por el servidor (3306 por defecto).

El segundo argumento, y todos los siguientes, son considerados como sentencias SQL.

Las sentencias SQL se pueden extender sobre múltiples argumentos. Si el último carácter de un argumento es un punto y coma, este indica el final de una sentencia SQL.

Los argumentos de una sentencia SQL se concatenan separados por espacios. El eventual punto y coma final será removido.

Todas las sentencias SQL, excepto la última, se ejecutarán directamente.

Para table-IN, la última sentencia SQL puede ser un comando SELECT que empieza con \verb|'SELECT '| en letras mayúsculas. Si la cadena no se inicia con \verb|'SELECT '|, se considera que es un nombre de tabla y automáticamente se genera una sentencia SELECT.

Para table-OUT, la última sentencia SQL puede contener uno o múltiples signos de interrogación. Si contiene un signo de interrogación, se considera como una plantilla para la rutina de escritura. De otro modo, la cadena es considerada un nombre de tabla y se genera automáticamente una plantilla INSERT.

La rutina de escritura usa la plantilla con el signo de interrogación y reemplaza al primer signo de interrogación con el primer parámetro de salida, el segundo signo de interrogación con el segundo parámetro de salida y así sucesivamente. Luego se emite el comando SQL.

El siguiente es un ejemplo de la sentencia table de salida:

\newpage

\begin{verbatim}
table ta { l in LOCALIDADES } OUT
   'MySQL'
   'Database=glpkdb;UID=glpkuser;PWD=glpkpassword'
   'DROP TABLE IF EXISTS resultados;'
   'CREATE TABLE resultados ( ID INT, LOC VARCHAR(255), CANT DOUBLE );'
   'INSERT INTO resultados VALUES ( 4, ?, ? )' :
   l ~ LOC, cantidad[l] ~ CANT;
\end{verbatim}

\noindent
Alternativamente, se puede escribir como sigue:

\begin{verbatim}
table ta { l in LOCALIDADES } OUT
   'MySQL'
   'Database=glpkdb;UID=glpkuser;PWD=glpkpassword'
   'DROP TABLE IF EXISTS resultados;'
   'CREATE TABLE resultados ( ID INT, LOC VARCHAR(255), CANT DOUBLE );'
   'resultados' :
   l ~ LOC, cantidad[l] ~ CANT, 4 ~ ID;
\end{verbatim}

El uso de plantillas con `\verb|?|' no sólo permite INSERT, sino también UPDATE, DELETE, etc. Por ejemplo:

\begin{verbatim}
table ta { l in LOCALIDADES } OUT
   'MySQL'
   'Database=glpkdb;UID=glpkuser;PWD=glpkpassword'
   'UPDATE resultados SET FECHA = ' & fecha & ' WHERE ID = 4;'
   'UPDATE resultados SET CANT = ? WHERE LOC = ? AND ID = 4' :
   cantidad[l], l;
\end{verbatim}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\chapter{Solución de modelos con glpsol}

El paquete GLPK\footnote{{\tt http://www.gnu.org/software/glpk/}} incluye el programa {\tt glpsol}, un {\it solver} autónomo de PL/PEM. Este programa puede ser invocado desde la línea de comando o desde el {\it shell} para resolver modelos escritos en el lenguaje de modelado GNU MathProg.

Para comunicarle al solver que el archivo de entrada contiene una descripción del modelo, es necesario especificar la opción \verb|--model| en la línea de comando. Por ejemplo:

\begin{verbatim}
      glpsol --model foo.mod
\end{verbatim}

A veces es necesario usar la sección de datos colocada en un archivo separado, en cuyo caso se debe usar el siguiente comando:

\begin{verbatim}
      glpsol --model foo.mod --data foo.dat
\end{verbatim}

\noindent Debe notarse que, si el archivo del modelo también contiene una sección de datos, esta sección será ignorada.

También se permite especificar más de un archivo conteniendo la sección de datos, por ejemplo:

\begin{verbatim}
      glpsol --model foo.mod --data foo1.dat --data foo2.dat
\end{verbatim}

Si la descripción del modelo contiene algunas sentencias display y/o printf, por defecto la salida es enviada a la terminal. Si se necesita redirigir la salida a un archivo, se puede usar el siguiente comando:

\begin{verbatim}
      glpsol --model foo.mod --display foo.out
\end{verbatim}

Si se necesita inspeccionar el problema, el cual ha sido generado por el traductor del modelo, se puede usar la opción \verb|--wlp| como sigue:

\begin{verbatim}
      glpsol --model foo.mod --wlp foo.lp
\end{verbatim}

\noindent En este caso el problema se escribe en el archivo \verb|foo.lp|, en formato CPLEX LP apropiado para el análisis visual.

\newpage

A veces sólo se necesita chequear la descripción del modelo, sin resolver la instancia generada del problema. En este caso, se debe especificar la opción \verb|--check|, por ejemplo:

\begin{verbatim}
      glpsol --check --model foo.mod --wlp foo.lp
\end{verbatim}

Si se necesita escribir una solución numérica obtenida por el solver en un archivo, se puede usar el siguiente comando:

\begin{verbatim}
      glpsol --model foo.mod --output foo.sol
\end{verbatim}

\noindent en cuyo caso la solución se escribe en el archivo \verb|foo.sol| en formato de texto plano apropiado para el análisis visual.

La lista completa de opciones de \verb|glpsol| se puede encontrar en el manual de referencia de GLPK incluido en la distribución de GLPK.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\chapter{Ejemplo de descripción del modelo}

\section{Descripción del modelo escrita en MathProg}

Abajo hay un ejemplo completo de la descripción de un modelo escrito en el lenguaje de modelado GNU MathProg.

\bigskip

\begin{verbatim}
# UN PROBLEMA DE TRANSPORTE
#
# Este problema determina la logística de costo mínimo de flete
# que cumple los requerimientos en los mercados y en las fábricas
# de suministro.
#
# Referencia:
#              Dantzig G B. 1963. Linear Programming and Extensions.
#              Princeton University Press, Princeton, New Jersey.
#              Sección 3-3.

set I;
/* plantas de enlatado */

set J;
/* mercados */

param a{i in I};
/* producción de la planta i, en cajas */

param b{j in J};
/* demanda en el mercado j, en cajas */

param d{i in I, j in J};
/* distancia, en miles de millas */

param f;
/* flete, en dólares por caja cada mil millas */

param c{i in I, j in J} := f * d[i,j] / 1000;
/* costo de transporte, en miles de dólares por caja */

var x{i in I, j in J} >= 0;
/* cantidades despachadas, en cajas */

minimize costo: sum{i in I, j in J} c[i,j] * x[i,j];
/* costo total de transporte, en miles de dólares */

s.t. suministro{i in I}: sum{j in J} x[i,j] <= a[i];
/* observar el límite de suministro de la planta i */

s.t. demanda{j in J}: sum{i in I} x[i,j] >= b[j];
/* satisfacer la demanda del mercado j */

data;

set I := Seattle San-Diego;

set J := New-York Chicago Topeka;

param a := Seattle     350
           San-Diego   600;

param b := New-York    325
           Chicago     300
           Topeka      275;

param d :              New-York   Chicago   Topeka :=
           Seattle     2.5        1.7       1.8
           San-Diego   2.5        1.8       1.4  ;

param f := 90;

end;
\end{verbatim}

%\newpage

\section{Instancia generada del problema de PL}

Abajo está el resultado de la traducción del modelo de ejemplo producido por el solver \verb|glpsol|, con la opción \verb|--wlp| y escrita en el formato CPLEX LP.

\medskip

\begin{verbatim}
\* Problem: transporte *\

Minimize
 costo: + 0.225 x(Seattle,New~York) + 0.153 x(Seattle,Chicago)
 + 0.162 x(Seattle,Topeka) + 0.225 x(San~Diego,New~York)
 + 0.162 x(San~Diego,Chicago) + 0.126 x(San~Diego,Topeka)

Subject To
 suministro(Seattle): + x(Seattle,New~York) + x(Seattle,Chicago)
 + x(Seattle,Topeka) <= 350
 suministro(San~Diego): + x(San~Diego,New~York) + x(San~Diego,Chicago)
 + x(San~Diego,Topeka) <= 600
 demanda(New~York): + x(Seattle,New~York) + x(San~Diego,New~York) >= 325
 demanda(Chicago): + x(Seattle,Chicago) + x(San~Diego,Chicago) >= 300
 demanda(Topeka): + x(Seattle,Topeka) + x(San~Diego,Topeka) >= 275

End
\end{verbatim}

\section{Solución óptima del problema de PL}

Abajo está la solución óptima de la instancia generada del problema de PL encontrada por el solver \verb|glpsol|, con la opción \verb|--output| y escrita en formato de texto plano.

\medskip

%\begin{footnotesize}
\begin{verbatim}
Problem:    transporte
Rows:       6
Columns:    6
Non-zeros:  18
Status:     OPTIMAL
Objective:  costo = 153.675 (MINimum)

   No.   Row name   St   Activity     Lower bound   Upper bound    Marginal
------ ------------ -- ------------- ------------- ------------- -------------
     1 costo        B        153.675
     2 suministro[Seattle]
                    NU           350                         350         < eps
     3 suministro[San-Diego]
                    B            550                         600
     4 demanda[New-York]
                    NL           325           325                       0.225
     5 demanda[Chicago]
                    NL           300           300                       0.153
     6 demanda[Topeka]
                    NL           275           275                       0.126

   No. Column name  St   Activity     Lower bound   Upper bound    Marginal
------ ------------ -- ------------- ------------- ------------- -------------
     1 x[Seattle,New-York]
                    B             50             0
     2 x[Seattle,Chicago]
                    B            300             0
     3 x[Seattle,Topeka]
                    NL             0             0                       0.036
     4 x[San-Diego,New-York]
                    B            275             0
     5 x[San-Diego,Chicago]
                    NL             0             0                       0.009
     6 x[San-Diego,Topeka]
                    B            275             0

End of output
\end{verbatim}
%\end{footnotesize}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\newpage

\section*{Reconocimientos}
\addcontentsline{toc}{chapter}{Reconocimientos}

Los autores desean agradecer a las siguientes personas, quienes amablemente leyeron, comentaron y corrigieron el borrador de este documento:

\noindent Juan Carlos Borrás \verb|<borras@cs.helsinki.fi>|

\noindent Harley Mackenzie \verb|<hjm@bigpond.com>|

\noindent Robbie Morrison \verb|<robbie@actrix.co.nz>|

\end{document}