diff options
author | Matthias Wachs <wachs@net.in.tum.de> | 2014-05-13 22:50:28 +0000 |
---|---|---|
committer | Matthias Wachs <wachs@net.in.tum.de> | 2014-05-13 22:50:28 +0000 |
commit | 745109bb6a59a312e118c3242ce4ed861566fe79 (patch) | |
tree | 9e900dd999a59f03f6b7197308afbf4fc5fa652f /src/ats | |
parent | c2335d65e672477399b9bf208de9914e1e4f341b (diff) | |
download | gnunet-745109bb6a59a312e118c3242ce4ed861566fe79.tar.gz gnunet-745109bb6a59a312e118c3242ce4ed861566fe79.zip |
implemented mip gap
Diffstat (limited to 'src/ats')
-rw-r--r-- | src/ats/ats.conf.in | 1 | ||||
-rw-r--r-- | src/ats/perf_ats_solver.conf | 4 | ||||
-rw-r--r-- | src/ats/plugin_ats_mlp.c | 128 | ||||
-rw-r--r-- | src/ats/plugin_ats_mlp.h | 5 |
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] |
39 | MLP_MAX_MIP_GAP = 0,025 | 39 | MLP_MAX_MIP_GAP = 0,0025 |
40 | # Tolerated LP/MIP Gap [0.0 .. 1.0] | ||
41 | MLP_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, | |||
1145 | static void mlp_branch_and_cut_cb (glp_tree *tree, void *info) | 1145 | static 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 |