1+ #include < cassert>
12#include < cstdio>
23
34#include " HCheckConfig.h"
45#include " Highs.h"
56#include " catch.hpp"
67#include " io/HMPSIO.h"
78
8- const bool dev_run = false ;
9+ const bool dev_run = false ; // true;//
10+
11+ const std::vector<std::string> solvers{
12+ // kHighsChooseString
13+ kSimplexString ,
14+ // kIpxString,
15+ kHipoString
16+ // kQpAsmString
17+ // kHiPdlpString
18+ };
19+
20+ void testRunData (Highs& h, const bool irreducible, const bool reduces_to_empty,
21+ const std::string& run_data_file);
922
1023TEST_CASE (" run-data-md" , " [highs_run_data]" ) {
1124 Highs h;
@@ -18,120 +31,182 @@ TEST_CASE("run-data-md", "[highs_run_data]") {
1831}
1932
2033TEST_CASE (" highs-run-data" , " [highs_run_data]" ) {
34+ // Doesn't work for MIPs yet, but wait until profiling is merged in
35+ // to avoid conflicts
36+ const std::vector<std::string> models{
37+ " adlittle" , " egout-ac"
38+ // "flugpl"
39+ };
2140 const std::string test_name = Catch::getResultCapture ().getCurrentTestName ();
22- const std::string highs_run_data_file = test_name + " .run_data" ;
41+ const std::string run_data_file = test_name + " .run_data" ;
2342
2443 Highs h;
25- if (!dev_run) h.setOptionValue (" output_flag" , false );
26- const HighsRunData& highs_run_data = h.getRunData ();
27-
28- auto testRunData = [&](const std::string& filename) {
44+ h.setOptionValue (" output_flag" , dev_run);
45+ const bool irreducible = false ;
46+ for (auto & model : models) {
47+ std::string filename =
48+ std::string (HIGHS_DIR ) + " /check/instances/" + model + " .mps" ;
49+ REQUIRE (h.readModel (filename) == HighsStatus::kOk );
2950 HighsStatus return_status = h.readModel (filename);
3051 REQUIRE (return_status == HighsStatus::kOk );
52+ const bool reduces_to_empty = model == " egout-ac" ? true : false ;
3153
32- // Cannot write run_data since not valid before run()
33- return_status = h.writeRunData (" " );
34- REQUIRE (return_status == HighsStatus::kWarning );
35-
36- HighsRunDataType highs_run_data_type;
37- return_status = h.getRunDataType (" presolved_num_col" , highs_run_data_type);
38- REQUIRE (return_status == HighsStatus::kError );
39- return_status =
40- h.getRunDataType (" presolved_model_num_col" , highs_run_data_type);
41- REQUIRE (return_status == HighsStatus::kOk );
42- REQUIRE (highs_run_data_type == HighsRunDataType::kInt );
43-
44- return_status = h.getRunDataType (" presolving_time" , highs_run_data_type);
45- REQUIRE (return_status == HighsStatus::kError );
46- return_status = h.getRunDataType (" presolve_time" , highs_run_data_type);
47- REQUIRE (return_status == HighsStatus::kOk );
48- REQUIRE (highs_run_data_type == HighsRunDataType::kDouble );
49-
50- // Run data not valid before run()
51- HighsInt presolved_model_num_col;
52- return_status =
53- h.getRunDataValue (" presolved_model_num_col" , presolved_model_num_col);
54- REQUIRE (return_status == HighsStatus::kWarning );
54+ for (auto & solver : solvers)
55+ testRunData (h, irreducible, reduces_to_empty, run_data_file);
56+ }
57+ if (!dev_run) std::remove (run_data_file.c_str ());
5558
56- return_status = h. run ( );
57- REQUIRE (return_status == HighsStatus:: kOk );
59+ h. resetGlobalScheduler ( true );
60+ }
5861
59- if (dev_run) {
60- return_status = h.writeRunData (" " );
61- REQUIRE (return_status == HighsStatus::kOk );
62+ TEST_CASE (" highs-run-data-presolve" , " [highs_run_data]" ) {
63+ const std::vector<std::string> models{" adlittle" , " flugpl" };
64+ const std::string test_name = Catch::getResultCapture ().getCurrentTestName ();
65+ const std::string run_data_file = test_name + " .run_data" ;
66+ Highs h;
67+ h.setOptionValue (" output_flag" , dev_run);
68+ const HighsRunData& run_data = h.getRunData ();
69+ const HighsLp& lp = h.getLp ();
70+ for (auto & model : models) {
71+ std::string filename =
72+ std::string (HIGHS_DIR ) + " /check/instances/" + model + " .mps" ;
73+ REQUIRE (h.readModel (filename) == HighsStatus::kOk );
74+ const bool irreducible = true ;
75+ const bool reduces_to_empty = false ;
76+ for (auto & solver : solvers) {
77+ h.setOptionValue (" solver" , solver);
78+ if (dev_run)
79+ printf (" \n !>>>>%s-%s<<<<\n " , model.c_str (), solver.c_str ());
80+
81+ REQUIRE (h.presolve () == HighsStatus::kOk );
82+ HighsLp presolved_lp = h.getPresolvedLp ();
83+
84+ h.passModel (presolved_lp);
85+ h.setOptionValue (" solve_relaxation" , true );
86+ h.setOptionValue (kPresolveString , kHighsOffString );
87+ testRunData (h, irreducible, reduces_to_empty, run_data_file);
6288 }
89+ }
6390
64- return_status = h.writeRunData (highs_run_data_file);
65- REQUIRE (return_status == HighsStatus::kOk );
66-
67- // Wrong name for objective
68- return_status =
69- h.getRunDataValue (" presolved_num_col" , presolved_model_num_col);
70- REQUIRE (return_status == HighsStatus::kError );
71-
72- // Right name for objective
73- return_status =
74- h.getRunDataValue (" presolved_model_num_col" , presolved_model_num_col);
75- REQUIRE (return_status == HighsStatus::kOk );
76-
77- if (dev_run)
78- printf (" From getRunDataValue: presolved_model_num_col = %d\n " ,
79- int (presolved_model_num_col));
80-
81- double presolve_time;
82- // Wrong name for simplex iteration count
83- return_status = h.getRunDataValue (" presolving_time" , presolve_time);
84- REQUIRE (return_status == HighsStatus::kError );
91+ h.resetGlobalScheduler (true );
92+ }
8593
86- // Right name for presolve time
87- return_status = h.getRunDataValue (" presolve_time" , presolve_time);
94+ void testRunData (Highs& h, const bool irreducible, const bool reduces_to_empty,
95+ const std::string& run_data_file) {
96+
97+ assert (!(irreducible && reduces_to_empty));
98+ const HighsRunData& run_data = h.getRunData ();
99+ const HighsLp& lp = h.getLp ();
100+
101+ std::string presolve;
102+ h.getOptionValue (kPresolveString , presolve);
103+ const bool run_presolve = presolve != kHighsOffString ;
104+
105+ // Cannot write run_data since not valid before run()
106+ HighsStatus return_status = h.writeRunData (" " );
107+ REQUIRE (return_status == HighsStatus::kWarning );
108+
109+ HighsRunDataType run_data_type;
110+ return_status = h.getRunDataType (" presolved_num_col" , run_data_type);
111+ REQUIRE (return_status == HighsStatus::kError );
112+ return_status = h.getRunDataType (" presolved_model_num_col" , run_data_type);
113+ REQUIRE (return_status == HighsStatus::kOk );
114+ REQUIRE (run_data_type == HighsRunDataType::kInt );
115+
116+ return_status = h.getRunDataType (" presolving_time" , run_data_type);
117+ REQUIRE (return_status == HighsStatus::kError );
118+ return_status = h.getRunDataType (" presolve_time" , run_data_type);
119+ REQUIRE (return_status == HighsStatus::kOk );
120+ REQUIRE (run_data_type == HighsRunDataType::kDouble );
121+
122+ // Run data not valid before run()
123+ HighsInt presolved_model_num_col;
124+ return_status =
125+ h.getRunDataValue (" presolved_model_num_col" , presolved_model_num_col);
126+ REQUIRE (return_status == HighsStatus::kWarning );
127+
128+ return_status = h.run ();
129+ REQUIRE (return_status == HighsStatus::kOk );
130+
131+ if (dev_run) {
132+ return_status = h.writeRunData (" " );
88133 REQUIRE (return_status == HighsStatus::kOk );
89-
90- const HighsModelStatus model_status = h.getModelStatus ();
91- if (dev_run) {
92- printf (" From getModelStatus: model_status = %s\n " ,
93- h.modelStatusToString (model_status).c_str ());
94- printf (" From getRunData: presolved_model_num_col = %d\n " ,
95- int (highs_run_data.presolved_model_num_col ));
96- printf (" From getRunData: presolved_model_num_row = %d\n " ,
97- int (highs_run_data.presolved_model_num_row ));
98- printf (" From getRunData: presolved_model_num_nz = %d\n " ,
99- int (highs_run_data.presolved_model_num_nz ));
100- if (!h.getLp ().isMip ())
101- printf (
102- " From getRunData: num_simplex_iterations_after_postsolve = %d\n " ,
103- int (highs_run_data.num_simplex_iterations_after_postsolve ));
104- printf (" From getRunData: presolve_time = %g\n " ,
105- highs_run_data.presolve_time );
106- printf (" From getRunData: solve_time = %g\n " ,
107- highs_run_data.solve_time );
108- printf (" From getRunData: postsolve_time = %g\n " ,
109- highs_run_data.postsolve_time );
110- }
111- REQUIRE (highs_run_data.presolved_model_num_col >= 0 );
112- REQUIRE (highs_run_data.presolved_model_num_row >= 0 );
113- REQUIRE (highs_run_data.presolved_model_num_nz >= 0 );
134+ }
135+
136+ return_status = h.writeRunData (run_data_file);
137+ REQUIRE (return_status == HighsStatus::kOk );
138+
139+ // Wrong name for objective
140+ return_status =
141+ h.getRunDataValue (" presolved_num_col" , presolved_model_num_col);
142+ REQUIRE (return_status == HighsStatus::kError );
143+
144+ // Right name for objective
145+ return_status =
146+ h.getRunDataValue (" presolved_model_num_col" , presolved_model_num_col);
147+ REQUIRE (return_status == HighsStatus::kOk );
148+
149+ if (dev_run)
150+ printf (" From getRunDataValue: presolved_model_num_col = %d\n " ,
151+ int (presolved_model_num_col));
152+
153+ double presolve_time;
154+ // Wrong name for presolve_time
155+ return_status = h.getRunDataValue (" presolving_time" , presolve_time);
156+ REQUIRE (return_status == HighsStatus::kError );
157+
158+ // Right name for presolve time
159+ return_status = h.getRunDataValue (" presolve_time" , presolve_time);
160+ REQUIRE (return_status == HighsStatus::kOk );
161+
162+ const HighsModelStatus model_status = h.getModelStatus ();
163+ if (dev_run) {
164+ printf (" From getModelStatus: model_status = %s\n " ,
165+ h.modelStatusToString (model_status).c_str ());
166+ printf (" From getRunData: presolved_model_num_col = %d\n " ,
167+ int (run_data.presolved_model_num_col ));
168+ printf (" From getRunData: presolved_model_num_row = %d\n " ,
169+ int (run_data.presolved_model_num_row ));
170+ printf (" From getRunData: presolved_model_num_nz = %d\n " ,
171+ int (run_data.presolved_model_num_nz ));
114172 if (!h.getLp ().isMip ())
115- REQUIRE (highs_run_data.num_simplex_iterations_after_postsolve == 0 );
116- REQUIRE (highs_run_data.presolve_time >= 0 );
117- REQUIRE (highs_run_data.solve_time >= 0 );
118- REQUIRE (highs_run_data.postsolve_time >= 0 );
119- };
120-
121- std::string filename;
122- filename = std::string (HIGHS_DIR ) + " /check/instances/adlittle.mps" ;
123- testRunData (filename);
124-
125- filename = std::string (HIGHS_DIR ) + " /check/instances/egout-ac.mps" ;
126- testRunData (filename);
127-
128- // Doesn't work for MIPs yet, but wait until profiling is merged in
129- // to avoid conflicts
130- //
131- // filename = std::string(HIGHS_DIR) + "/check/instances/flugpl.mps";
132- // testRunData(filename);
133-
134- if (!dev_run) std::remove (highs_run_data_file.c_str ());
135-
136- h.resetGlobalScheduler (true );
173+ printf (" From getRunData: num_simplex_iterations_after_postsolve = %d\n " ,
174+ int (run_data.num_simplex_iterations_after_postsolve ));
175+ printf (" From getRunData: presolve_time = %g\n " , run_data.presolve_time );
176+ printf (" From getRunData: solve_time = %g\n " , run_data.solve_time );
177+ printf (" From getRunData: postsolve_time = %g\n " , run_data.postsolve_time );
178+ }
179+ if (run_presolve) {
180+ REQUIRE (run_data.presolve_time >= 0 );
181+ REQUIRE (run_data.presolve_time < kHighsInf );
182+ REQUIRE (run_data.presolved_model_num_col >= 0 );
183+ REQUIRE (run_data.presolved_model_num_row >= 0 );
184+ REQUIRE (run_data.presolved_model_num_nz >= 0 );
185+ if (!irreducible) {
186+ REQUIRE (run_data.presolved_model_num_col < lp.num_col_ );
187+ REQUIRE (run_data.presolved_model_num_row < lp.num_row_ );
188+ REQUIRE (run_data.presolved_model_num_nz < lp.a_matrix_ .numNz ());
189+ }
190+ if (reduces_to_empty) {
191+ REQUIRE (run_data.presolved_model_num_col == 0 );
192+ REQUIRE (run_data.presolved_model_num_row == 0 );
193+ REQUIRE (run_data.presolved_model_num_nz == 0 );
194+ }
195+ REQUIRE (run_data.postsolve_time >= 0 );
196+ REQUIRE (run_data.postsolve_time < kHighsInf );
197+ if (!h.getLp ().isMip ()) {
198+ REQUIRE (run_data.num_simplex_iterations_after_postsolve == 0 );
199+ }
200+ } else {
201+ REQUIRE (run_data.presolve_time == kHighsIllegalDoubleMeasure );
202+ REQUIRE (run_data.presolved_model_num_col == kHighsIllegalIntMeasure );
203+ REQUIRE (run_data.presolved_model_num_row == kHighsIllegalIntMeasure );
204+ REQUIRE (run_data.presolved_model_num_nz == kHighsIllegalIntMeasure );
205+ REQUIRE (run_data.postsolve_time == kHighsIllegalDoubleMeasure );
206+ REQUIRE (run_data.num_simplex_iterations_after_postsolve ==
207+ kHighsIllegalIntMeasure );
208+ }
209+ REQUIRE (run_data.solve_time >= 0 );
210+ REQUIRE (run_data.solve_time < kHighsInf );
211+ h.clearSolver ();
137212}
0 commit comments