aboutsummaryrefslogtreecommitdiff
path: root/src/ats
diff options
context:
space:
mode:
authorMatthias Wachs <wachs@net.in.tum.de>2014-05-13 22:50:28 +0000
committerMatthias Wachs <wachs@net.in.tum.de>2014-05-13 22:50:28 +0000
commit745109bb6a59a312e118c3242ce4ed861566fe79 (patch)
tree9e900dd999a59f03f6b7197308afbf4fc5fa652f /src/ats
parentc2335d65e672477399b9bf208de9914e1e4f341b (diff)
downloadgnunet-745109bb6a59a312e118c3242ce4ed861566fe79.tar.gz
gnunet-745109bb6a59a312e118c3242ce4ed861566fe79.zip
implemented mip gap
Diffstat (limited to 'src/ats')
-rw-r--r--src/ats/ats.conf.in1
-rw-r--r--src/ats/perf_ats_solver.conf4
-rw-r--r--src/ats/plugin_ats_mlp.c128
-rw-r--r--src/ats/plugin_ats_mlp.h5
4 files changed, 102 insertions, 36 deletions
diff --git a/src/ats/ats.conf.in b/src/ats/ats.conf.in
index e1ad75c8f..f321b7af1 100644
--- a/src/ats/ats.conf.in
+++ b/src/ats/ats.conf.in
@@ -50,6 +50,7 @@ PROP_STABILITY_FACTOR = 125
50# MLP_MAX_ITERATIONS = 50# MLP_MAX_ITERATIONS =
51# Tolerated MIP Gap in percent [0 .. 100] 51# Tolerated MIP Gap in percent [0 .. 100]
52# MLP_MAX_MIP_GAP = 0.0 52# MLP_MAX_MIP_GAP = 0.0
53# MLP_MAX_LP_MIP_GAP = 0,0
53 54
54# Maximum number of iterations for a solution process 55# Maximum number of iterations for a solution process
55# MLP_MAX_ITERATIONS = 1024 56# MLP_MAX_ITERATIONS = 1024
diff --git a/src/ats/perf_ats_solver.conf b/src/ats/perf_ats_solver.conf
index 0557203f4..debcef8c7 100644
--- a/src/ats/perf_ats_solver.conf
+++ b/src/ats/perf_ats_solver.conf
@@ -36,7 +36,9 @@ PROP_STABILITY_FACTOR = 125
36# Maximum number of iterations for a solution process 36# Maximum number of iterations for a solution process
37# MLP_MAX_ITERATIONS = 1024 37# MLP_MAX_ITERATIONS = 1024
38# Tolerated MIP Gap [0.0 .. 1.0] 38# Tolerated MIP Gap [0.0 .. 1.0]
39MLP_MAX_MIP_GAP = 0,025 39MLP_MAX_MIP_GAP = 0,0025
40# Tolerated LP/MIP Gap [0.0 .. 1.0]
41MLP_MAX_LP_MIP_GAP = 0,025
40 42
41# MLP_COEFFICIENT_D = 1.0 43# MLP_COEFFICIENT_D = 1.0
42# MLP_COEFFICIENT_U = 1.0 44# MLP_COEFFICIENT_U = 1.0
diff --git a/src/ats/plugin_ats_mlp.c b/src/ats/plugin_ats_mlp.c
index c4c97b796..3c6523dae 100644
--- a/src/ats/plugin_ats_mlp.c
+++ b/src/ats/plugin_ats_mlp.c
@@ -985,26 +985,26 @@ mlp_solve_lp_problem (struct GAS_MLP_Handle *mlp)
985 int res_status = 0; 985 int res_status = 0;
986 res = glp_simplex(mlp->p.prob, &mlp->control_param_lp); 986 res = glp_simplex(mlp->p.prob, &mlp->control_param_lp);
987 if (0 == res) 987 if (0 == res)
988 LOG(GNUNET_ERROR_TYPE_DEBUG, "Solving LP problem: 0x%02X %s\n", res, 988 LOG(GNUNET_ERROR_TYPE_DEBUG, "Solving LP problem: %s\n",
989 mlp_solve_to_string (res)); 989 mlp_solve_to_string (res));
990 else 990 else
991 LOG(GNUNET_ERROR_TYPE_DEBUG, "Solving LP problem failed: 0x%02X %s\n", 991 LOG(GNUNET_ERROR_TYPE_DEBUG, "Solving LP problem failed: %s\n",
992 res, mlp_solve_to_string (res)); 992 mlp_solve_to_string (res));
993 993
994 /* Analyze problem status */ 994 /* Analyze problem status */
995 res_status = glp_get_status (mlp->p.prob); 995 res_status = glp_get_status (mlp->p.prob);
996 switch (res_status) { 996 switch (res_status) {
997 case GLP_OPT: /* solution is optimal */ 997 case GLP_OPT: /* solution is optimal */
998 LOG (GNUNET_ERROR_TYPE_INFO, 998 LOG (GNUNET_ERROR_TYPE_INFO,
999 "Solving LP problem: 0x%02X %s, 0x%02X %s\n", 999 "Solving LP problem: %s, %s\n",
1000 res, mlp_solve_to_string(res), 1000 mlp_solve_to_string(res),
1001 res_status, mlp_status_to_string(res_status)); 1001 mlp_status_to_string(res_status));
1002 return GNUNET_OK; 1002 return GNUNET_OK;
1003 default: 1003 default:
1004 LOG (GNUNET_ERROR_TYPE_WARNING, 1004 LOG (GNUNET_ERROR_TYPE_ERROR,
1005 "Solving LP problem failed: 0x%02X %s 0x%02X %s\n", 1005 "Solving LP problem failed: %s %s\n",
1006 res, mlp_solve_to_string(res), 1006 mlp_solve_to_string(res),
1007 res_status, mlp_status_to_string(res_status)); 1007 mlp_status_to_string(res_status));
1008 return GNUNET_SYSERR; 1008 return GNUNET_SYSERR;
1009 } 1009 }
1010} 1010}
@@ -1056,7 +1056,7 @@ mlp_propagate_results (void *cls,
1056 1056
1057 /* 1057 /*
1058 * Debug: solution 1058 * Debug: solution
1059 * LOG (GNUNET_ERROR_TYPE_INFO, "MLP result address: `%s' `%s' length %u session %u, mlp use %f\n", 1059 * LOG (GNUNET_ERROR_TYPE_INFO, "MLP result address: `%s' `%s' length %u session %u, mlp use %.3f\n",
1060 * GNUNET_i2s(&address->peer), address->plugin, 1060 * GNUNET_i2s(&address->peer), address->plugin,
1061 * address->addr_len, address->session_id); 1061 * address->addr_len, address->session_id);
1062 */ 1062 */
@@ -1145,6 +1145,7 @@ static void notify (struct GAS_MLP_Handle *mlp,
1145static void mlp_branch_and_cut_cb (glp_tree *tree, void *info) 1145static void mlp_branch_and_cut_cb (glp_tree *tree, void *info)
1146{ 1146{
1147 struct GAS_MLP_Handle *mlp = info; 1147 struct GAS_MLP_Handle *mlp = info;
1148 double mlp_obj = 0;
1148 1149
1149 switch (glp_ios_reason (tree)) 1150 switch (glp_ios_reason (tree))
1150 { 1151 {
@@ -1169,8 +1170,29 @@ static void mlp_branch_and_cut_cb (glp_tree *tree, void *info)
1169 case GLP_IBINGO: 1170 case GLP_IBINGO:
1170 /* A better solution was found */ 1171 /* A better solution was found */
1171 mlp->ps.mlp_gap = glp_ios_mip_gap (tree); 1172 mlp->ps.mlp_gap = glp_ios_mip_gap (tree);
1172 LOG (GNUNET_ERROR_TYPE_ERROR, 1173 mlp_obj = glp_mip_obj_val (mlp->p.prob);
1173 "Found better integer solution, current MIP GAP: %f\n", mlp->ps.mlp_gap); 1174 mlp->ps.lp_mlp_gap = (abs(mlp_obj - mlp->ps.lp_objective_value)) / (abs(mlp_obj) + DBL_EPSILON);
1175
1176 LOG (GNUNET_ERROR_TYPE_INFO,
1177 "Found better integer solution, current gaps: %.3f <= %.3f, %.3f <= %.3f\n",
1178 mlp->ps.mlp_gap, mlp->pv.mip_gap,
1179 mlp->ps.lp_mlp_gap, mlp->pv.lp_mip_gap);
1180
1181 if (mlp->ps.mlp_gap <= mlp->pv.mip_gap)
1182 {
1183 LOG (GNUNET_ERROR_TYPE_INFO,
1184 "Current LP/MLP gap of %.3f smaller than tolerated gap of %.3f, terminating search\n",
1185 mlp->ps.lp_mlp_gap, mlp->pv.lp_mip_gap);
1186 glp_ios_terminate (tree);
1187 }
1188
1189 if (mlp->ps.lp_mlp_gap <= mlp->pv.lp_mip_gap)
1190 {
1191 LOG (GNUNET_ERROR_TYPE_INFO,
1192 "Current LP/MLP gap of %.3f smaller than tolerated gap of %.3f, terminating search\n",
1193 mlp->ps.lp_mlp_gap, mlp->pv.lp_mip_gap);
1194 glp_ios_terminate (tree);
1195 }
1174 1196
1175 break; 1197 break;
1176 default: 1198 default:
@@ -1263,7 +1285,7 @@ GAS_mlp_solve_problem (void *solver)
1263 mlp->ps.lp_objective_value = 0.0; 1285 mlp->ps.lp_objective_value = 0.0;
1264 mlp->ps.mlp_gap = 1.0; 1286 mlp->ps.mlp_gap = 1.0;
1265 mlp->ps.mlp_objective_value = 0.0; 1287 mlp->ps.mlp_objective_value = 0.0;
1266 1288 mlp->ps.lp_mlp_gap = 0.0;
1267 1289
1268 dur_setup = GNUNET_TIME_absolute_get_duration (start_total); 1290 dur_setup = GNUNET_TIME_absolute_get_duration (start_total);
1269 1291
@@ -1281,6 +1303,13 @@ GAS_mlp_solve_problem (void *solver)
1281 /* Only for debugging, always use LP presolver: 1303 /* Only for debugging, always use LP presolver:
1282 * mlp->control_param_lp.presolve = GLP_YES; */ 1304 * mlp->control_param_lp.presolve = GLP_YES; */
1283 res_lp = mlp_solve_lp_problem(mlp); 1305 res_lp = mlp_solve_lp_problem(mlp);
1306 if (GNUNET_OK == res_lp)
1307 {
1308 mlp->ps.lp_objective_value = glp_get_obj_val (mlp->p.prob);
1309 LOG (GNUNET_ERROR_TYPE_DEBUG,
1310 "LP solution was: %.3f\n",
1311 mlp->ps.lp_objective_value);
1312 }
1284 1313
1285 dur_lp = GNUNET_TIME_absolute_get_duration (start_cur_op); 1314 dur_lp = GNUNET_TIME_absolute_get_duration (start_cur_op);
1286 notify(mlp, GAS_OP_SOLVE_MLP_LP_STOP, 1315 notify(mlp, GAS_OP_SOLVE_MLP_LP_STOP,
@@ -1311,17 +1340,17 @@ GAS_mlp_solve_problem (void *solver)
1311 { 1340 {
1312 case 0: 1341 case 0:
1313 /* Successful */ 1342 /* Successful */
1314 LOG (GNUNET_ERROR_TYPE_WARNING, 1343 LOG (GNUNET_ERROR_TYPE_INFO,
1315 "Solving MLP problem: 0x%02X %s\n", 1344 "Solving MLP problem: %s\n",
1316 mip_res, mlp_solve_to_string (mip_res)); 1345 mlp_solve_to_string (mip_res));
1317 break; 1346 break;
1318 case GLP_ETMLIM: /* Time limit reached */ 1347 case GLP_ETMLIM: /* Time limit reached */
1319 case GLP_EMIPGAP: /* MIP gap tolerance limit reached */ 1348 case GLP_EMIPGAP: /* MIP gap tolerance limit reached */
1320 case GLP_ESTOP: /* Solver was instructed to stop*/ 1349 case GLP_ESTOP: /* Solver was instructed to stop*/
1321 /* Semi-successful */ 1350 /* Semi-successful */
1322 LOG (GNUNET_ERROR_TYPE_WARNING, 1351 LOG (GNUNET_ERROR_TYPE_INFO,
1323 "Solving MLP problem solution was interupted: 0x%02X %s\n", 1352 "Solving MLP problem solution was interupted: %s\n",
1324 mip_res, mlp_solve_to_string (mip_res)); 1353 mlp_solve_to_string (mip_res));
1325 break; 1354 break;
1326 case GLP_EBOUND: 1355 case GLP_EBOUND:
1327 case GLP_EROOT: 1356 case GLP_EROOT:
@@ -1330,9 +1359,9 @@ GAS_mlp_solve_problem (void *solver)
1330 case GLP_EFAIL: 1359 case GLP_EFAIL:
1331 default: 1360 default:
1332 /* Fail */ 1361 /* Fail */
1333 LOG (GNUNET_ERROR_TYPE_ERROR, 1362 LOG (GNUNET_ERROR_TYPE_INFO,
1334 "Solving MLP problem failed: 0x%02X %s\n", 1363 "Solving MLP problem failed: %s\n",
1335 mip_res, mlp_solve_to_string (mip_res)); 1364 mlp_solve_to_string (mip_res));
1336 break; 1365 break;
1337 } 1366 }
1338 1367
@@ -1342,25 +1371,38 @@ GAS_mlp_solve_problem (void *solver)
1342 { 1371 {
1343 case GLP_OPT: /* solution is optimal */ 1372 case GLP_OPT: /* solution is optimal */
1344 LOG (GNUNET_ERROR_TYPE_WARNING, 1373 LOG (GNUNET_ERROR_TYPE_WARNING,
1345 "Solution of MLP problem is optimal: 0x%02X %s, 0x%02X %s\n", 1374 "Solution of MLP problem is optimal: %s, %s\n",
1346 mip_res, mlp_solve_to_string (mip_res), 1375 mlp_solve_to_string (mip_res),
1347 mip_status, mlp_status_to_string (mip_status)); 1376 mlp_status_to_string (mip_status));
1348 mip_res = GNUNET_OK; 1377 mip_res = GNUNET_OK;
1349 break; 1378 break;
1350 case GLP_FEAS: /* solution is feasible but not proven optimal */ 1379 case GLP_FEAS: /* solution is feasible but not proven optimal */
1351 LOG (GNUNET_ERROR_TYPE_WARNING, 1380
1352 "Solution of MLP problem is feasible: 0x%02X %s, 0x%02X %s\n", 1381 if ( (mlp->ps.mlp_gap <= mlp->pv.mip_gap) ||
1353 mip_res, mlp_solve_to_string (mip_res), 1382 (mlp->ps.lp_mlp_gap <= mlp->pv.lp_mip_gap) )
1354 mip_status, mlp_status_to_string (mip_status)); 1383 {
1355 mip_res = GNUNET_OK; 1384 LOG (GNUNET_ERROR_TYPE_WARNING,
1385 "Solution of MLP problem is feasible and solution within gap constraints: %s, %s\n",
1386 mlp_solve_to_string (mip_res),
1387 mlp_status_to_string (mip_status));
1388 mip_res = GNUNET_OK;
1389 }
1390 else
1391 {
1392 LOG (GNUNET_ERROR_TYPE_WARNING,
1393 "Solution of MLP problem is feasible but solution not within gap constraints: %s, %s\n",
1394 mlp_solve_to_string (mip_res),
1395 mlp_status_to_string (mip_status));
1396 mip_res = GNUNET_SYSERR;
1397 }
1356 break; 1398 break;
1357 case GLP_UNDEF: /* Solution undefined */ 1399 case GLP_UNDEF: /* Solution undefined */
1358 case GLP_NOFEAS: /* No feasible solution */ 1400 case GLP_NOFEAS: /* No feasible solution */
1359 default: 1401 default:
1360 LOG (GNUNET_ERROR_TYPE_ERROR, 1402 LOG (GNUNET_ERROR_TYPE_ERROR,
1361 "Solving MLP problem failed: 0x%02X %s 0x%02X %s\n", 1403 "Solving MLP problem failed: %s %s\n",
1362 mip_res, mlp_solve_to_string (mip_res), 1404 mlp_solve_to_string (mip_res),
1363 mip_status, mlp_status_to_string (mip_status)); 1405 mlp_status_to_string (mip_status));
1364 mip_res = GNUNET_SYSERR; 1406 mip_res = GNUNET_SYSERR;
1365 break; 1407 break;
1366 } 1408 }
@@ -2290,8 +2332,8 @@ libgnunet_plugin_ats_mlp_init (void *cls)
2290 } 2332 }
2291 2333
2292 mlp->pv.BIG_M = (double) BIG_M_VALUE; 2334 mlp->pv.BIG_M = (double) BIG_M_VALUE;
2293 mlp->pv.mip_gap = (double) 0.0;
2294 2335
2336 mlp->pv.mip_gap = (double) 0.0;
2295 if (GNUNET_SYSERR != GNUNET_CONFIGURATION_get_value_string (env->cfg, "ats", 2337 if (GNUNET_SYSERR != GNUNET_CONFIGURATION_get_value_string (env->cfg, "ats",
2296 "MLP_MAX_MIP_GAP", &tmp_str)) 2338 "MLP_MAX_MIP_GAP", &tmp_str))
2297 { 2339 {
@@ -2307,6 +2349,22 @@ libgnunet_plugin_ats_mlp_init (void *cls)
2307 mlp->pv.mip_gap); 2349 mlp->pv.mip_gap);
2308 } 2350 }
2309 2351
2352 mlp->pv.lp_mip_gap = (double) 0.0;
2353 if (GNUNET_SYSERR != GNUNET_CONFIGURATION_get_value_string (env->cfg, "ats",
2354 "MLP_MAX_LP_MIP_GAP", &tmp_str))
2355 {
2356 /* Dangerous due to localized separator , or . */
2357 mlp->pv.lp_mip_gap = strtod (tmp_str, NULL);
2358 if ( (mlp->pv.lp_mip_gap < 0.0) && (mlp->pv.lp_mip_gap > 1.0) )
2359 {
2360 LOG (GNUNET_ERROR_TYPE_INFO, "Invalid LP/MIP gap configuration %u \n",
2361 tmp);
2362 }
2363 else
2364 LOG (GNUNET_ERROR_TYPE_WARNING, "Using LP/MIP gap of %.3f\n",
2365 mlp->pv.lp_mip_gap);
2366 }
2367
2310 /* Get timeout for iterations */ 2368 /* Get timeout for iterations */
2311 if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_time(env->cfg, "ats", 2369 if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_time(env->cfg, "ats",
2312 "MLP_MAX_DURATION", &max_duration)) 2370 "MLP_MAX_DURATION", &max_duration))
diff --git a/src/ats/plugin_ats_mlp.h b/src/ats/plugin_ats_mlp.h
index 3b5c8f2a0..99ee74012 100644
--- a/src/ats/plugin_ats_mlp.h
+++ b/src/ats/plugin_ats_mlp.h
@@ -29,6 +29,7 @@
29#include "gnunet_ats_plugin.h" 29#include "gnunet_ats_plugin.h"
30#include "gnunet-service-ats_addresses.h" 30#include "gnunet-service-ats_addresses.h"
31#include "gnunet_statistics_service.h" 31#include "gnunet_statistics_service.h"
32#include <float.h>
32#if HAVE_LIBGLPK 33#if HAVE_LIBGLPK
33#include "glpk.h" 34#include "glpk.h"
34#endif 35#endif
@@ -74,6 +75,7 @@ struct MLP_Solution
74 double lp_objective_value; 75 double lp_objective_value;
75 double mlp_objective_value; 76 double mlp_objective_value;
76 double mlp_gap; 77 double mlp_gap;
78 double lp_mlp_gap;
77 79
78 int p_elements; 80 int p_elements;
79 int p_cols; 81 int p_cols;
@@ -163,6 +165,9 @@ struct MLP_Variables
163 /* MIP Gap */ 165 /* MIP Gap */
164 double mip_gap; 166 double mip_gap;
165 167
168 /* LP MIP Gap */
169 double lp_mip_gap;
170
166 /* ATS Quality metrics 171 /* ATS Quality metrics
167 * 172 *
168 * Array with GNUNET_ATS_QualityPropertiesCount elements 173 * Array with GNUNET_ATS_QualityPropertiesCount elements