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}
|