| 1 |
#include <string.h> |
| 2 |
#include <stdio.h> |
| 3 |
#include "lpkit.h" |
| 4 |
#include "lpglob.h" |
| 5 |
#include "patchlevel.h" |
| 6 |
|
| 7 |
void print_help(char *argv[]) |
| 8 |
{ |
| 9 |
printf("Usage of %s version %s:\n", argv[0], PATCHLEVEL); |
| 10 |
printf("%s [options] \"<\" <input_file>\n", argv[0]); |
| 11 |
printf("list of options:\n"); |
| 12 |
printf("-h\t\tprints this message\n"); |
| 13 |
printf("-v\t\tverbose mode, gives flow through the program\n"); |
| 14 |
printf("-d\t\tdebug mode, all intermediate results are printed,\n\t\tand the branch-and-bound decisions\n"); |
| 15 |
printf("-p\t\tprint the values of the dual variables\n"); |
| 16 |
printf("-b <bound>\tspecify a lower bound for the objective function\n\t\tto the program. If close enough, may speed up the\n\t\tcalculations.\n"); |
| 17 |
printf("-i\t\tprint all intermediate valid solutions.\n\t\tCan give you useful solutions even if the total run time\n\t\tis too long\n"); |
| 18 |
printf("-e <number>\tspecifies the epsilon which is used to determine whether a\n\t\tfloating point number is in fact an integer.\n\t\tShould be < 0.5\n"); |
| 19 |
printf("-c\t\tduring branch-and-bound, take the ceiling branch first\n"); |
| 20 |
printf("-s\t\tuse automatic problem scaling.\n"); |
| 21 |
printf("-I\t\tprint info after reinverting\n"); |
| 22 |
printf("-t\t\ttrace pivot selection\n"); |
| 23 |
printf("-mps\t\tread from MPS file instead of lp file\n"); |
| 24 |
printf("-degen\t\tuse perturbations to reduce degeneracy,\n\t\tcan increase numerical instability\n"); |
| 25 |
} |
| 26 |
|
| 27 |
int main(int argc, char *argv[]) |
| 28 |
{ |
| 29 |
lprec *lp; |
| 30 |
int i; |
| 31 |
nstring filename; |
| 32 |
FILE *input = NULL; |
| 33 |
short verbose = FALSE; |
| 34 |
short debug = FALSE; |
| 35 |
short print_sol = FALSE; |
| 36 |
short print_duals = FALSE; |
| 37 |
short floor_first = TRUE; |
| 38 |
short scaling = FALSE; |
| 39 |
short print_at_invert = FALSE; |
| 40 |
short tracing = FALSE; |
| 41 |
short mps = FALSE; |
| 42 |
short anti_degen = FALSE; |
| 43 |
int result; |
| 44 |
REAL obj_bound = (REAL)DEF_INFINITE; |
| 45 |
REAL epsilon = (REAL)DEF_EPSILON; |
| 46 |
REAL dual_opt; |
| 47 |
|
| 48 |
for(i = 1; i < argc; i++) |
| 49 |
{ |
| 50 |
if(strcmp(argv[i], "-v") == 0) |
| 51 |
verbose = TRUE; |
| 52 |
else if(strcmp(argv[i], "-d") == 0) |
| 53 |
debug = TRUE; |
| 54 |
else if(strcmp(argv[i], "-i") == 0) |
| 55 |
print_sol = TRUE; |
| 56 |
else if(strcmp(argv[i], "-c") == 0) |
| 57 |
floor_first = FALSE; |
| 58 |
else if(strcmp(argv[i], "-b") == 0) |
| 59 |
obj_bound = atof(argv[++i]); |
| 60 |
else if(strcmp(argv[i], "-e") == 0) |
| 61 |
{ |
| 62 |
epsilon = atof(argv[++i]); |
| 63 |
if((epsilon <= 0.0) || (epsilon >= 0.5)) |
| 64 |
{ |
| 65 |
fprintf(stderr, "Invalid epsilon %g; 0 < epsilon < 0.5\n", |
| 66 |
(double)epsilon); |
| 67 |
exit(1); |
| 68 |
} |
| 69 |
} |
| 70 |
else if(strcmp(argv[i], "-p") == 0) |
| 71 |
print_duals = TRUE; |
| 72 |
else if(strcmp(argv[i], "-h") == 0) |
| 73 |
{ |
| 74 |
print_help(argv); |
| 75 |
exit(0); |
| 76 |
} |
| 77 |
else if(strcmp(argv[i], "-s") == 0) |
| 78 |
scaling = TRUE; |
| 79 |
else if(strcmp(argv[i], "-I") == 0) |
| 80 |
print_at_invert=TRUE; |
| 81 |
else if(strcmp(argv[i], "-t") == 0) |
| 82 |
tracing=TRUE; |
| 83 |
else if(strcmp(argv[i],"-mps") == 0) |
| 84 |
mps=TRUE; |
| 85 |
else if(strcmp(argv[i],"-degen") == 0) |
| 86 |
anti_degen=TRUE; |
| 87 |
} |
| 88 |
|
| 89 |
if(mps) |
| 90 |
lp = read_mps(stdin, verbose); |
| 91 |
else |
| 92 |
lp = read_lp_file(stdin, verbose, "lp" ); |
| 93 |
|
| 94 |
if(lp->columns < 8 && verbose) |
| 95 |
print_lp(lp); |
| 96 |
if(scaling) |
| 97 |
auto_scale(lp); |
| 98 |
if(print_sol) |
| 99 |
lp->print_sol = TRUE; |
| 100 |
lp->epsilon = epsilon; |
| 101 |
if(print_duals) |
| 102 |
lp->print_duals = TRUE; |
| 103 |
if(debug) |
| 104 |
lp->debug = TRUE; |
| 105 |
if(!floor_first) |
| 106 |
lp->floor_first = FALSE; |
| 107 |
if(print_at_invert) |
| 108 |
lp->print_at_invert = TRUE; |
| 109 |
if(tracing == TRUE) |
| 110 |
lp->trace = TRUE; |
| 111 |
if(obj_bound != DEF_INFINITE) |
| 112 |
lp->obj_bound = obj_bound; |
| 113 |
lp->anti_degen = anti_degen; |
| 114 |
|
| 115 |
if(verbose) |
| 116 |
{ |
| 117 |
printf("Solving\n"); |
| 118 |
lp->verbose = TRUE; |
| 119 |
} |
| 120 |
|
| 121 |
result = solve(lp); |
| 122 |
|
| 123 |
if(result == OPTIMAL) |
| 124 |
{ |
| 125 |
print_solution(lp); |
| 126 |
if(verbose) |
| 127 |
fprintf(stderr, |
| 128 |
"Branch & Bound depth: %d\nNodes processed: %d\nSimplex pivots: %d\n", |
| 129 |
lp->max_level, lp->total_nodes, lp->total_iter); |
| 130 |
} |
| 131 |
|
| 132 |
if(result == INFEASIBLE) |
| 133 |
printf("This problem is infeasible\n"); |
| 134 |
if(result == UNBOUNDED) |
| 135 |
printf("This problem is unbounded\n"); |
| 136 |
if(result == FAILURE) |
| 137 |
printf("lp_solve failed\n"); |
| 138 |
return(result); |
| 139 |
} |