From 1fc7e68052fc885f3e959ed332a83c067ae5d5c3 Mon Sep 17 00:00:00 2001 From: Gleb Belov Date: Tue, 18 Jun 2024 15:10:02 +1000 Subject: [PATCH] QP hierarchical objectives test #239 Fails except with Gurobi --- include/mp/backend-std.h | 2 ++ .../fast/multi_obj/dietobj_pr_3.inc | 14 ++++++++ .../fast/multi_obj/dietqobj_1000_2.mod | 35 +++++++++++++++++++ .../categorized/fast/multi_obj/modellist.json | 26 ++++++++++++++ test/end2end/scripts/python/Model.py | 1 + test/end2end/scripts/python/Solver.py | 2 +- 6 files changed, 79 insertions(+), 1 deletion(-) create mode 100644 test/end2end/cases/categorized/fast/multi_obj/dietobj_pr_3.inc create mode 100644 test/end2end/cases/categorized/fast/multi_obj/dietqobj_1000_2.mod diff --git a/include/mp/backend-std.h b/include/mp/backend-std.h index 9ca2e9b12..424b7613c 100644 --- a/include/mp/backend-std.h +++ b/include/mp/backend-std.h @@ -276,7 +276,9 @@ class StdBackend : auto get_sol = [this]() { return GetSolution(); }; + int i=0; while (GetMM().PrepareSolveIteration(get_stt, get_sol)) { + // ExportModel({"/tmp/model" + std::to_string(++i) + ".lp"}); Solve(); } } diff --git a/test/end2end/cases/categorized/fast/multi_obj/dietobj_pr_3.inc b/test/end2end/cases/categorized/fast/multi_obj/dietobj_pr_3.inc new file mode 100644 index 000000000..9e9c6ae0b --- /dev/null +++ b/test/end2end/cases/categorized/fast/multi_obj/dietobj_pr_3.inc @@ -0,0 +1,14 @@ +suffix objpriority; +suffix objweight; + + +let total_cost["A&P"].objpriority := 4; +let total_cost["JEWEL"].objpriority := 3; +let total_cost["VONS"].objpriority := 1; +let total_number.objpriority := 2; + +let total_cost["A&P"].objweight := 1; +let total_cost["JEWEL"].objweight := 2; +let total_cost["VONS"].objweight := 1.3; +let total_number.objweight := -5; + diff --git a/test/end2end/cases/categorized/fast/multi_obj/dietqobj_1000_2.mod b/test/end2end/cases/categorized/fast/multi_obj/dietqobj_1000_2.mod new file mode 100644 index 000000000..de0465c27 --- /dev/null +++ b/test/end2end/cases/categorized/fast/multi_obj/dietqobj_1000_2.mod @@ -0,0 +1,35 @@ +## Test correct objective value postsolve in MP +## See AutoLinking + +set MINREQ; # nutrients with minimum requirements +set MAXREQ; # nutrients with maximum requirements + +set NUTR := MINREQ union MAXREQ; # nutrients +set FOOD; # foods +set STORE; # stores + +param cost {STORE,FOOD} > 0; +param f_min {FOOD} >= 0; +param f_max {j in FOOD} >= f_min[j]; + +param n_min {MINREQ} >= 0; +param n_max {MAXREQ} >= 0; + +param amt {NUTR,FOOD} >= 0; + +var Buy {j in FOOD} >= f_min[j], <= f_max[j]; + +minimize total_cost {s in STORE}: + sum {j in FOOD} -cost[s,j] * Buy[j] + + sum {j in FOOD} Uniform(0.01, 0.2) * Buy[j] * Buy[j] + + 1000; + +minimize total_number: + sum {j in FOOD} Buy[j] + - sum {j in FOOD} Uniform(0.01, 0.2) * Buy[j] * Buy[j]; + +subject to diet_min {i in MINREQ}: + sum {j in FOOD} amt[i,j] * Buy[j] >= n_min[i]; + +subject to diet_max {i in MAXREQ}: + sum {j in FOOD} amt[i,j] * Buy[j] <= n_max[i]; diff --git a/test/end2end/cases/categorized/fast/multi_obj/modellist.json b/test/end2end/cases/categorized/fast/multi_obj/modellist.json index 0588a0be2..c6ea652de 100644 --- a/test/end2end/cases/categorized/fast/multi_obj/modellist.json +++ b/test/end2end/cases/categorized/fast/multi_obj/modellist.json @@ -100,6 +100,32 @@ "_sobj[4]": 44.80888220421118 } }, + { + "name" : "dietQobj_1000 multiobj=2 obj_pr_2", + "tags" : ["quadraticnonconvex", "quadratic_obj", "multiobj"], + "files" : ["dietqobj_1000.mod", "dietobj.dat", "dietobj_pr_2.inc"], + "options": { "ANYSOLVER_options": "multiobj=2" }, + "values": { + "total_cost[\"A&P\"]": 936.6309187422044, + "total_cost[\"JEWEL\"]": 959.3824742719657, + "total_cost[\"VONS\"]": 935.065924552458, + "total_number": 40, + "_sobj[4]": 40 + } + }, + { + "name" : "dietQobj_1000_2 multiobj=2 obj_pr_3", + "tags" : ["quadratic", "quadratic_obj", "multiobj"], + "files" : ["dietqobj_1000_2.mod", "dietobj.dat", "dietobj_pr_3.inc"], + "options": { "ANYSOLVER_options": "multiobj=2" }, + "values": { + "total_cost[\"A&P\"]": 915.7758062677805, + "total_cost[\"JEWEL\"]": 936.0958377754476, + "total_cost[\"VONS\"]": 924.2202858257223, + "total_number": 17.793036329321545, + "_sobj[4]": 17.793036329321545 + } + }, { "name" : "dietobj multiobj=1 obj:2:priority=10", "Comment": "Modify obj priority via an option", diff --git a/test/end2end/scripts/python/Model.py b/test/end2end/scripts/python/Model.py index 337b797ea..047985dc5 100644 --- a/test/end2end/scripts/python/Model.py +++ b/test/end2end/scripts/python/Model.py @@ -11,6 +11,7 @@ class ModelTags(enum.Enum): quadratic = 2 # obj and con quadratic_obj = 2.5 quadraticnonconvex = 3 + quadratic_obj_nonconvex = 3.5 socp = 4 socp_hard_to_recognize = 4.1 ## For solvers recognizing from quadratics expcones = 4.4 diff --git a/test/end2end/scripts/python/Solver.py b/test/end2end/scripts/python/Solver.py index dd4791001..49b7ce38b 100644 --- a/test/end2end/scripts/python/Solver.py +++ b/test/end2end/scripts/python/Solver.py @@ -941,7 +941,7 @@ def __init__(self, exeName, timeout=None, nthreads=None, ModelTags.continuous, ModelTags.integer, ModelTags.binary, ModelTags.sos, - ModelTags.quadratic, ModelTags.quadratic_obj, ModelTags.quadraticnonconvex, + ModelTags.quadratic, ModelTags.quadratic_obj, ModelTags.quadratic_obj_nonconvex, ModelTags.plinear, ModelTags.socp, ## MP transforms cones to quadratics