1
1
/* Solve linear programming problems by either vertex/point enumeration
2
2
or the primal simplex algorithm.
3
3
Copyright (C) 2001-2010 Roberto Bagnara <bagnara@cs.unipr.it>
4
Copyright (C) 2010-2011 BUGSENG srl (http://bugseng.com)
5
6
This file is part of the Parma Polyhedra Library (PPL).
127
129
"Reads a file in MPS format and attempts solution using the optimization\n" \
128
130
"algorithms provided by the PPL.\n\n" \
130
" -c, --check[=THRESHOLD] checks the obtained results; optima are checked\n" \
131
" with a tolerance of THRESHOLD (default %.10g)\n" \
132
" -i, --incremental solves the problem incrementally\n" \
132
" -c, --check[=THRESHOLD] checks the obtained results using GLPK;\n" \
133
" optima are checked with a tolerance of\n" \
134
" THRESHOLD (default %.10g); input data\n" \
135
" are also perturbed the same way as GLPK does\n" \
136
" -i, --incremental solves the problem incrementally\n"
137
#define USAGE_STRING1 \
133
138
" -m, --min minimizes the objective function\n" \
134
" -M, --max maximizes the objective function (default)\n"
135
#define USAGE_STRING1 \
139
" -M, --max maximizes the objective function (default)\n" \
136
140
" -n, --no-optimization checks for satisfiability only\n" \
137
141
" -r, --no-mip consider integer variables as real variables\n" \
138
142
" -CSECS, --max-cpu=SECS limits CPU usage to SECS seconds\n" \
139
143
" -RMB, --max-memory=MB limits memory usage to MB megabytes\n" \
140
144
" -h, --help prints this help text to stdout\n" \
141
" -oPATH, --output=PATH appends output to PATH\n" \
142
" -e, --enumerate use the (expensive!) enumeration method\n"
145
" -oPATH, --output=PATH appends output to PATH\n"
143
146
#define USAGE_STRING2 \
147
" -e, --enumerate use the (expensive!) enumeration method\n" \
144
148
" -pM, --pricing=M use pricing method M for simplex (assumes -s);\n" \
145
149
" M is an int from 0 to 2, default 0:\n" \
146
150
" 0 --> steepest-edge using floating point\n" \
337
341
l = strtol(optarg, &endptr, 10);
338
342
if (*endptr || l < 0)
339
343
fatal("a non-negative integer must follow `-R'");
344
else if (((unsigned long) l) > ULONG_MAX/(1024*1024))
345
max_bytes_of_virtual_memory = ULONG_MAX;
341
347
max_bytes_of_virtual_memory = l*1024*1024;
521
527
#if PPL_HAVE_DECL_RLIMIT_AS
524
limit_virtual_memory(unsigned bytes) {
530
limit_virtual_memory(unsigned long bytes) {
527
533
if (getrlimit(RLIMIT_AS, &t) != 0)
649
655
: lpx_mip_obj_val(glpk_lp);
651
657
if (fabs(ppl_optimum_value - glpk_optimum_value) > check_threshold) {
652
error("check failed: for GLPK the problem's optimum is %.10g,"
653
" not %.10g", glpk_optimum_value, ppl_optimum_value);
658
error("check failed: for GLPK the problem's optimum is %.20g,"
659
" not %.20g", glpk_optimum_value, ppl_optimum_value);
654
660
check_results_failed = 1;
813
819
/* Kludge: let's pass PPL_MIP_PROBLEM_STATUS_OPTIMIZED,
814
820
to let work `maybe_check_results'. */
815
821
maybe_check_results(PPL_MIP_PROBLEM_STATUS_OPTIMIZED, 0.0);
819
825
/* Check whether the problem is unbounded. */
836
842
if (verbosity >= 1)
837
843
fprintf(output_file, "Unbounded problem.\n");
838
844
maybe_check_results(PPL_MIP_PROBLEM_STATUS_UNBOUNDED, 0.0);
848
optimum_found = maximize
843
849
? ppl_Polyhedron_maximize_with_point(ppl_ph, ppl_objective_le,
844
optimum_n, optimum_d, &included,
850
optimum_n, optimum_d, &included,
846
852
: ppl_Polyhedron_minimize_with_point(ppl_ph, ppl_objective_le,
847
optimum_n, optimum_d, &included,
851
fatal("internal error");
853
ppl_delete_Polyhedron(ppl_ph);
853
optimum_n, optimum_d, &included,
855
856
#ifdef PPL_LPSOL_SUPPORTS_TIMINGS
970
977
/* Kludge: let's pass PPL_MIP_PROBLEM_STATUS_OPTIMIZED,
971
978
to let work `maybe_check_results'. */
972
979
maybe_check_results(PPL_MIP_PROBLEM_STATUS_OPTIMIZED, 0.0);
975
982
else if (status == PPL_MIP_PROBLEM_STATUS_UNBOUNDED) {
976
983
if (verbosity >= 1)
977
984
fprintf(output_file, "Unbounded problem.\n");
978
985
maybe_check_results(status, 0.0);
981
988
else if (status == PPL_MIP_PROBLEM_STATUS_OPTIMIZED) {
982
989
ppl_MIP_Problem_optimal_value(ppl_mip, optimum_n, optimum_d);
983
990
ppl_MIP_Problem_optimizing_point(ppl_mip, &g);
984
991
ppl_assign_Generator_from_Generator(point, g);
988
996
fatal("internal error");
990
/* This is just to avoid a compiler warning. */
999
ppl_delete_MIP_Problem(ppl_mip);
1000
return optimum_found;
1004
set_mpq_t_from_double(mpq_t q, double d) {
1005
void set_d_eps(mpq_t x, double val);
1088
1106
/* Set `nz' to the number of non-zero coefficients. */
1089
1107
nz = lpx_get_mat_row(glpk_lp, row, coefficient_index, coefficient_value);
1090
1108
for (i = 1; i <= nz; ++i) {
1091
mpq_set_d(rational_coefficient[i], coefficient_value[i]);
1109
set_mpq_t_from_double(rational_coefficient[i], coefficient_value[i]);
1092
1110
/* Update den_lcm. */
1093
1111
mpz_lcm(den_lcm, den_lcm, mpq_denref(rational_coefficient[i]));
1095
1113
lpx_get_row_bnds(glpk_lp, row, &type, &lb, &ub);
1096
mpq_set_d(rational_lb, lb);
1114
set_mpq_t_from_double(rational_lb, lb);
1097
1115
mpz_lcm(den_lcm, den_lcm, mpq_denref(rational_lb));
1098
mpq_set_d(rational_ub, ub);
1116
set_mpq_t_from_double(rational_ub, ub);
1099
1117
mpz_lcm(den_lcm, den_lcm, mpq_denref(rational_ub));
1101
1119
ppl_new_Linear_Expression_with_dimension(&ppl_le, dimension);
1132
1150
for (column = 1; column <= dimension; ++column) {
1133
1151
lpx_get_col_bnds(glpk_lp, column, &type, &lb, &ub);
1135
mpq_set_d(rational_lb, lb);
1136
mpq_set_d(rational_ub, ub);
1153
set_mpq_t_from_double(rational_lb, lb);
1154
set_mpq_t_from_double(rational_ub, ub);
1138
1156
/* Initialize the least common multiple computation. */
1139
1157
mpz_set_si(den_lcm, 1);
1159
1177
mpz_set_si(den_lcm, 1);
1161
1179
mpq_init(objective[0]);
1162
mpq_set_d(objective[0], lpx_get_obj_coef(glpk_lp, 0));
1180
set_mpq_t_from_double(objective[0], lpx_get_obj_coef(glpk_lp, 0));
1163
1181
for (i = 1; i <= dimension; ++i) {
1164
1182
mpq_init(objective[i]);
1165
mpq_set_d(objective[i], lpx_get_obj_coef(glpk_lp, i));
1183
set_mpq_t_from_double(objective[i], lpx_get_obj_coef(glpk_lp, i));
1166
1184
/* Update den_lcm. */
1167
1185
mpz_lcm(den_lcm, den_lcm, mpq_denref(objective[i]));
1170
1188
/* Set the ppl_objective_le to be the objective function. */
1171
1189
ppl_new_Linear_Expression_with_dimension(&ppl_objective_le, dimension);
1172
/* The inhomogeneous term is completely useless for our purpose. */
1190
/* Set value for objective function's inhomogeneous term. */
1191
mpz_mul(tmp_z, den_lcm, mpq_numref(objective[0]));
1192
mpz_divexact(tmp_z, tmp_z, mpq_denref(objective[0]));
1193
ppl_assign_Coefficient_from_mpz_t(ppl_coeff, tmp_z);
1194
ppl_Linear_Expression_add_to_inhomogeneous(ppl_objective_le, ppl_coeff);
1195
/* Set values for objective function's variable coefficients. */
1173
1196
for (i = 1; i <= dimension; ++i) {
1174
1197
mpz_mul(tmp_z, den_lcm, mpq_numref(objective[i]));
1175
1198
mpz_divexact(tmp_z, tmp_z, mpq_denref(objective[i]));
1180
1203
if (verbosity >= 4) {
1181
1204
fprintf(output_file, "Objective function:\n");
1205
if (mpz_cmp_si(den_lcm, 1) != 0)
1206
fprintf(output_file, "(");
1182
1207
ppl_io_fprint_Linear_Expression(output_file, ppl_objective_le);