MCPcopy Create free account
hub / github.com/ERGO-Code/HiGHS / lpKktCheck

Function lpKktCheck

highs/lp_data/HighsSolution.cpp:1043–1327  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

1041}
1042
1043void lpKktCheck(HighsModelStatus& model_status, HighsInfo& info,
1044 const HighsLp& lp, const HighsSolution& solution,
1045 const HighsBasis& basis, const HighsOptions& options,
1046 const std::string& message) {
1047 if (!solution.value_valid) return;
1048 const bool has_dual_values = solution.dual_valid;
1049 const HighsLogOptions& log_options = options.log_options;
1050 double primal_feasibility_tolerance = options.primal_feasibility_tolerance;
1051 double dual_feasibility_tolerance = options.dual_feasibility_tolerance;
1052 double primal_residual_tolerance = options.primal_residual_tolerance;
1053 double dual_residual_tolerance = options.dual_residual_tolerance;
1054 double optimality_tolerance = options.optimality_tolerance;
1055 if (options.kkt_tolerance != kDefaultKktTolerance) {
1056 primal_feasibility_tolerance = options.kkt_tolerance;
1057 dual_feasibility_tolerance = options.kkt_tolerance;
1058 primal_residual_tolerance = options.kkt_tolerance;
1059 dual_residual_tolerance = options.kkt_tolerance;
1060 optimality_tolerance = options.kkt_tolerance;
1061 }
1062 info.objective_function_value = lp.objectiveValue(solution.col_value);
1063 HighsPrimalDualErrors primal_dual_errors;
1064 const bool get_residuals = !basis.valid;
1065 getLpKktFailures(options, lp, solution, basis, info, primal_dual_errors,
1066 get_residuals);
1067 if (model_status == HighsModelStatus::kOptimal)
1068 reportKktFailures(lp, options, info, message);
1069 // get_residuals is false when there is a valid basis, since
1070 // residual errors are assumed to be small, so
1071 // info.num_primal_residual_errors = -1, since they aren't
1072 // known. Hence don't consider this in identifying unboundedness
1073 // from HighsModelStatus::kUnboundedOrInfeasible
1074 if (model_status == HighsModelStatus::kUnboundedOrInfeasible &&
1075 info.num_primal_infeasibilities == 0 &&
1076 (!get_residuals || info.num_primal_residual_errors == 0))
1077 model_status = HighsModelStatus::kUnbounded;
1078 bool was_optimal = model_status == HighsModelStatus::kOptimal;
1079 bool kkt_ok = true;
1080 bool written_optimality_error_header = false;
1081
1082 auto foundOptimalityError = [&]() {
1083 kkt_ok = false;
1084 if (!was_optimal || written_optimality_error_header) return;
1085 highsLogUser(log_options, HighsLogType::kWarning,
1086 "LP solver claims optimality, but with\n");
1087 written_optimality_error_header = true;
1088 };
1089
1090 double max_primal_tolerance_relative_violation = 0;
1091 double max_dual_tolerance_relative_violation = 0;
1092 double primal_dual_objective_tolerance_relative_violation = 0;
1093 const double max_allowed_tolerance_relative_violation = 1e2;
1094 if (basis.valid) {
1095 if (info.num_primal_infeasibilities > 0) {
1096 max_primal_tolerance_relative_violation =
1097 std::max(info.max_primal_infeasibility / primal_feasibility_tolerance,
1098 max_primal_tolerance_relative_violation);
1099 foundOptimalityError();
1100 if (was_optimal)

Callers 2

lpNoBasisKktCheckFunction · 0.85
callLpKktCheckMethod · 0.85

Calls 5

getLpKktFailuresFunction · 0.85
reportKktFailuresFunction · 0.85
highsLogUserFunction · 0.85
objectiveValueMethod · 0.45

Tested by

no test coverage detected