simplex_glpk.c
Go to the documentation of this file.
1 #include "simplex.h"
2 #include "error.h"
3 #include "geom.h"
4 #include "defines.h"
5 
6 #include <math.h>
7 #include <string.h>
8 
22 void SimplexCreate(double epsilon,unsigned int ncols,TSimplex *s)
23 {
24  double ct;
25 
26  /* LP: Create an empty LP problem */
27  s->lp=lpx_create_prob();
28  if (s->lp==NULL)
29  Error("Problems creating LP tableau\n");
30 
31 
32  /* LP: Add the columns to the LP problem */
33  lpx_add_cols(s->lp,ncols);
34 
35 
36  /* LP: Adjust the verbosity of the LP problem */
37  #if (_DEBUG<5)
38  lpx_set_int_parm(s->lp,LPX_K_MSGLEV,0);
39  #endif
40 
41 
42  /* LP: Adjust LP internal parameters */
43  ct=lpx_get_real_parm(s->lp,LPX_K_TOLBND);
44  if (ct>(epsilon*1e-2))
45  lpx_set_real_parm(s->lp,LPX_K_TOLBND,epsilon*1e-2);
46 
47  ct=lpx_get_real_parm(s->lp,LPX_K_TOLDJ);
48  if (ct>(epsilon*1e-2))
49  lpx_set_real_parm(s->lp,LPX_K_TOLDJ,epsilon*1e-2);
50 
51  ct=lpx_get_real_parm(s->lp,LPX_K_TOLPIV);
52  if (ct>(epsilon*1e-4))
53  lpx_set_real_parm(s->lp,LPX_K_TOLPIV,epsilon*1e-4);
54 
55 
56  /* LP: Minimize */
57  lpx_set_obj_dir(s->lp,LPX_MIN);
58 
59 
60  /* LP: Timeout in seconds*/
61  lpx_set_real_parm(s->lp,ncols*LPX_K_TMLIM,SIMPLEX_TIMEOUT);
62 }
63 
64 /* LP: Reset the LP internal information */
66 {
67  lpx_adv_basis(s->lp);
68 }
69 
70 unsigned int SimplexNColumns(TSimplex *s)
71 {
72  return(lpx_get_num_cols(s->lp));
73 }
74 
75 unsigned int SimplexNRows(TSimplex *s)
76 {
77  return(lpx_get_num_rows(s->lp));
78 }
79 
80 /* LP: set bounds for a given column */
81 void SimplexSetColBounds(unsigned int ncol,Tinterval *i,TSimplex *s)
82 {
83  double l,u;
84 
85  l=LowerLimit(i);
86  u=UpperLimit(i);
87 
88  if (l==-INF)
89  {
90  if (u==INF)
91  lpx_set_col_bnds(s->lp,ncol+1,LPX_FR,0.0,0.0);
92  else
93  lpx_set_col_bnds(s->lp,ncol+1,LPX_UP,0.0,u);
94  }
95  else
96  {
97  if (u==INF)
98  lpx_set_col_bnds(s->lp,ncol+1,LPX_LO,l,0.0);
99  else
100  {
101  if (u==l)
102  lpx_set_col_bnds(s->lp,ncol+1,LPX_FX,l,l);
103  else
104  lpx_set_col_bnds(s->lp,ncol+1,LPX_DB,l,u);
105  }
106  }
107 }
108 
109 /* LP: get bounds for a given column */
110 void SimplexGetColBounds(unsigned int ncol,Tinterval *i,TSimplex *s)
111 {
112  unsigned int t;
113  double l,u;
114 
115  t=lpx_get_col_type(s->lp,ncol+1);
116  l=lpx_get_col_lb(s->lp,ncol+1);
117  u=lpx_get_col_ub(s->lp,ncol+1);
118 
119  switch(t)
120  {
121  case LPX_FR:
122  NewInterval(-INF,INF,i);
123  break;
124  case LPX_LO:
125  NewInterval(l,INF,i);
126  break;
127  case LPX_UP:
128  NewInterval(-INF,u,i);
129  break;
130  case LPX_FX:
131  case LPX_DB:
132  NewInterval(l,u,i); /*only columns of this type exists in our examples*/
133  break;
134  }
135 }
136 
137 void SimplexGetColConstraint(unsigned int ncol,TLinearConstraint *lc,TSimplex *s)
138 {
139  unsigned int m,k,i;
140  signed int *ind;
141  double *val;
142  Tinterval error;
143 
144  m=SimplexNRows(s);
145 
146  NEW(val,m+1,double);
147  NEW(ind,m+1,signed int);
148 
149  k=lpx_get_mat_col(s->lp,ncol+1,ind,val);
150 
152  for(i=1;i<=k;i++)
153  AddTerm2LinearConstraint(ind[i]-1,val[i],lc);
154 
155  SimplexGetColBounds(ncol,&error,s);
156  SetLinearConstraintError(&error,lc);
157 
158  free(ind);
159  free(val);
160 }
161 
162 boolean SimplexColEmpty(unsigned int ncol,TSimplex *s)
163 {
164  return((unsigned int)lpx_get_mat_col(s->lp,1+ncol,NULL,NULL)==0);
165 }
166 
167 double SimplexGetColPrimal(unsigned int ncol,TSimplex *s)
168 {
169  return(lpx_get_col_prim(s->lp,ncol+1));
170 }
171 
172 double SimplexGetColDual(unsigned int ncol,TSimplex *s)
173 {
174  return(lpx_get_col_dual(s->lp,ncol+1));
175 }
176 
177 /* LP: set bounds for a given row */
178 void SimplexSetRowBounds(unsigned int nrow,Tinterval *i,TSimplex *s)
179 {
180  double l,u;
181 
182  l=LowerLimit(i);
183  u=UpperLimit(i);
184 
185  if (l==-INF)
186  {
187  if (u==INF)
188  lpx_set_row_bnds(s->lp,nrow+1,LPX_FR,0.0,0.0);
189  else
190  lpx_set_row_bnds(s->lp,nrow+1,LPX_UP,0.0,u);
191  }
192  else
193  {
194  if (u==INF)
195  lpx_set_row_bnds(s->lp,nrow+1,LPX_LO,l,0.0);
196  else
197  {
198  if (u==l)
199  lpx_set_row_bnds(s->lp,nrow+1,LPX_FX,l,l);
200  else
201  lpx_set_row_bnds(s->lp,nrow+1,LPX_DB,l,u);
202  }
203  }
204 }
205 
206 /* LP: get bounds for a given row */
207 void SimplexGetRowBounds(unsigned int nrow,Tinterval *i,TSimplex *s)
208 {
209  unsigned int t;
210  double l,u;
211 
212  t=lpx_get_row_type(s->lp,nrow+1);
213  l=lpx_get_row_lb(s->lp,nrow+1);
214  u=lpx_get_row_ub(s->lp,nrow+1);
215 
216  switch(t)
217  {
218  case LPX_FR:
219  NewInterval(-INF,INF,i);
220  break;
221  case LPX_LO:
222  NewInterval(l,INF,i);
223  break;
224  case LPX_UP:
225  NewInterval(-INF,u,i);
226  break;
227  case LPX_FX:
228  case LPX_DB:
229  NewInterval(l,u,i);
230  break;
231  }
232 }
233 
234 void SimplexGetRowConstraint(unsigned int nrow,TLinearConstraint *lc,TSimplex *s)
235 {
236  unsigned int n,k,i;
237  signed int *ind;
238  double *val;
239  Tinterval error;
240 
241  n=SimplexNColumns(s);
242 
243  NEW(val,n+1,double);
244  NEW(ind,n+1,signed int);
245 
246  k=lpx_get_mat_row(s->lp,nrow+1,ind,val);
247 
249  for(i=1;i<=k;i++)
250  AddTerm2LinearConstraint(ind[i]-1,val[i],lc);
251 
252  SimplexGetRowBounds(nrow,&error,s);
253  SetLinearConstraintError(&error,lc);
254 
255  free(ind);
256  free(val);
257 }
258 
259 double SimplexGetRowPrimal(unsigned int nrow,TSimplex *s)
260 {
261  return(lpx_get_row_prim(s->lp,nrow+1));
262 }
263 
264 double SimplexGetRowDual(unsigned int nrow,TSimplex *s)
265 {
266  return(lpx_get_row_dual(s->lp,nrow+1));
267 }
268 
270 {
271  Tinterval bounds;
272  unsigned int nrow;
273  unsigned int i;
274  signed int *ind;
275  double *val;
276  unsigned int n;
277 
278  /* LP: Add a row to the tableau */
279  nrow=lpx_add_rows(s->lp,1);
280  if (nrow==((unsigned int)(-1)))
281  Error("Error adding constraint to simplex");
282 
284 
285  NEW(ind,n+1,signed int);
286  NEW(val,n+1,double);
287 
288  for(i=0;i<n;i++)
289  {
290  ind[i+1]=GetLinearConstraintVariable(i,lc)+1;
291  val[i+1]=GetLinearConstraintCoefficient(i,lc);
292  }
293 
294  /* LP: set the row information */
295  lpx_set_mat_row(s->lp,nrow,n,ind,val);
296 
297  free(ind);
298  free(val);
299 
300  GetLinearConstraintError(&bounds,lc);
301  SimplexSetRowBounds(nrow-1,&bounds,s);
302 
303 #if (_DEBUG>4)
304  printf(" Setting Row %u with range ",nrow-1);
305  PrintInterval(stdout,&bounds);
306  printf("\n ");
307  PrintLinearConstraint(stdout,TRUE,NULL,lc);
308 #endif
309 }
310 
311 
313 {
314  unsigned int i,n;
315 
316  #if (_DEBUG>4)
317  printf("Setting cost function: ");
318  #endif
319 
320  n=SimplexNColumns(s);
321 
322  for(i=0;i<n;i++)
323  lpx_set_obj_coef(s->lp,i+1,0.0);
324 
326  for(i=0;i<n;i++)
327  {
328  #if (_DEBUG>4)
329  printf("+%f*v[%u]",
332  #endif
333  lpx_set_obj_coef(s->lp,
336  }
337  #if (_DEBUG>4)
338  printf("\n");
339  #endif
340 }
341 
342 
344 {
345  unsigned int i,n;
346 
348 
349  n=SimplexNColumns(s);
350 
351  for(i=0;i<n;i++)
352  AddTerm2LinearConstraint(i,lpx_get_obj_coef(s->lp,i+1),obj);
353 }
354 
356 {
357  return(lpx_get_obj_val(s->lp));
358 }
359 
360 unsigned int SimplexSolve(TSimplex *s)
361 {
362  unsigned int r;
363 
364  r=lpx_simplex(s->lp);
365 
366  if (r==LPX_E_TMLIM)
367  return(ERROR_IN_PROCESS);
368  else
369  {
370  if (r==LPX_E_OK)
371  {
372  r=lpx_get_status(s->lp);
373 
374  if (r==LPX_OPT)
375  return(REDUCED_BOX);
376  else
377  {
378  if (r==LPX_NOFEAS)
379  return(EMPTY_BOX);
380  else
381  {
382  if (r==LPX_UNBND)
383  return(UNBOUNDED_BOX);
384  else
385  return(ERROR_IN_PROCESS);
386  }
387  }
388  }
389  else
390  return(ERROR_IN_PROCESS);
391  }
392 }
393 
395 {
396  lpx_delete_prob(s->lp);
397 }
398 
399 
void SimplexCreate(double epsilon, unsigned int ncols, TSimplex *s)
Constructor.
Definition: simplex_glpk.c:22
void SimplexGetColConstraint(unsigned int ncol, TLinearConstraint *lc, TSimplex *s)
Gets a column from the simplex in the form of a linear constraint.
Definition: simplex_glpk.c:137
#define ERROR_IN_PROCESS
One of the possible results of reducing a box.
Definition: box.h:32
Definition of basic functions.
#define UNBOUNDED_BOX
One of the possible results of reducing a box.
Definition: box.h:45
void SimplexSetOptimizationFunction(TLinearConstraint *obj, TSimplex *s)
Sets a new objective function.
Definition: simplex_glpk.c:312
#define NEW(_var, _n, _type)
Allocates memory space.
Definition: defines.h:385
A linear constraint with an associated error.
void ResetSimplex(TSimplex *s)
Resets the simplex structure.
Definition: simplex_glpk.c:65
double SimplexGetOptimalValueRaw(TSimplex *s)
Gets the optimal value after optimizing the problem.
Definition: simplex_glpk.c:355
double SimplexGetRowDual(unsigned int nrow, TSimplex *s)
Gets a row dual value after solving the simplex.
Definition: simplex_glpk.c:264
boolean SimplexColEmpty(unsigned int ncol, TSimplex *s)
Checks if a simplex column is empty.
Definition: simplex_glpk.c:162
void SimplexDelete(TSimplex *s)
Destructor.
Definition: simplex_glpk.c:394
void InitLinearConstraint(TLinearConstraint *lc)
Constructor.
#define EMPTY_BOX
One of the possible results of reducing a box.
Definition: box.h:25
unsigned int GetLinearConstraintVariable(unsigned int i, TLinearConstraint *lc)
Gets the a particular variable index.
void PrintLinearConstraint(FILE *f, boolean eq, char **varName, TLinearConstraint *lc)
Prints a linear constraint.
#define TRUE
TRUE.
Definition: boolean.h:21
void Error(const char *s)
General error function.
Definition: error.c:80
SimplexType * lp
Definition: simplex.h:75
A simplex tableau structure.
Definition: simplex.h:73
void AddTerm2LinearConstraint(unsigned int ind, double val, TLinearConstraint *lc)
Adds a scaled variable to the linear constraint.
unsigned int SimplexSolve(TSimplex *s)
Determines an optimal value.
Definition: simplex_glpk.c:360
Error and warning functions.
void SimplexGetOptimizationFunction(TLinearConstraint *obj, TSimplex *s)
Gets a current objective function.
Definition: simplex_glpk.c:343
double LowerLimit(Tinterval *i)
Gets the lower limit.
Definition: interval.c:79
#define SIMPLEX_TIMEOUT
Simplex timeout.
Definition: simplex.h:63
Definitions of constants and macros used in several parts of the cuik library.
void SimplexSetRowBounds(unsigned int nrow, Tinterval *i, TSimplex *s)
Sets the bounds for a given row (i.e., constraint).
Definition: simplex_glpk.c:178
double SimplexGetColDual(unsigned int ncol, TSimplex *s)
Gets a column dual value after solving the simplex.
Definition: simplex_glpk.c:172
double UpperLimit(Tinterval *i)
Gets the uppser limit.
Definition: interval.c:87
double SimplexGetColPrimal(unsigned int ncol, TSimplex *s)
Gets a column primal value after solving the simplex.
Definition: simplex_glpk.c:167
void SimplexGetColBounds(unsigned int ncol, Tinterval *i, TSimplex *s)
Gets the bounds for a given column (i.e., variable).
Definition: simplex_glpk.c:110
unsigned int GetNumTermsInLinearConstraint(TLinearConstraint *lc)
Number of variables in a linear constraint.
void GetLinearConstraintError(Tinterval *error, TLinearConstraint *lc)
Gets the right-hand side interval for the linear constraint.
Definition of the TSimplex type and the associated functions.
void PrintInterval(FILE *f, Tinterval *i)
Prints an interval.
Definition: interval.c:1006
void SimplexSetColBounds(unsigned int ncol, Tinterval *i, TSimplex *s)
Sets the bounds for a given column (i.e., variable).
Definition: simplex_glpk.c:81
unsigned int SimplexNColumns(TSimplex *s)
Gets the number of columns (i.e., variables) of the simplex structure.
Definition: simplex_glpk.c:70
void SetLinearConstraintError(Tinterval *error, TLinearConstraint *lc)
Sets a new righ-hand side error of the linear constraint.
unsigned int SimplexNRows(TSimplex *s)
Gets the number of rows (i.e., constraints) of the simplex structure.
Definition: simplex_glpk.c:75
void NewInterval(double lower, double upper, Tinterval *i)
Constructor.
Definition: interval.c:47
#define INF
Infinite.
Definition: defines.h:70
double GetLinearConstraintCoefficient(unsigned int i, TLinearConstraint *lc)
Gets the a particular linear constraint coefficient.
#define REDUCED_BOX
One of the possible results of reducing a box.
Definition: box.h:38
Defines a interval.
Definition: interval.h:33
void SimplexGetRowBounds(unsigned int nrow, Tinterval *i, TSimplex *s)
Gets the bounds for a given row (i.e., constraint).
Definition: simplex_glpk.c:207
double SimplexGetRowPrimal(unsigned int nrow, TSimplex *s)
Gets a row primal value after solving the simplex.
Definition: simplex_glpk.c:259
void SimplexGetRowConstraint(unsigned int nrow, TLinearConstraint *lc, TSimplex *s)
Gets a row constraint from the simplex.
Definition: simplex_glpk.c:234
void SimplexAddNewConstraintRaw(TLinearConstraint *lc, TSimplex *s)
Adds a row (i.e., a constraint) to the simplex.
Definition: simplex_glpk.c:269