44#include " Highs.h"
55#include " catch.hpp"
66
7- const bool dev_run = false ;
7+ const bool dev_run = true ; // false;
88const double inf = kHighsInf ;
99
1010void checkModelScaling (const HighsInt user_bound_scale,
@@ -16,51 +16,43 @@ void checkLpScaling(const HighsInt user_bound_scale,
1616 const HighsInt user_cost_scale, const HighsLp& unscaled_lp,
1717 const HighsLp& scaled_lp);
1818
19- void checkSolutionScaling (const HighsInt user_bound_scale,
20- const HighsInt user_cost_scale,
21- const HighsSolution& unscaled_solution,
22- const HighsSolution& scaled_solution);
23-
2419TEST_CASE (" user-cost-scale-after-run" , " [highs_user_scale]" ) {
2520 std::string filename =
2621 std::string (HIGHS_DIR) + " /check/instances/adlittle.mps" ;
2722 Highs highs;
2823 const HighsInfo& info = highs.getInfo ();
2924 highs.setOptionValue (" output_flag" , dev_run);
30- highs.readModel (filename);
31- highs.run ();
32- HighsInfo unscaled_info = info;
33- HighsSolution unscaled_solution = highs.getSolution ();
34- HighsLp unscaled_lp = highs.getLp ();
35- double max_primal_infeasibility = info.max_primal_infeasibility ;
36- double max_dual_infeasibility = info.max_dual_infeasibility ;
37- double sum_dual_infeasibilities = info.sum_dual_infeasibilities ;
38- double objective_function_value = info.objective_function_value ;
39-
40- HighsInt user_bound_scale = 10 ;
41- double user_bound_scale_value = std::pow (2 , user_bound_scale);
42- highs.setOptionValue (" user_bound_scale" , user_bound_scale);
43-
44- HighsInt user_cost_scale = 30 ;
45- double user_cost_scale_value = std::pow (2 , user_cost_scale);
46- highs.setOptionValue (" user_cost_scale" , user_cost_scale);
47-
48- HighsLp scaled_lp = highs.getLp ();
49- HighsSolution scaled_solution = highs.getSolution ();
50- checkLpScaling (user_bound_scale, user_cost_scale, unscaled_lp, scaled_lp);
51- checkSolutionScaling (user_bound_scale, user_cost_scale, unscaled_solution,
52- scaled_solution);
53-
54- REQUIRE (highs.getModelStatus () == HighsModelStatus::kNotset );
55- REQUIRE (info.dual_solution_status == kSolutionStatusNone );
56- REQUIRE (info.objective_function_value == user_cost_scale_value *
57- user_bound_scale_value *
58- objective_function_value);
59- REQUIRE (info.num_dual_infeasibilities == kHighsIllegalInfeasibilityCount );
60- REQUIRE (info.max_dual_infeasibility ==
61- user_cost_scale_value * max_dual_infeasibility);
62- REQUIRE (info.sum_dual_infeasibilities ==
63- user_cost_scale_value * sum_dual_infeasibilities);
25+ for (HighsInt k = 0 ; k < 2 ; k++) {
26+ highs.readModel (filename);
27+ highs.run ();
28+ HighsInfo unscaled_info = info;
29+ HighsSolution unscaled_solution = highs.getSolution ();
30+ HighsLp unscaled_lp = highs.getLp ();
31+
32+ HighsInt user_bound_scale = 10 ;
33+ REQUIRE (highs.setOptionValue (" user_bound_scale" , user_bound_scale) == HighsStatus::kOk );
34+
35+ HighsInt user_cost_scale = 30 ;
36+ REQUIRE (highs.setOptionValue (" user_cost_scale" , user_cost_scale) == HighsStatus::kOk );
37+
38+ HighsLp scaled_lp = highs.getLp ();
39+ checkLpScaling (user_bound_scale, user_cost_scale, unscaled_lp, scaled_lp);
40+
41+ REQUIRE (highs.getModelStatus () == HighsModelStatus::kNotset );
42+ REQUIRE (info.primal_solution_status == kSolutionStatusNone );
43+ REQUIRE (info.dual_solution_status == kSolutionStatusNone );
44+ REQUIRE (info.num_primal_infeasibilities == kHighsIllegalInfeasibilityCount );
45+ REQUIRE (info.max_primal_infeasibility == kHighsIllegalInfeasibilityMeasure );
46+ REQUIRE (info.sum_primal_infeasibilities == kHighsIllegalInfeasibilityMeasure );
47+ REQUIRE (info.num_dual_infeasibilities == kHighsIllegalInfeasibilityCount );
48+ REQUIRE (info.max_dual_infeasibility == kHighsIllegalInfeasibilityMeasure );
49+ REQUIRE (info.sum_dual_infeasibilities == kHighsIllegalInfeasibilityMeasure );
50+
51+ filename =
52+ std::string (HIGHS_DIR) + " /check/instances/flugpl.mps" ;
53+ REQUIRE (highs.setOptionValue (" user_bound_scale" , 0 ) == HighsStatus::kOk );
54+ REQUIRE (highs.setOptionValue (" user_cost_scale" , 0 ) == HighsStatus::kOk );
55+ }
6456
6557 highs.resetGlobalScheduler (true );
6658}
@@ -72,24 +64,28 @@ TEST_CASE("user-cost-scale-after-load", "[highs_user_scale]") {
7264 const HighsInfo& info = highs.getInfo ();
7365 highs.setOptionValue (" output_flag" , dev_run);
7466
75- highs.readModel (filename);
76- HighsLp unscaled_lp = highs.getLp ();
67+ for (HighsInt k = 0 ; k < 2 ; k++) {
68+ highs.readModel (filename);
69+ HighsLp unscaled_lp = highs.getLp ();
7770
78- HighsInt user_bound_scale = 10 ;
79- double user_bound_scale_value = std::pow (2 , user_bound_scale);
80- highs.setOptionValue (" user_bound_scale" , user_bound_scale);
71+ HighsInt user_bound_scale = 10 ;
72+ double user_bound_scale_value = std::pow (2 , user_bound_scale);
73+ REQUIRE ( highs.setOptionValue (" user_bound_scale" , user_bound_scale) == HighsStatus:: kOk );
8174
82- HighsInt user_cost_scale = 30 ;
83- double user_cost_scale_value = std::pow (2 , user_cost_scale);
84- highs.setOptionValue (" user_cost_scale" , user_cost_scale);
75+ HighsInt user_cost_scale = 30 ;
76+ double user_cost_scale_value = std::pow (2 , user_cost_scale);
77+ REQUIRE ( highs.setOptionValue (" user_cost_scale" , user_cost_scale) == HighsStatus:: kOk );
8578
86- highs.readModel (filename);
87- HighsLp scaled_lp = highs.getLp ();
79+ REQUIRE ( highs.readModel (filename) == HighsStatus:: kOk );
80+ HighsLp scaled_lp = highs.getLp ();
8881
89- checkLpScaling (user_bound_scale, user_cost_scale, unscaled_lp, scaled_lp);
90- // checkSolutionScaling(user_bound_scale, user_cost_scale, unscaled_solution,
91- // scaled_solution);
92- highs.run ();
82+ checkLpScaling (user_bound_scale, user_cost_scale, unscaled_lp, scaled_lp);
83+
84+ filename =
85+ std::string (HIGHS_DIR) + " /check/instances/flugpl.mps" ;
86+ REQUIRE (highs.setOptionValue (" user_bound_scale" , 0 ) == HighsStatus::kOk );
87+ REQUIRE (highs.setOptionValue (" user_cost_scale" , 0 ) == HighsStatus::kOk );
88+ }
9389
9490 highs.resetGlobalScheduler (true );
9591}
@@ -117,14 +113,14 @@ TEST_CASE("user-small-cost-scale", "[highs_user_scale]") {
117113 REQUIRE (solution.col_value [0 ] == 40 );
118114 REQUIRE (solution.col_value [1 ] == 20 );
119115
120- highs.setOptionValue (" user_cost_scale" , -30 );
116+ REQUIRE ( highs.setOptionValue (" user_cost_scale" , -30 ) == HighsStatus:: kOk );
121117 highs.clearSolver ();
122118 highs.run ();
123119 if (dev_run) highs.writeSolution (" " , 1 );
124120 REQUIRE (solution.col_value [0 ] == 0 );
125121 REQUIRE (solution.col_value [1 ] == 0 );
126122
127- highs.setOptionValue (" user_cost_scale" , 0 );
123+ REQUIRE ( highs.setOptionValue (" user_cost_scale" , 0 ) == HighsStatus:: kOk );
128124
129125 highs.run ();
130126 REQUIRE (solution.col_value [0 ] == 40 );
@@ -214,15 +210,31 @@ void checkLpScaling(const HighsInt user_bound_scale,
214210 const double user_cost_scale_value = std::pow (2 , user_cost_scale);
215211 REQUIRE (unscaled_lp.num_col_ == scaled_lp.num_col_ );
216212 REQUIRE (unscaled_lp.num_row_ == scaled_lp.num_row_ );
213+ REQUIRE (scaled_lp.user_cost_scale_ == user_cost_scale);
214+ REQUIRE (scaled_lp.user_bound_scale_ == user_bound_scale);
215+ const bool has_integrality = scaled_lp.integrality_ .size () > 0 ;
216+ const HighsSparseMatrix& unscaled_matrix = unscaled_lp.a_matrix_ ;
217+ REQUIRE (unscaled_matrix.isColwise ());
217218 for (HighsInt iCol = 0 ; iCol < unscaled_lp.num_col_ ; iCol++) {
218- REQUIRE (scaled_lp.col_cost_ [iCol] ==
219- unscaled_lp.col_cost_ [iCol] * user_cost_scale_value);
220- if (unscaled_lp.col_lower_ [iCol] > -inf)
221- REQUIRE (scaled_lp.col_lower_ [iCol] ==
222- unscaled_lp.col_lower_ [iCol] * user_bound_scale_value);
223- if (unscaled_lp.col_upper_ [iCol] < inf)
224- REQUIRE (scaled_lp.col_upper_ [iCol] ==
225- unscaled_lp.col_upper_ [iCol] * user_bound_scale_value);
219+ bool continuous = !has_integrality || scaled_lp.integrality_ [iCol] == HighsVarType::kContinuous ;
220+ double value = unscaled_lp.col_cost_ [iCol] * user_cost_scale_value;
221+ if (!continuous) value *= user_bound_scale_value;
222+ REQUIRE (scaled_lp.col_cost_ [iCol] == value);
223+ if (unscaled_lp.col_lower_ [iCol] > -inf) {
224+ value = unscaled_lp.col_lower_ [iCol];
225+ if (continuous) value *= user_bound_scale_value;
226+ REQUIRE (scaled_lp.col_lower_ [iCol] == value);
227+ }
228+ if (unscaled_lp.col_upper_ [iCol] < inf) {
229+ value = unscaled_lp.col_upper_ [iCol];
230+ if (continuous) value *= user_bound_scale_value;
231+ REQUIRE (scaled_lp.col_upper_ [iCol] == value);
232+ }
233+ for (HighsInt iEl = unscaled_matrix.start_ [iCol]; iEl < unscaled_matrix.start_ [iCol+1 ]; iEl++) {
234+ value = unscaled_matrix.value_ [iEl];
235+ if (!continuous) value *= user_bound_scale_value;
236+ REQUIRE (scaled_lp.a_matrix_ .value_ [iEl] == value);
237+ }
226238 }
227239 for (HighsInt iRow = 0 ; iRow < unscaled_lp.num_row_ ; iRow++) {
228240 if (unscaled_lp.row_lower_ [iRow] > -inf)
@@ -234,24 +246,3 @@ void checkLpScaling(const HighsInt user_bound_scale,
234246 }
235247}
236248
237- void checkSolutionScaling (const HighsInt user_bound_scale,
238- const HighsInt user_cost_scale,
239- const HighsSolution& unscaled_solution,
240- const HighsSolution& scaled_solution) {
241- const double user_bound_scale_value = std::pow (2 , user_bound_scale);
242- const double user_cost_scale_value = std::pow (2 , user_cost_scale);
243- for (HighsInt iCol = 0 ; iCol < HighsInt (unscaled_solution.col_value .size ());
244- iCol++) {
245- REQUIRE (scaled_solution.col_value [iCol] ==
246- unscaled_solution.col_value [iCol] * user_bound_scale_value);
247- REQUIRE (scaled_solution.col_dual [iCol] ==
248- unscaled_solution.col_dual [iCol] * user_cost_scale_value);
249- }
250- for (HighsInt iRow = 0 ; iRow < HighsInt (unscaled_solution.row_value .size ());
251- iRow++) {
252- REQUIRE (scaled_solution.row_value [iRow] ==
253- unscaled_solution.row_value [iRow] * user_bound_scale_value);
254- REQUIRE (scaled_solution.row_dual [iRow] ==
255- unscaled_solution.row_dual [iRow] * user_cost_scale_value);
256- }
257- }
0 commit comments