1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ 2 /* */ 3 /* This file is part of the HiGHS linear optimization suite */ 4 /* */ 5 /* Written and engineered 2008-2021 at the University of Edinburgh */ 6 /* */ 7 /* Available as open-source under the MIT License */ 8 /* */ 9 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ 10 /**@file lp_data/HighsOptions.h 11 * @brief 12 * @author Julian Hall, Ivet Galabova, Qi Huangfu and Michael Feldmeier 13 */ 14 #ifndef LP_DATA_HIGHS_OPTIONS_H_ 15 #define LP_DATA_HIGHS_OPTIONS_H_ 16 17 #include <cstring> // For strlen 18 #include <vector> 19 20 #include "io/HighsIO.h" 21 #include "lp_data/HConst.h" 22 #include "lp_data/HighsStatus.h" 23 #include "simplex/HFactor.h" 24 #include "simplex/SimplexConst.h" 25 26 using std::string; 27 28 enum class OptionStatus { OK = 0, NO_FILE, UNKNOWN_OPTION, ILLEGAL_VALUE }; 29 30 class OptionRecord { 31 public: 32 HighsOptionType type; 33 std::string name; 34 std::string description; 35 bool advanced; 36 OptionRecord(HighsOptionType Xtype,std::string Xname,std::string Xdescription,bool Xadvanced)37 OptionRecord(HighsOptionType Xtype, std::string Xname, 38 std::string Xdescription, bool Xadvanced) { 39 this->type = Xtype; 40 this->name = Xname; 41 this->description = Xdescription; 42 this->advanced = Xadvanced; 43 } 44 ~OptionRecord()45 virtual ~OptionRecord() {} 46 }; 47 48 class OptionRecordBool : public OptionRecord { 49 public: 50 bool* value; 51 bool default_value; OptionRecordBool(std::string Xname,std::string Xdescription,bool Xadvanced,bool * Xvalue_pointer,bool Xdefault_value)52 OptionRecordBool(std::string Xname, std::string Xdescription, bool Xadvanced, 53 bool* Xvalue_pointer, bool Xdefault_value) 54 : OptionRecord(HighsOptionType::BOOL, Xname, Xdescription, Xadvanced) { 55 advanced = Xadvanced; 56 value = Xvalue_pointer; 57 default_value = Xdefault_value; 58 *value = default_value; 59 } 60 assignvalue(bool Xvalue)61 void assignvalue(bool Xvalue) { *value = Xvalue; } 62 ~OptionRecordBool()63 virtual ~OptionRecordBool() {} 64 }; 65 66 class OptionRecordInt : public OptionRecord { 67 public: 68 int* value; 69 int lower_bound; 70 int default_value; 71 int upper_bound; OptionRecordInt(std::string Xname,std::string Xdescription,bool Xadvanced,int * Xvalue_pointer,int Xlower_bound,int Xdefault_value,int Xupper_bound)72 OptionRecordInt(std::string Xname, std::string Xdescription, bool Xadvanced, 73 int* Xvalue_pointer, int Xlower_bound, int Xdefault_value, 74 int Xupper_bound) 75 : OptionRecord(HighsOptionType::INT, Xname, Xdescription, Xadvanced) { 76 value = Xvalue_pointer; 77 lower_bound = Xlower_bound; 78 default_value = Xdefault_value; 79 upper_bound = Xupper_bound; 80 *value = default_value; 81 } 82 assignvalue(int Xvalue)83 void assignvalue(int Xvalue) { *value = Xvalue; } 84 ~OptionRecordInt()85 virtual ~OptionRecordInt() {} 86 }; 87 88 class OptionRecordDouble : public OptionRecord { 89 public: 90 double* value; 91 double lower_bound; 92 double upper_bound; 93 double default_value; OptionRecordDouble(std::string Xname,std::string Xdescription,bool Xadvanced,double * Xvalue_pointer,double Xlower_bound,double Xdefault_value,double Xupper_bound)94 OptionRecordDouble(std::string Xname, std::string Xdescription, 95 bool Xadvanced, double* Xvalue_pointer, 96 double Xlower_bound, double Xdefault_value, 97 double Xupper_bound) 98 : OptionRecord(HighsOptionType::DOUBLE, Xname, Xdescription, Xadvanced) { 99 value = Xvalue_pointer; 100 lower_bound = Xlower_bound; 101 default_value = Xdefault_value; 102 upper_bound = Xupper_bound; 103 *value = default_value; 104 } 105 assignvalue(double Xvalue)106 void assignvalue(double Xvalue) { *value = Xvalue; } 107 ~OptionRecordDouble()108 virtual ~OptionRecordDouble() {} 109 }; 110 111 class OptionRecordString : public OptionRecord { 112 public: 113 std::string* value; 114 std::string default_value; OptionRecordString(std::string Xname,std::string Xdescription,bool Xadvanced,std::string * Xvalue_pointer,std::string Xdefault_value)115 OptionRecordString(std::string Xname, std::string Xdescription, 116 bool Xadvanced, std::string* Xvalue_pointer, 117 std::string Xdefault_value) 118 : OptionRecord(HighsOptionType::STRING, Xname, Xdescription, Xadvanced) { 119 value = Xvalue_pointer; 120 default_value = Xdefault_value; 121 *value = default_value; 122 } 123 assignvalue(std::string Xvalue)124 void assignvalue(std::string Xvalue) { *value = Xvalue; } 125 ~OptionRecordString()126 virtual ~OptionRecordString() {} 127 }; 128 129 inline const char* bool2string(bool b); 130 131 bool commandLineOffChooseOnOk(FILE* logfile, const string& value); 132 bool commandLineSolverOk(FILE* logfile, const string& value); 133 134 bool boolFromString(const std::string value, bool& bool_value); 135 136 OptionStatus getOptionIndex(FILE* logfile, const std::string& name, 137 const std::vector<OptionRecord*>& option_records, 138 int& index); 139 140 OptionStatus checkOptions(FILE* logfile, 141 const std::vector<OptionRecord*>& option_records); 142 OptionStatus checkOption(FILE* logfile, const OptionRecordInt& option); 143 OptionStatus checkOption(FILE* logfile, const OptionRecordDouble& option); 144 145 OptionStatus checkOptionValue(FILE* logfile, 146 std::vector<OptionRecord*>& option_records, 147 const int value); 148 OptionStatus checkOptionValue(FILE* logfile, 149 std::vector<OptionRecord*>& option_records, 150 const double value); 151 OptionStatus checkOptionValue(FILE* logfile, 152 std::vector<OptionRecord*>& option_records, 153 const std::string value); 154 155 OptionStatus setOptionValue(FILE* logfile, const std::string& name, 156 std::vector<OptionRecord*>& option_records, 157 const bool value); 158 OptionStatus setOptionValue(FILE* logfile, const std::string& name, 159 std::vector<OptionRecord*>& option_records, 160 const int value); 161 OptionStatus setOptionValue(FILE* logfile, const std::string& name, 162 std::vector<OptionRecord*>& option_records, 163 const double value); 164 OptionStatus setOptionValue(FILE* logfile, const std::string& name, 165 std::vector<OptionRecord*>& option_records, 166 const std::string value); 167 OptionStatus setOptionValue(FILE* logfile, const std::string& name, 168 std::vector<OptionRecord*>& option_records, 169 const char* value); 170 171 OptionStatus setOptionValue(OptionRecordBool& option, const bool value); 172 OptionStatus setOptionValue(FILE* logfile, OptionRecordInt& option, 173 const int value); 174 OptionStatus setOptionValue(FILE* logfile, OptionRecordDouble& option, 175 const double value); 176 OptionStatus setOptionValue(FILE* logfile, OptionRecordString& option, 177 std::string const value); 178 179 OptionStatus passOptions(FILE* logfile, const HighsOptions& from_options, 180 HighsOptions& to_options); 181 182 OptionStatus getOptionValue(FILE* logfile, const std::string& name, 183 const std::vector<OptionRecord*>& option_records, 184 bool& value); 185 OptionStatus getOptionValue(FILE* logfile, const std::string& name, 186 const std::vector<OptionRecord*>& option_records, 187 int& value); 188 OptionStatus getOptionValue(FILE* logfile, const std::string& name, 189 const std::vector<OptionRecord*>& option_records, 190 double& value); 191 OptionStatus getOptionValue(FILE* logfile, const std::string& name, 192 const std::vector<OptionRecord*>& option_records, 193 std::string& value); 194 195 OptionStatus getOptionType(FILE* logfile, const std::string& name, 196 const std::vector<OptionRecord*>& option_records, 197 HighsOptionType& type); 198 199 void resetOptions(std::vector<OptionRecord*>& option_records); 200 201 HighsStatus writeOptionsToFile(FILE* file, 202 const std::vector<OptionRecord*>& option_records, 203 const bool report_only_non_default_values = true, 204 const bool html = false); 205 void reportOptions(FILE* file, const std::vector<OptionRecord*>& option_records, 206 const bool report_only_non_default_values = true, 207 const bool html = false); 208 void reportOption(FILE* file, const OptionRecordBool& option, 209 const bool report_only_non_default_values, const bool html); 210 void reportOption(FILE* file, const OptionRecordInt& option, 211 const bool report_only_non_default_values, const bool html); 212 void reportOption(FILE* file, const OptionRecordDouble& option, 213 const bool report_only_non_default_values, const bool html); 214 void reportOption(FILE* file, const OptionRecordString& option, 215 const bool report_only_non_default_values, const bool html); 216 217 const string simplex_string = "simplex"; 218 const string ipm_string = "ipm"; 219 const string mip_string = "mip"; 220 221 const int KEEP_N_ROWS_DELETE_ROWS = -1; 222 const int KEEP_N_ROWS_DELETE_ENTRIES = 0; 223 const int KEEP_N_ROWS_KEEP_ROWS = 1; 224 225 // Strings for command line options 226 const string model_file_string = "model_file"; 227 const string presolve_string = "presolve"; 228 const string solver_string = "solver"; 229 const string parallel_string = "parallel"; 230 const string time_limit_string = "time_limit"; 231 const string options_file_string = "options_file"; 232 233 // enum objSense { OBJSENSE_MINIMIZE = 1, OBJSENSE_MAXIMIZE = -1 }; 234 235 struct HighsOptionsStruct { 236 // Options read from the command line 237 std::string model_file; 238 std::string presolve; 239 std::string solver; 240 std::string parallel; 241 double time_limit; 242 std::string options_file; 243 244 // Options read from the file 245 double infinite_cost; 246 double infinite_bound; 247 double small_matrix_value; 248 double large_matrix_value; 249 double primal_feasibility_tolerance; 250 double dual_feasibility_tolerance; 251 double ipm_optimality_tolerance; 252 double dual_objective_value_upper_bound; 253 int highs_debug_level; 254 int simplex_strategy; 255 int simplex_scale_strategy; 256 int simplex_crash_strategy; 257 int simplex_dual_edge_weight_strategy; 258 int simplex_primal_edge_weight_strategy; 259 int simplex_iteration_limit; 260 int simplex_update_limit; 261 int ipm_iteration_limit; 262 int highs_min_threads; 263 int highs_max_threads; 264 int message_level; 265 std::string solution_file; 266 bool write_solution_to_file; 267 bool write_solution_pretty; 268 269 // Advanced options 270 bool run_crossover; 271 bool mps_parser_type_free; 272 int keep_n_rows; 273 int allowed_simplex_matrix_scale_factor; 274 int allowed_simplex_cost_scale_factor; 275 int simplex_dualise_strategy; 276 int simplex_permute_strategy; 277 int dual_simplex_cleanup_strategy; 278 int simplex_price_strategy; 279 int dual_chuzc_sort_strategy; 280 bool simplex_initial_condition_check; 281 double simplex_initial_condition_tolerance; 282 double dual_steepest_edge_weight_log_error_threshold; 283 double dual_simplex_cost_perturbation_multiplier; 284 double factor_pivot_threshold; 285 double factor_pivot_tolerance; 286 double start_crossover_tolerance; 287 bool less_infeasible_DSE_check; 288 bool less_infeasible_DSE_choose_row; 289 bool use_original_HFactor_logic; 290 291 // Options for MIP solver 292 int mip_max_nodes; 293 int mip_max_leaves; 294 int mip_report_level; 295 double mip_feasibility_tolerance; 296 double mip_epsilon; 297 double mip_heuristic_effort; 298 #ifdef HIGHS_DEBUGSOL 299 std::string mip_debug_solution_file; 300 #endif 301 // Options for HighsPrintMessage and HighsLogMessage 302 FILE* logfile = stdout; 303 FILE* output = stdout; 304 305 void (*printmsgcb)(int level, const char* msg, void* msgcb_data) = NULL; 306 void (*logmsgcb)(HighsMessageType type, const char* msg, 307 void* msgcb_data) = NULL; 308 void* msgcb_data = NULL; 309 ~HighsOptionsStructHighsOptionsStruct310 virtual ~HighsOptionsStruct() {} 311 }; 312 313 // For now, but later change so HiGHS properties are string based so that new 314 // options (for debug and testing too) can be added easily. The options below 315 // are just what has been used to parse options from argv. 316 // todo: when creating the new options don't forget underscores for class 317 // variables but no underscores for struct 318 class HighsOptions : public HighsOptionsStruct { 319 public: HighsOptions()320 HighsOptions() { initRecords(); } 321 HighsOptions(const HighsOptions & options)322 HighsOptions(const HighsOptions& options) { 323 initRecords(); 324 HighsOptionsStruct::operator=(options); 325 } 326 HighsOptions(HighsOptions && options)327 HighsOptions(HighsOptions&& options) { 328 records = std::move(options.records); 329 HighsOptionsStruct::operator=(std::move(options)); 330 } 331 332 const HighsOptions& operator=(const HighsOptions& other) { 333 if (&other != this) { 334 if ((int)records.size() == 0) initRecords(); 335 HighsOptionsStruct::operator=(other); 336 } 337 return *this; 338 } 339 340 const HighsOptions& operator=(HighsOptions&& other) { 341 if (&other != this) { 342 if ((int)records.size() == 0) initRecords(); 343 HighsOptionsStruct::operator=(other); 344 } 345 return *this; 346 } 347 ~HighsOptions()348 virtual ~HighsOptions() { 349 if (records.size() > 0) deleteRecords(); 350 } 351 352 private: initRecords()353 void initRecords() { 354 OptionRecordBool* record_bool; 355 OptionRecordInt* record_int; 356 OptionRecordDouble* record_double; 357 OptionRecordString* record_string; 358 bool advanced; 359 advanced = false; 360 // Options read from the command line 361 record_string = 362 new OptionRecordString(model_file_string, "Model file", advanced, 363 &model_file, FILENAME_DEFAULT); 364 records.push_back(record_string); 365 record_string = new OptionRecordString( 366 presolve_string, "Presolve option: \"off\", \"choose\" or \"on\"", 367 advanced, &presolve, choose_string); 368 records.push_back(record_string); 369 record_string = new OptionRecordString( 370 solver_string, "Solver option: \"simplex\", \"choose\" or \"ipm\"", 371 advanced, &solver, choose_string); 372 records.push_back(record_string); 373 record_string = new OptionRecordString( 374 parallel_string, "Parallel option: \"off\", \"choose\" or \"on\"", 375 advanced, ¶llel, choose_string); 376 records.push_back(record_string); 377 record_double = new OptionRecordDouble(time_limit_string, "Time limit", 378 advanced, &time_limit, 0, 379 HIGHS_CONST_INF, HIGHS_CONST_INF); 380 records.push_back(record_double); 381 record_string = 382 new OptionRecordString(options_file_string, "Options file", advanced, 383 &options_file, FILENAME_DEFAULT); 384 records.push_back(record_string); 385 // Options read from the file 386 record_double = new OptionRecordDouble( 387 "infinite_cost", 388 "Limit on cost coefficient: values larger than " 389 "this will be treated as infinite", 390 advanced, &infinite_cost, 1e15, 1e20, HIGHS_CONST_INF); 391 records.push_back(record_double); 392 393 record_double = new OptionRecordDouble( 394 "infinite_bound", 395 "Limit on |constraint bound|: values larger " 396 "than this will be treated as infinite", 397 advanced, &infinite_bound, 1e15, 1e20, HIGHS_CONST_INF); 398 records.push_back(record_double); 399 400 record_double = new OptionRecordDouble( 401 "small_matrix_value", 402 "Lower limit on |matrix entries|: values smaller than this will be " 403 "treated as zero", 404 advanced, &small_matrix_value, 1e-12, 1e-9, HIGHS_CONST_INF); 405 records.push_back(record_double); 406 407 record_double = new OptionRecordDouble( 408 "large_matrix_value", 409 "Upper limit on |matrix entries|: values larger " 410 "than this will be treated as infinite", 411 advanced, &large_matrix_value, 1e0, 1e15, HIGHS_CONST_INF); 412 records.push_back(record_double); 413 414 record_double = new OptionRecordDouble( 415 "primal_feasibility_tolerance", "Primal feasibility tolerance", 416 advanced, &primal_feasibility_tolerance, 1e-10, 1e-7, HIGHS_CONST_INF); 417 records.push_back(record_double); 418 419 record_double = new OptionRecordDouble( 420 "dual_feasibility_tolerance", "Dual feasibility tolerance", advanced, 421 &dual_feasibility_tolerance, 1e-10, 1e-7, HIGHS_CONST_INF); 422 records.push_back(record_double); 423 424 record_double = new OptionRecordDouble( 425 "ipm_optimality_tolerance", "IPM optimality tolerance", advanced, 426 &ipm_optimality_tolerance, 1e-12, 1e-8, HIGHS_CONST_INF); 427 records.push_back(record_double); 428 429 record_double = new OptionRecordDouble( 430 "dual_objective_value_upper_bound", 431 "Upper bound on objective value for dual simplex: algorithm terminates " 432 "if reached", 433 advanced, &dual_objective_value_upper_bound, -HIGHS_CONST_INF, 434 HIGHS_CONST_INF, HIGHS_CONST_INF); 435 records.push_back(record_double); 436 437 record_int = 438 new OptionRecordInt("highs_debug_level", "Debugging level in HiGHS", 439 advanced, &highs_debug_level, HIGHS_DEBUG_LEVEL_MIN, 440 HIGHS_DEBUG_LEVEL_MIN, HIGHS_DEBUG_LEVEL_MAX); 441 records.push_back(record_int); 442 443 record_int = 444 new OptionRecordInt("simplex_strategy", "Strategy for simplex solver", 445 advanced, &simplex_strategy, SIMPLEX_STRATEGY_MIN, 446 SIMPLEX_STRATEGY_DUAL, SIMPLEX_STRATEGY_MAX); 447 records.push_back(record_int); 448 449 record_int = new OptionRecordInt( 450 "simplex_scale_strategy", 451 "Strategy for scaling before simplex solver: off / on (0/1)", advanced, 452 &simplex_scale_strategy, SIMPLEX_SCALE_STRATEGY_MIN, 453 SIMPLEX_SCALE_STRATEGY_HIGHS_FORCED, SIMPLEX_SCALE_STRATEGY_MAX); 454 records.push_back(record_int); 455 456 record_int = new OptionRecordInt( 457 "simplex_crash_strategy", 458 "Strategy for simplex crash: off / LTSSF / Bixby (0/1/2)", advanced, 459 &simplex_crash_strategy, SIMPLEX_CRASH_STRATEGY_MIN, 460 SIMPLEX_CRASH_STRATEGY_OFF, SIMPLEX_CRASH_STRATEGY_MAX); 461 records.push_back(record_int); 462 463 record_int = 464 new OptionRecordInt("simplex_dual_edge_weight_strategy", 465 "Strategy for simplex dual edge weights: Choose / " 466 "Dantzig / Devex / Steepest " 467 "Edge (-1/0/1/2)", 468 advanced, &simplex_dual_edge_weight_strategy, 469 SIMPLEX_DUAL_EDGE_WEIGHT_STRATEGY_MIN, 470 SIMPLEX_DUAL_EDGE_WEIGHT_STRATEGY_CHOOSE, 471 SIMPLEX_DUAL_EDGE_WEIGHT_STRATEGY_MAX); 472 records.push_back(record_int); 473 474 record_int = 475 new OptionRecordInt("simplex_primal_edge_weight_strategy", 476 "Strategy for simplex primal edge weights: Choose " 477 "/ Dantzig / Devex (-1/0/1)", 478 advanced, &simplex_primal_edge_weight_strategy, 479 SIMPLEX_PRIMAL_EDGE_WEIGHT_STRATEGY_MIN, 480 SIMPLEX_PRIMAL_EDGE_WEIGHT_STRATEGY_CHOOSE, 481 SIMPLEX_PRIMAL_EDGE_WEIGHT_STRATEGY_MAX); 482 records.push_back(record_int); 483 484 record_int = new OptionRecordInt("simplex_iteration_limit", 485 "Iteration limit for simplex solver", 486 advanced, &simplex_iteration_limit, 0, 487 HIGHS_CONST_I_INF, HIGHS_CONST_I_INF); 488 records.push_back(record_int); 489 490 record_int = new OptionRecordInt( 491 "simplex_update_limit", 492 "Limit on the number of simplex UPDATE operations", advanced, 493 &simplex_update_limit, 0, 5000, HIGHS_CONST_I_INF); 494 records.push_back(record_int); 495 496 record_int = new OptionRecordInt( 497 "ipm_iteration_limit", "Iteration limit for IPM solver", advanced, 498 &ipm_iteration_limit, 0, HIGHS_CONST_I_INF, HIGHS_CONST_I_INF); 499 records.push_back(record_int); 500 501 record_int = new OptionRecordInt( 502 "highs_min_threads", "Minimum number of threads in parallel execution", 503 advanced, &highs_min_threads, 1, 1, HIGHS_THREAD_LIMIT); 504 records.push_back(record_int); 505 506 record_int = new OptionRecordInt( 507 "highs_max_threads", "Maximum number of threads in parallel execution", 508 advanced, &highs_max_threads, 1, HIGHS_THREAD_LIMIT, 509 HIGHS_THREAD_LIMIT); 510 records.push_back(record_int); 511 512 record_int = new OptionRecordInt("message_level", 513 "HiGHS message level: bit-mask 1 => " 514 "VERBOSE; 2 => DETAILED 4 => MINIMAL", 515 advanced, &message_level, ML_MIN, 516 ML_MINIMAL, ML_MAX); 517 records.push_back(record_int); 518 519 record_string = 520 new OptionRecordString("solution_file", "Solution file", advanced, 521 &solution_file, FILENAME_DEFAULT); 522 records.push_back(record_string); 523 524 record_bool = 525 new OptionRecordBool("write_solution_to_file", 526 "Write the primal and dual solution to a file", 527 advanced, &write_solution_to_file, false); 528 records.push_back(record_bool); 529 530 record_bool = new OptionRecordBool("write_solution_pretty", 531 "Write the primal and dual solution in " 532 "a pretty (human-readable) format", 533 advanced, &write_solution_pretty, false); 534 records.push_back(record_bool); 535 536 record_int = new OptionRecordInt( 537 "mip_max_nodes", "MIP solver max number of nodes", advanced, 538 &mip_max_nodes, 0, HIGHS_CONST_I_INF, HIGHS_CONST_I_INF); 539 records.push_back(record_int); 540 #ifdef HIGHS_DEBUGSOL 541 record_string = new OptionRecordString( 542 "mip_debug_solution_file", 543 "Solution file for debug solution of the MIP solver", advanced, 544 &mip_debug_solution_file, FILENAME_DEFAULT); 545 records.push_back(record_string); 546 #endif 547 548 record_int = new OptionRecordInt( 549 "mip_max_leaves", "MIP solver max number of leave nodes", advanced, 550 &mip_max_leaves, 0, HIGHS_CONST_I_INF, HIGHS_CONST_I_INF); 551 records.push_back(record_int); 552 553 record_int = 554 new OptionRecordInt("mip_report_level", "MIP solver reporting level", 555 advanced, &mip_report_level, 0, 1, 2); 556 records.push_back(record_int); 557 558 record_double = new OptionRecordDouble( 559 "mip_feasibility_tolerance", "MIP feasibility tolerance", advanced, 560 &mip_feasibility_tolerance, 1e-10, 1e-6, HIGHS_CONST_INF); 561 562 record_double = 563 new OptionRecordDouble("mip_epsilon", "MIP epsilon tolerance", advanced, 564 &mip_epsilon, 1e-15, 1e-9, HIGHS_CONST_INF); 565 566 record_double = new OptionRecordDouble( 567 "mip_heuristic_effort", "effort spent for MIP heuristics", advanced, 568 &mip_heuristic_effort, 0.0, 0.05, 1.0); 569 570 records.push_back(record_double); 571 572 // Advanced options 573 advanced = true; 574 575 record_bool = new OptionRecordBool("run_crossover", 576 "Run the crossover routine for IPX", 577 advanced, &run_crossover, true); 578 records.push_back(record_bool); 579 580 record_bool = new OptionRecordBool("mps_parser_type_free", 581 "Use the free format MPS file reader", 582 advanced, &mps_parser_type_free, true); 583 records.push_back(record_bool); 584 record_int = 585 new OptionRecordInt("keep_n_rows", 586 "For multiple N-rows in MPS files: delete rows / " 587 "delete entries / keep rows (-1/0/1)", 588 advanced, &keep_n_rows, KEEP_N_ROWS_DELETE_ROWS, 589 KEEP_N_ROWS_DELETE_ROWS, KEEP_N_ROWS_KEEP_ROWS); 590 records.push_back(record_int); 591 record_int = new OptionRecordInt( 592 "allowed_simplex_matrix_scale_factor", 593 "Largest power-of-two factor permitted when scaling the constraint " 594 "matrix for the simplex solver", 595 advanced, &allowed_simplex_matrix_scale_factor, 0, 10, 20); 596 records.push_back(record_int); 597 598 record_int = new OptionRecordInt( 599 "allowed_simplex_cost_scale_factor", 600 "Largest power-of-two factor permitted when scaling the costs for the " 601 "simplex solver", 602 advanced, &allowed_simplex_cost_scale_factor, 0, 0, 20); 603 records.push_back(record_int); 604 605 record_int = new OptionRecordInt( 606 "simplex_dualise_strategy", "Strategy for dualising before simplex", 607 advanced, &simplex_dualise_strategy, OPTION_OFF, OPTION_OFF, OPTION_ON); 608 records.push_back(record_int); 609 610 record_int = new OptionRecordInt( 611 "simplex_permute_strategy", "Strategy for permuting before simplex", 612 advanced, &simplex_permute_strategy, OPTION_OFF, OPTION_OFF, OPTION_ON); 613 records.push_back(record_int); 614 615 record_int = 616 new OptionRecordInt("dual_simplex_cleanup_strategy", 617 "Strategy for cleanup in dual simplex solver: none " 618 "/ HPrimal / HQPrimal (0/1/2)", 619 advanced, &dual_simplex_cleanup_strategy, 620 DUAL_SIMPLEX_CLEANUP_STRATEGY_MIN, 621 DUAL_SIMPLEX_CLEANUP_STRATEGY_HPRIMAL, 622 DUAL_SIMPLEX_CLEANUP_STRATEGY_MAX); 623 records.push_back(record_int); 624 625 record_int = new OptionRecordInt( 626 "simplex_price_strategy", "Strategy for PRICE in simplex", advanced, 627 &simplex_price_strategy, SIMPLEX_PRICE_STRATEGY_MIN, 628 SIMPLEX_PRICE_STRATEGY_ROW_SWITCH_COL_SWITCH, 629 SIMPLEX_PRICE_STRATEGY_MAX); 630 records.push_back(record_int); 631 632 record_int = new OptionRecordInt( 633 "dual_chuzc_sort_strategy", "Strategy for CHUZC sort in dual simplex", 634 advanced, &dual_chuzc_sort_strategy, SIMPLEX_DUAL_CHUZC_STRATEGY_MIN, 635 SIMPLEX_DUAL_CHUZC_STRATEGY_CHOOSE, SIMPLEX_DUAL_CHUZC_STRATEGY_MAX); 636 records.push_back(record_int); 637 638 record_bool = 639 new OptionRecordBool("simplex_initial_condition_check", 640 "Perform initial basis condition check in simplex", 641 advanced, &simplex_initial_condition_check, true); 642 records.push_back(record_bool); 643 644 record_double = new OptionRecordDouble( 645 "simplex_initial_condition_tolerance", 646 "Tolerance on initial basis condition in simplex", advanced, 647 &simplex_initial_condition_tolerance, 1.0, 1e14, HIGHS_CONST_INF); 648 records.push_back(record_double); 649 650 record_double = new OptionRecordDouble( 651 "dual_steepest_edge_weight_log_error_threshold", 652 "Threshold on dual steepest edge weight errors for Devex switch", 653 advanced, &dual_steepest_edge_weight_log_error_threshold, 1.0, 1e1, 654 HIGHS_CONST_INF); 655 records.push_back(record_double); 656 657 record_double = new OptionRecordDouble( 658 "dual_simplex_cost_perturbation_multiplier", 659 "Dual simplex cost perturbation multiplier: 0 => no perturbation", 660 advanced, &dual_simplex_cost_perturbation_multiplier, 0.0, 1.0, 661 HIGHS_CONST_INF); 662 records.push_back(record_double); 663 664 record_double = new OptionRecordDouble( 665 "factor_pivot_threshold", "Matrix factorization pivot threshold", 666 advanced, &factor_pivot_threshold, min_pivot_threshold, 667 default_pivot_threshold, max_pivot_threshold); 668 records.push_back(record_double); 669 670 record_double = new OptionRecordDouble( 671 "factor_pivot_tolerance", "Matrix factorization pivot tolerance", 672 advanced, &factor_pivot_tolerance, min_pivot_tolerance, 673 default_pivot_tolerance, max_pivot_tolerance); 674 records.push_back(record_double); 675 676 record_double = new OptionRecordDouble( 677 "start_crossover_tolerance", 678 "Tolerance to be satisfied before IPM crossover will start", advanced, 679 &start_crossover_tolerance, 1e-12, 1e-8, HIGHS_CONST_INF); 680 records.push_back(record_double); 681 682 record_bool = new OptionRecordBool( 683 "use_original_HFactor_logic", 684 "Use original HFactor logic for sparse vs hyper-sparse TRANs", advanced, 685 &use_original_HFactor_logic, true); 686 records.push_back(record_bool); 687 688 record_bool = new OptionRecordBool( 689 "less_infeasible_DSE_check", "Check whether LP is candidate for LiDSE", 690 advanced, &less_infeasible_DSE_check, true); 691 records.push_back(record_bool); 692 693 record_bool = 694 new OptionRecordBool("less_infeasible_DSE_choose_row", 695 "Use LiDSE if LP has right properties", advanced, 696 &less_infeasible_DSE_choose_row, true); 697 records.push_back(record_bool); 698 } 699 deleteRecords()700 void deleteRecords() { 701 for (unsigned int i = 0; i < records.size(); i++) delete records[i]; 702 } 703 704 public: 705 std::vector<OptionRecord*> records; 706 }; 707 708 #endif 709