-
Notifications
You must be signed in to change notification settings - Fork 2
/
lpdemo2.c
171 lines (146 loc) · 5.3 KB
/
lpdemo2.c
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
/*
lpdemo2.c Contributed by Terje Lensberg October 28, 2015
- Contains a C struct to represent LP problems and code to solve such LP representations with lrs
- Illustrates the interface to lrs and its use of rational numbers
- This version does only maximization
- Compile:
gcc -O3 -o lpdemo2 lpdemo2.c lrslib.c lrsgmp.c -lgmp -DGMP
- Usage: ./lpdemo2
*/
#include <stdio.h>
#include <string.h>
#include "lrsdriver.h"
#include "lrslib.h"
#define LE -1L // A constraint type used here. GE and EQ are defined in lrslib.h
#define ROW 0
#define COL 1
#define MAXROW 10 // maximum number of rows
#define MAXCOL 10 // maximum number of columns
typedef struct {
long num;
long den;
} ratnum; // Rational number: "num/den"
typedef struct {
ratnum a[MAXCOL]; // Coefficients
long ctype; // Constraint type (GE, LE, EQ)
ratnum rhs; // 'b'
} lprow; // A row in the LP problem
typedef struct { // C struct to represent an LP problem
long dim[2]; // Number of rows and cols
lprow row[MAXROW]; // The rows
} lpp;
/* An LP problem:
max z = (3/4)*x1 + x2 - x3
s.t. 2*x1 + (2/3)*x2 - (2/3)*x3 <= 1
x1 + 2*x2 + (1/3)*x3 <= 3/2
x1 + x2 + x3 = 1
x1 >= 0
x2 >= 0
x3 >= 0
Solution: x1 = 11/32, x2 = 9/16, x3 = 3/32, z = 93/128
*/
lpp LP = // The LP problem as a C struct with coefficients as rational numbers {num,den}
{ {7, 3}, // Dimensions
{ // -------- a --------- ctype rhs // lprow contents
{ {{3,4}, {1,1}, {-1,1}}, GE, {0,1} }, // Objective function (goes in row 0 with constraint type GE)
{ {{2,1}, {2,3}, {-2,3}}, LE, {1,1} }, // Inequality constraints
{ {{1,1}, {2,1}, { 1,3}}, LE, {3,2} },
{ {{1,1}, {1,1}, { 1,1}}, EQ, {1,1} }, // Equality constraint
{ {{1,1}, {0,1}, { 0,1}}, GE, {0,1} }, // Lower bounds
{ {{0,1}, {1,1}, { 0,1}}, GE, {0,1} },
{ {{0,1}, {0,1}, { 1,1}}, GE, {0,1} }
}
};
//----------------------------------------------------------------------------------------//
// Build an lrs representation from the C struct:
// - Replace LE constraints with GE by multiplying LE rows by -1
// - Multiply the RHS column by -1 and move it in front of matrix a
// - For each row, call lrs_set_row() with the associated (and possibly modified) constraint type
void buildLP (lrs_dic *P, lrs_dat *Q, lpp *lp)
{
long num[MAXCOL];
long den[MAXCOL];
long i, j, sgn;
long m = lp->dim[ROW];
long n = lp->dim[COL];
lprow *row;
for (i=0; i<m; i++) {
row = lp->row + i;
sgn = row->ctype == LE ? -1L : 1L; // sgn = 1 for EQ too
if(sgn < 0L) // ctype == LE. Multiply row by -1 and change ctype to GE
row->ctype = GE;
// RHS
num[0] = -sgn*row->rhs.num; // Opposite sign in column 0
den[0] = row->rhs.den;
// Coef. matrix
for(j=0; j<n; j++) {
num[j+1] = sgn*row->a[j].num; // j+1: RHS goes in column 0
den[j+1] = row->a[j].den;
}
// Specify constraint type and set row
lrs_set_row(P,Q,i,num,den,row->ctype);
/*
{ // Uncomment this to print the lrs input representation of the LP problem
char out[40];
printf("\n");
for(j=0;j<n+1;j++) {
if(den[j] == 1)
sprintf(out, "%ld", num[j]);
else
sprintf(out, "%ld/%ld", num[j], den[j]);
printf(" %7s", out);
}
printf(" ctype=%s", row->ctype == GE ? "GE" : "EQ");
} // end print
*/
}
printf("\n");
}
//----------------------------------------------------------------------------------------//
// This is a slightly modified version of main() in lpdemo.c
int lp_solve (lpp *lp)
{
lrs_dic *P; /* structure for holding current dictionary and indices */
lrs_dat *Q; /* structure for holding static problem data */
lrs_mp_vector output; /* one line of output:ray,vertex,facet,linearity */
long col; /* output column index for dictionary */
// allocate and init structure for static problem data
Q = lrs_alloc_dat ("LRS globals");
if (Q == NULL)
return 1;
strcpy(Q->fname,"lpdemo2");
Q->m = lp->dim[ROW]-1; // Rows, excluding the objective function
Q->n = 1+lp->dim[COL]; // Columns, including RHS which goes in column 0
Q->lponly = TRUE; // we do not want all vertices generated!
Q->maximize = TRUE;
output = lrs_alloc_mp_vector (Q->n);
P = lrs_alloc_dic (Q); // allocate and initialize lrs_dic
if (P == NULL)
return 1;
// Build the LP representation in the format required by lrs
buildLP(P,Q,lp);
// Solve the LP
if (!lrs_solve_lp(P,Q))
return 1;
// Print output
prat ("\nObjective value = ", P->objnum, P->objden);
for (col = 0; col < Q->n; col++)
if (lrs_getsolution (P, Q, output, col))
lrs_printoutput (Q, output);
/* free space : do not change order of next lines! */
lrs_clear_mp_vector (output, Q->n);
lrs_free_dic (P,Q); /* deallocate lrs_dic */
lrs_free_dat (Q); /* deallocate lrs_dat */
return 0;
}
//----------------------------------------------------------------------------------------//
int main(void)
{
lpp *lp = &LP;
/* Global initialization - done once */
if ( !lrs_init ("\n*lpdemo2:"))
return 1;
lp_solve(lp);
lrs_close ("lp:");
printf("\n");
}