aboutsummaryrefslogtreecommitdiffstats
path: root/native/src
diff options
context:
space:
mode:
Diffstat (limited to 'native/src')
-rw-r--r--native/src/blocking/linprog/lp_dflp.cpp4
-rw-r--r--native/src/blocking/linprog/lp_dpcp.cpp4
-rw-r--r--native/src/linprog/glpk.cpp206
-rw-r--r--native/src/testmain.cpp3
4 files changed, 212 insertions, 5 deletions
diff --git a/native/src/blocking/linprog/lp_dflp.cpp b/native/src/blocking/linprog/lp_dflp.cpp
index 6198825..0370358 100644
--- a/native/src/blocking/linprog/lp_dflp.cpp
+++ b/native/src/blocking/linprog/lp_dflp.cpp
@@ -153,7 +153,7 @@ static BlockingBounds* _lp_dflp_bounds(const ResourceSharingInfo& info,
153#endif 153#endif
154 154
155 // Solve the big, combined LP. 155 // Solve the big, combined LP.
156 Solution *sol = cplex_solve(lp, var_idx); 156 Solution *sol = linprog_solve(lp, var_idx);
157 157
158 assert(sol != NULL); 158 assert(sol != NULL);
159 159
@@ -225,7 +225,7 @@ static void apply_dflp_bounds_for_task(
225 solver_cost.start(); 225 solver_cost.start();
226#endif 226#endif
227 227
228 Solution *sol = cplex_solve(lp, vars.get_num_vars()); 228 Solution *sol = linprog_solve(lp, vars.get_num_vars());
229 229
230#if DEBUG_LP_OVERHEADS >=2 230#if DEBUG_LP_OVERHEADS >=2
231 solver_cost.stop(); 231 solver_cost.stop();
diff --git a/native/src/blocking/linprog/lp_dpcp.cpp b/native/src/blocking/linprog/lp_dpcp.cpp
index 1b1cf32..bec131b 100644
--- a/native/src/blocking/linprog/lp_dpcp.cpp
+++ b/native/src/blocking/linprog/lp_dpcp.cpp
@@ -371,7 +371,7 @@ static BlockingBounds* _lp_dpcp_bounds(const ResourceSharingInfo& info,
371#endif 371#endif
372 372
373 // Solve the big, combined LP. 373 // Solve the big, combined LP.
374 Solution *sol = cplex_solve(lp, var_idx); 374 Solution *sol = linprog_solve(lp, var_idx);
375 375
376 assert(sol != NULL); 376 assert(sol != NULL);
377 377
@@ -445,7 +445,7 @@ static void apply_dpcp_bounds_for_task(
445 solver_cost.start(); 445 solver_cost.start();
446#endif 446#endif
447 447
448 Solution *sol = cplex_solve(lp, vars.get_num_vars()); 448 Solution *sol = linprog_solve(lp, vars.get_num_vars());
449 449
450#if DEBUG_LP_OVERHEADS >= 2 450#if DEBUG_LP_OVERHEADS >= 2
451 solver_cost.stop(); 451 solver_cost.stop();
diff --git a/native/src/linprog/glpk.cpp b/native/src/linprog/glpk.cpp
new file mode 100644
index 0000000..9ddf2c6
--- /dev/null
+++ b/native/src/linprog/glpk.cpp
@@ -0,0 +1,206 @@
1#include <assert.h>
2#include <glpk.h>
3
4#include <iostream>
5
6#include "cpu_time.h"
7
8#include "linprog/glpk.h"
9
10class GLPKSolution : public Solution
11{
12private:
13 glp_prob *glpk;
14 const LinearProgram &linprog;
15 const unsigned int num_cols;
16 const unsigned int num_rows;
17 unsigned int num_coeffs;
18
19 bool solved;
20
21 void solve(double var_lb, double var_ub);
22 void set_objective();
23 void set_bounds(double col_lb, double col_ub);
24 void set_coefficients();
25public:
26
27 GLPKSolution(const LinearProgram &lp, unsigned int max_num_vars,
28 double var_lb = 0.0, double var_ub = 1.0);
29
30 ~GLPKSolution();
31
32 double get_value(unsigned int var) const
33 {
34 return glp_get_col_prim(glpk, var + 1);
35 }
36
37 bool is_solved() const
38 {
39 return solved;
40 }
41};
42
43GLPKSolution::GLPKSolution(const LinearProgram& lp, unsigned int max_num_vars,
44 double var_lb, double var_ub)
45 : glpk(glp_create_prob()),
46 linprog(lp),
47 num_cols(max_num_vars),
48 num_rows(lp.get_equalities().size() +
49 lp.get_inequalities().size()),
50 num_coeffs(0),
51 solved(false)
52{
53 if (num_cols)
54 solve(var_lb, var_ub);
55 else
56 // Trivial case: no variables.
57 // This can happen if a task set does not
58 // contain any shared resources.
59 solved = true;
60}
61
62void GLPKSolution::solve(double var_lb, double var_ub)
63{
64#if DEBUG_LP_OVERHEADS >= 3
65 static DEFINE_CPU_CLOCK(init_costs);
66 static DEFINE_CPU_CLOCK(model_costs);
67 static DEFINE_CPU_CLOCK(solver_costs);
68
69 init_costs.start();
70#endif
71 glp_term_out(GLP_OFF);
72 glp_set_obj_dir(glpk, GLP_MAX);
73 glp_add_cols(glpk, num_cols);
74 glp_add_rows(glpk, num_rows);
75
76#if DEBUG_LP_OVERHEADS >= 3
77 init_costs.stop();
78 model_costs.start();
79#endif
80
81 set_objective();
82 set_bounds(var_lb, var_ub);
83 set_coefficients();
84
85#if DEBUG_LP_OVERHEADS >= 3
86 model_costs.stop();
87 solver_costs.start();
88#endif
89
90 glp_smcp glpk_params;
91
92 glp_init_smcp(&glpk_params);
93
94 glpk_params.presolve = GLP_ON;
95
96 solved = glp_simplex(glpk, &glpk_params) == 0 &&
97 glp_get_status(glpk) == GLP_OPT;
98
99#if DEBUG_LP_OVERHEADS >= 3
100 solver_costs.stop();
101
102 std::cout << init_costs << std::endl
103 << model_costs << std::endl
104 << solver_costs << std::endl;
105#endif
106}
107
108GLPKSolution::~GLPKSolution()
109{
110 glp_delete_prob(glpk);
111}
112
113void GLPKSolution::set_objective()
114{
115 assert(linprog.get_objective()->get_terms().size() == num_cols);
116
117 foreach (linprog.get_objective()->get_terms(), term)
118 glp_set_obj_coef(glpk, term->second + 1, term->first);
119}
120
121
122void GLPKSolution::set_bounds(double col_lb, double col_ub)
123{
124 unsigned int r = 1;
125
126 foreach(linprog.get_equalities(), equ)
127 {
128 glp_set_row_bnds(glpk, r++, GLP_FX,
129 equ->second, equ->second);
130
131 num_coeffs += equ->first->get_terms().size();
132 }
133
134 foreach(linprog.get_inequalities(), inequ)
135 {
136 glp_set_row_bnds(glpk, r++, GLP_UP,
137 0, inequ->second);
138
139 num_coeffs += inequ->first->get_terms().size();
140 }
141
142 for (unsigned int c = 1; c <= num_cols; c++)
143 glp_set_col_bnds(glpk, c, GLP_DB, col_lb, col_ub);
144}
145
146void GLPKSolution::set_coefficients()
147{
148 int *row_idx, *col_idx;
149 double *coeff;
150
151 row_idx = new int[1 + num_coeffs];
152 col_idx = new int[1 + num_coeffs];
153 coeff = new double[1 + num_coeffs];
154
155 unsigned int r = 1, k = 1;
156
157 foreach(linprog.get_equalities(), equ)
158 {
159 foreach(equ->first->get_terms(), term)
160 {
161 assert(k <= num_coeffs);
162
163 row_idx[k] = r;
164 col_idx[k] = 1 + term->second;
165 coeff[k] = term->first;
166
167 k += 1;
168 }
169 r += 1;
170 }
171
172
173 foreach(linprog.get_inequalities(), inequ)
174 {
175 foreach(inequ->first->get_terms(), term)
176 {
177 assert(k <= num_coeffs);
178
179 row_idx[k] = r;
180 col_idx[k] = 1 + term->second;
181 coeff[k] = term->first;
182
183 k += 1;
184 }
185 r += 1;
186 }
187
188 glp_load_matrix(glpk, num_coeffs, row_idx, col_idx, coeff);
189
190 delete[] row_idx;
191 delete[] col_idx;
192 delete[] coeff;
193}
194
195
196Solution *glpk_solve(const LinearProgram& lp, unsigned int max_num_vars)
197{
198 GLPKSolution *sol = new GLPKSolution(lp, max_num_vars);
199 if (sol->is_solved())
200 return sol;
201 else
202 {
203 delete sol;
204 return NULL;
205 }
206}
diff --git a/native/src/testmain.cpp b/native/src/testmain.cpp
index 767af02..a68b786 100644
--- a/native/src/testmain.cpp
+++ b/native/src/testmain.cpp
@@ -930,7 +930,8 @@ int main(int argc, char** argv)
930 930
931 delete results; 931 delete results;
932 932
933#if defined(CONFIG_HAVE_CPLEX) 933
934#if defined(CONFIG_HAVE_CPLEX) || defined(CONFIG_HAVE_GLPK)
934 935
935 results = lp_dpcp_bounds(rsi, loc, false); 936 results = lp_dpcp_bounds(rsi, loc, false);
936 937