4bff2e3938378cf39d671e73f552a8efbb65749c
[libfirm] / ir / lpp / lpp.h
1 /**
2  * Author:      Daniel Grund
3  * Date:        16.05.2005
4  * Copyright:   (c) Universitaet Karlsruhe
5  * Licence:     This file protected by GPL -  GNU GENERAL PUBLIC LICENSE.
6  * CVS-Id:      $Id: lpp.h 16112 2007-10-07 15:50:49Z mallon $
7  *
8  * Interface for specifying an milp. Does not define a solution method.
9  */
10 #ifndef _LPP_H
11 #define _LPP_H
12
13 #include <stdio.h>
14 #include <obstack.h>
15
16 #include "set.h"
17
18 #include "sp_matrix.h"
19
20 typedef enum _lpp_opt_t {
21         lpp_minimize,
22         lpp_maximize
23 } lpp_opt_t;
24
25 typedef enum _lpp_cst_t {
26         lpp_objective,
27         lpp_equal,
28         lpp_less,
29         lpp_greater
30 } lpp_cst_t;
31
32 typedef enum _lpp_var_t {
33         lpp_invalid,
34         lpp_rhs,
35         lpp_continous,
36         lpp_binary
37 } lpp_var_t;
38
39 typedef enum _lpp_sol_state_t {
40         lpp_unknown,
41         lpp_infeasible,
42         lpp_inforunb,
43         lpp_unbounded,
44         lpp_feasible,
45         lpp_optimal
46 } lpp_sol_state_t;
47
48 typedef enum _lpp_value_kind_t {
49         lpp_none,
50         lpp_value_start,
51         lpp_value_solution,
52 } lpp_value_kind_t;
53
54 typedef enum _lpp_emphasis_t {
55         lpp_balanced,
56         lpp_feasability,
57         lpp_optimality,
58         lpp_bestbound,
59         lpp_hiddenfeasibility
60 } lpp_emphasis_t;
61
62 typedef struct _name_t {
63         const char *name;           /**< the name of the var/constraint supplied by user */
64         int nr;                     /**< the col/row number in the matrix */
65         lpp_value_kind_t value_kind;
66         double value;
67         union _type {
68                 lpp_var_t var_type;
69                 lpp_cst_t cst_type;
70         } type;
71 } lpp_name_t;
72
73 typedef struct _lpp_t {
74         /* The problem data */
75         const char     *name;            /**< A textual name for this problem */
76         FILE           *log;             /**< The log file. */
77         lpp_opt_t      opt_type;         /**< Optimization direction */
78         struct obstack obst;             /**< Obstack for variable names */
79         sp_matrix_t    *m;               /**< The matrix holding objective, constraints and rhs */
80
81         /* Cst/Var to Nr mapping */
82         set *cst2nr;                     /**< Holds name_t's for constraints */
83         set *var2nr;                     /**< Holds name_t's for variables */
84
85         /* Nr to Cst/Var mapping */
86         int        cst_size, var_size;   /**< Size of the csts/vars-arrays below */
87         int        cst_next, var_next;   /**< Next free position in arrays below */
88         lpp_name_t **csts;               /**< Pointers to the elements in the cst2nr set */
89         lpp_name_t **vars;               /**< Pointers to the elements in the var2nr set */
90         double     objval;               /**< OUT: Value of the objective function. */
91         double     best_bound;           /**< OUT: best bound to the integer solution. */
92         double     grow_factor;          /**< The factor by which the vars and constraints are enlarged */
93
94         /* Solving options */
95         int    set_bound;                /**< IN: Boolean flag to set a bound for the objective function. */
96         double bound;                    /**< IN: The bound. Only valid if set_bound == 1. */
97         double time_limit_secs;          /**< IN: Time limit to obey while solving (0.0 means no time limit) */
98
99         /* Solution stuff */
100         lpp_sol_state_t sol_state;       /**< State of the solution */
101         double          sol_time;        /**< Time in seconds */
102         unsigned        iterations;      /**< Number of iterations CPLEX needed to solve the ILP (whatever this means) */
103
104         char           *error;
105         unsigned       next_name_number; /**< for internal use only */
106         lpp_emphasis_t emphasis;         /**< On what should CPLEX concentrate (feasibility, bestbound, ...) */
107
108         /* some statistic stuff */
109         unsigned       send_time;        /**< in case of solve_net: send time in usec */
110         unsigned       recv_time;        /**< in case of solve_net: recv time in usec */
111         unsigned       n_elems;          /**< number of elements stored in the matrix */
112         unsigned       matrix_mem;       /**< memory used by matrix elements (in bytes) */
113         double         density;          /**< density of the matrix (percentage) */
114 } lpp_t;
115
116 #define ERR_NAME_NOT_ALLOWED -2
117
118 /**
119  * Creates a new problem. Optimization type is minimize or maximize.
120  * Implicit row with name "obj" is inserted.
121  * Implicit col with name "rhs" is inserted.
122  */
123 lpp_t *new_lpp(const char *name, lpp_opt_t opt_type);
124
125 /**
126  * Creates a new problem. Optimization type is minimize or maximize.
127  * Implicit row with name "obj" is inserted.
128  * Implicit col with name "rhs" is inserted.
129  * @param estimated_vars   The estimated number of variables for the problem
130  * @param estimated_csts   The estimated number of constraints for the problem
131  * @param grow_factor      By which factor should the problem grow, if there are
132  *                         more variables or constraints than estimated.
133  */
134 lpp_t *new_lpp_userdef(const char *name, lpp_opt_t opt_type,
135                                            int estimated_vars, int estimated_csts, double grow_factor);
136
137 /**
138  * Frees the matrix embedded in the LPP.
139  */
140 void free_lpp_matrix(lpp_t *lpp);
141
142 /**
143  * Frees all memory allocated for LPP data structure.
144  */
145 void free_lpp(lpp_t *lpp);
146
147 /**
148  * @return The constant term in the objective function
149  */
150 double lpp_get_fix_costs(lpp_t *lpp);
151
152 /**
153  * Sets the constant term in the objective function to @p value
154  */
155 void lpp_set_fix_costs(lpp_t *lpp, double value);
156
157 /**
158  * Adds a constraint to a problem. If a constraint with the same name already
159  * exists nothing is altered, and the index of the existing entry is returned.
160  * @param cst_name The name of the constraint (1st char only alpha-numeric!). If NULL, a default name will be used.
161  * @param cst_type The type of constraint: objective, equality, less-or-equal, greater-or-equal
162  * @param rhs The right hand side value to set for this constraint.
163  * @return The (new or existing) index of the constraint
164  */
165 int lpp_add_cst(lpp_t *lpp, const char *cst_name, lpp_cst_t cst_type, double rhs);
166
167 /**
168  * Adds a constraint to a problem. If a constraint with the same name already
169  * exists it dies a horribly cruel death
170  * @param cst_name The name of the constraint (1st char only alpha-numeric!). If NULL, a default name will be used.
171  * @param cst_type The type of constraint: objective, equality, less-or-equal, greater-or-equal
172  * @param rhs The right hand side value to set for this constraint.
173  * @return The (new or existing) index of the constraint
174  */
175 int lpp_add_cst_uniq(lpp_t *lpp, const char *cst_name, lpp_cst_t cst_type, double rhs);
176
177 /**
178  * Returns the internal index of a constraint.
179  * @param cst_name The name of the constraint
180  * @return The internal index of constraint @p cst_name or -1 if it does not exist.
181  */
182 int lpp_get_cst_idx(lpp_t *lpp, const char *cst_name);
183
184 /**
185  * Returns the name of a constraint.
186  * @param index The internal index of a constraint.
187  * @param buf A buffer to hold the name of the constraint
188  * @param buf_size Size of the buffer
189  */
190 void lpp_get_cst_name(lpp_t *lpp, int index, char *buf, size_t buf_size);
191
192 /**
193  * Adds a variable to a problem. If a variable with the same name already
194  * exists nothing is altered, and the index of the existing entry is returned.
195  * @param var_name The name of the constraint (1st char only alpha-numeric!). If NULL, a default name will be used.
196  * @param var_type The type of variable: real, binary
197  * @param obj The objective value coefficient for this variable.
198  * @return The (new or existing) index of the variable
199  *
200  * NOTE: common integer or semi-continuous vars are not (yet) implemented
201  */
202 int lpp_add_var(lpp_t *lpp, const char *var_name, lpp_var_t var_type, double obj);
203
204 /**
205  * Same as lpp_add_var() but the user can supply a default value.
206  */
207 int lpp_add_var_default(lpp_t *lpp, const char *var_name, lpp_var_t var_type, double obj, double startval);
208
209 /**
210  * Returns the internal index of a variable.
211  * @param cst_name The name of the variable
212  * @return The internal index of variable @p var_name or -1 if it does not exist.
213  */
214 int lpp_get_var_idx(lpp_t *lpp, const char *var_name);
215
216 /**
217  * Returns the name of a variable.
218  * @param index The internal index of a variable.
219  * @param buf A buffer to hold the name of the variable
220  * @param buf_size Size of the buffer
221  */
222 void lpp_get_var_name(lpp_t *lpp, int index, char *buf, size_t buf_size);
223
224 /**
225  * Sets the factor of the variable @p var_name in constraint @p cst_name to @p value.
226  * @return -1 if constraint or variable name does not exist.
227  *          0 otherwise
228  */
229 int lpp_set_factor(lpp_t *lpp, const char *cst_name, const char *var_name, double value);
230
231 /**
232  * Same as lpp_set_factor but uses the internal indices instead of names.
233  * @return -1 if an index was invalid
234  *          0 otherwise
235  */
236 int lpp_set_factor_fast(lpp_t *lpp, int cst_idx, int var_idx, double value);
237
238 int lpp_set_factor_fast_bulk(lpp_t *lpp, int cst_idx, int *var_idx, int num_vars, double value);
239
240 /**
241  * Set a starting value for a var.
242  * @param var_idx The index of the variable to set the value for.
243  * @param value The value to set.
244  */
245 void lpp_set_start_value(lpp_t *lpp, int var_idx, double value);
246
247 /**
248  * @return The solution values of the variables from index begin to index end.
249  */
250 lpp_sol_state_t lpp_get_solution(lpp_t *lpp, double *values, int begin, int end);
251
252 /**
253  * Dumps the lpp into a file with name @p filename in MPS-format
254  */
255 void lpp_dump(lpp_t *lpp, const char *filename);
256
257 /**
258  * Set the log file, where the solver should write to.
259  * @param lpp The problem.
260  * @param log The logfile. NULL for no logging.
261  */
262 void lpp_set_log(lpp_t *lpp, FILE *log);
263
264 /**
265  * Check the start values and list conflicting constraints.
266  */
267 void lpp_check_startvals(lpp_t *lpp);
268
269 /**
270  * Dump problem into a text file.
271  * @param lpp The problem.
272  * @param f   The file.
273  */
274 void lpp_dump_plain(lpp_t *lpp, FILE *f);
275
276 #define lpp_get_iter_cnt(lpp)         ((lpp)->iterations)
277 #define lpp_get_sol_time(lpp)         ((lpp)->sol_time)
278 #define lpp_get_sol_state(lpp)        ((lpp)->sol_state)
279 #define lpp_get_var_count(lpp)        ((lpp)->var_next-1)
280 #define lpp_get_cst_count(lpp)        ((lpp)->cst_next-1)
281 #define lpp_get_sol_state(lpp)        ((lpp)->sol_state)
282 #define lpp_get_var_sol(lpp,idx)      ((lpp)->vars[idx]->value)
283 #define lpp_is_sol_valid(lpp)         (lpp_get_sol_state(lpp) >= lpp_feasible)
284
285 #define lpp_set_time_limit(lpp,secs)  ((lpp)->time_limit_secs = secs)
286
287 /**
288  * Set a bound for the objective function.
289  * @param lpp The problem.
290  * @param bound A bound for the objective function.
291  *              If the problem is a minimization problem, the bound
292  *              is a lower bound. If it is a maximization problem,
293  *              the bound is an upper bound.
294  */
295 #define lpp_set_bound(lpp,bnd)        ((lpp)->set_bound = 1, (lpp)->bound = (bnd))
296
297 /**
298  * Clear a set bound.
299  * @param lpp The problem.
300  */
301 #define lpp_unset_bound(lpp)          ((lpp)->set_bound = 0)
302
303 /**
304  * Solve an ILP.
305  * @param lpp    The problem.
306  * @param host   The host to solve on.
307  * @param solver The solver to use.
308  */
309 void lpp_solve(lpp_t *lpp, const char* host, const char* solver);
310
311 #endif /* _LPP_H */