Skip to content

Commit 3d0254f

Browse files
committed
Still need to finish assessExcessiveBoundCost
1 parent e7b425b commit 3d0254f

File tree

1 file changed

+113
-75
lines changed

1 file changed

+113
-75
lines changed

highs/lp_data/HighsSolve.cpp

Lines changed: 113 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -387,34 +387,44 @@ void assessExcessiveBoundCost(const HighsLogOptions log_options,
387387
}
388388
}
389389
double min_col_cost =
390-
std::min(min_continuous_col_cost, min_noncontinuous_col_cost);
390+
std::min(min_continuous_col_cost, min_noncontinuous_col_cost);
391391
double max_col_cost =
392-
std::max(max_continuous_col_cost, max_noncontinuous_col_cost);
392+
std::max(max_continuous_col_cost, max_noncontinuous_col_cost);
393393
double min_col_bound =
394-
std::min(min_continuous_col_bound, min_noncontinuous_col_bound);
394+
std::min(min_continuous_col_bound, min_noncontinuous_col_bound);
395395
double max_col_bound =
396-
std::max(max_continuous_col_bound, max_noncontinuous_col_bound);
397-
if (min_col_cost == kHighsInf) min_col_cost = 0;
398-
if (max_col_cost == -kHighsInf) max_col_cost = 0;
399-
if (min_col_bound == kHighsInf) min_col_bound = 0;
400-
if (max_col_bound == -kHighsInf) max_col_bound = 0;
401-
396+
std::max(max_continuous_col_bound, max_noncontinuous_col_bound);
397+
402398
double min_matrix_value = kHighsInf;
403399
double max_matrix_value = -kHighsInf;
404400
const HighsInt num_nz = lp.a_matrix_.numNz();
405401
for (HighsInt iEl = 0; iEl < num_nz; iEl++)
406402
assessFiniteNonzero(lp.a_matrix_.value_[iEl], min_matrix_value,
407403
max_matrix_value);
408-
404+
409405
double min_row_bound = kHighsInf;
410406
double max_row_bound = -kHighsInf;
411407
for (HighsInt iRow = 0; iRow < lp.num_row_; iRow++) {
412408
assessFiniteNonzero(lp.row_lower_[iRow], min_row_bound, max_row_bound);
413409
assessFiniteNonzero(lp.row_upper_[iRow], min_row_bound, max_row_bound);
414410
}
411+
412+
// Determine the minimum and maximum overall bounds that can be
413+
// scaled with user_bound_scale before zeroing extrema due to
414+
// absence of finite nonzero bounds
415+
416+
double min_scalable_bound = std::min(min_continuous_col_bound, min_row_bound);
417+
double max_scalable_bound = std::max(max_continuous_col_bound, max_row_bound);
418+
if (min_scalable_bound == kHighsInf) min_scalable_bound = 0;
419+
if (max_scalable_bound == -kHighsInf) max_scalable_bound = 0;
420+
421+
if (min_col_cost == kHighsInf) min_col_cost = 0;
422+
if (max_col_cost == -kHighsInf) max_col_cost = 0;
423+
if (min_col_bound == kHighsInf) min_col_bound = 0;
424+
if (max_col_bound == -kHighsInf) max_col_bound = 0;
415425
if (min_row_bound == kHighsInf) min_row_bound = 0;
416426
if (max_row_bound == -kHighsInf) max_row_bound = 0;
417-
427+
418428
// Report on the coefficient ranges
419429
highsLogUser(log_options, HighsLogType::kInfo, "Coefficient ranges:\n");
420430
if (num_nz)
@@ -429,15 +439,43 @@ void assessExcessiveBoundCost(const HighsLogOptions log_options,
429439
if (lp.num_row_)
430440
highsLogUser(log_options, HighsLogType::kInfo, " RHS [%5.0e, %5.0e]\n",
431441
min_row_bound, max_row_bound);
432-
442+
443+
// Determine recommended user scaling values
444+
HighsInt recommend_user_bound_scale_setting = 0;
445+
HighsInt recommend_user_cost_scale_setting = 0;
446+
double ratio = 1;
447+
if (min_scalable_bound > kExcessivelyLargeBoundValue) {
448+
// All scalable bounds are excessively large, so obviously suggest
449+
// scaling them down
450+
ratio = kExcessivelyLargeBoundValue / min_scalable_bound;
451+
} else if (0 < max_scalable_bound && max_scalable_bound < kExcessivelySmallBoundValue) {
452+
// All scalable bounds are excessively small, so obviously suggest
453+
// scaling them up
454+
ratio = kExcessivelySmallBoundValue / min_scalable_bound;
455+
} else {
456+
if (max_scalable_bound > kExcessivelyLargeBoundValue) {
457+
// Max bound is excessively large, so look to scale it down
458+
ratio = kExcessivelyLargeBoundValue / max_scalable_bound;
459+
if (0 < min_scalable_bound && min_scalable_bound < kExcessivelySmallBoundValue) {
460+
// Min nonzero bound is excessively small: look for balance
461+
462+
} else {
463+
// Ensure that scaling down large bounds doesn't lead to min
464+
// bound being too small
465+
}
466+
} else if (0 < min_scalable_bound && min_scalable_bound < kExcessivelySmallBoundValue) {
467+
// Min bound is excessively small, so look to scale it up,
468+
// ensuring that it doesn't lead to max bounds being too large
469+
}
470+
}
433471
const double user_cost_scale_value =
434-
std::pow(2, user_scale_data.user_cost_scale);
472+
std::pow(2, user_scale_data.user_cost_scale);
435473
const double user_bound_scale_value =
436-
std::pow(2, user_scale_data.user_bound_scale);
474+
std::pow(2, user_scale_data.user_bound_scale);
437475
const std::string problem =
438-
(user_scale_data.user_cost_scale || user_scale_data.user_bound_scale)
439-
? "User-scaled problem"
440-
: "Problem";
476+
(user_scale_data.user_cost_scale || user_scale_data.user_bound_scale)
477+
? "User-scaled problem"
478+
: "Problem";
441479
// LPs with no columns or no finite nonzero costs will have
442480
// max_col_cost = 0
443481
assert(max_col_cost >= 0);
@@ -447,121 +485,121 @@ void assessExcessiveBoundCost(const HighsLogOptions log_options,
447485
// LPs with no rows or no finite nonzero bounds will have
448486
// max_row_bound = 0
449487
assert(max_row_bound >= 0);
450-
488+
451489
if (max_col_cost > kExcessivelyLargeCostValue) {
452490
// Warn that costs are excessively large, and suggest scaling
453491
double ratio =
454-
kExcessivelyLargeCostValue / (max_col_cost / user_cost_scale_value);
492+
kExcessivelyLargeCostValue / (max_col_cost / user_cost_scale_value);
455493
HighsInt suggested_user_cost_scale_setting = std::floor(std::log2(ratio));
456494
HighsInt suggested_cost_scale_exponent = std::floor(std::log10(ratio));
457495
highsLogUser(
458-
log_options, HighsLogType::kWarning,
459-
"%s has excessively large costs: consider scaling the costs "
460-
"by 1e%+1d or less, or setting option user_cost_scale to %d or less\n",
461-
problem.c_str(), int(-suggested_cost_scale_exponent),
462-
int(suggested_user_cost_scale_setting));
496+
log_options, HighsLogType::kWarning,
497+
"%s has excessively large costs: consider scaling the costs "
498+
"by 1e%+1d or less, or setting option user_cost_scale to %d or less\n",
499+
problem.c_str(), int(-suggested_cost_scale_exponent),
500+
int(suggested_user_cost_scale_setting));
463501
}
464502
if (max_col_bound > kExcessivelyLargeBoundValue) {
465503
// Warn that bounds are excessively large, and suggest scaling
466504
double ratio =
467-
kExcessivelyLargeBoundValue / (max_col_bound / user_bound_scale_value);
505+
kExcessivelyLargeBoundValue / (max_col_bound / user_bound_scale_value);
468506
HighsInt suggested_user_bound_scale = std::floor(std::log2(ratio));
469507
HighsInt suggested_bound_scale_exponent = std::floor(std::log10(ratio));
470508
if (lp.isMip()) {
471509
highsLogUser(
472-
log_options, HighsLogType::kWarning,
473-
"%s has excessively large bounds: consider scaling the bounds "
474-
"by 1e%+1d or less\n",
475-
problem.c_str(), int(-suggested_bound_scale_exponent));
510+
log_options, HighsLogType::kWarning,
511+
"%s has excessively large bounds: consider scaling the bounds "
512+
"by 1e%+1d or less\n",
513+
problem.c_str(), int(-suggested_bound_scale_exponent));
476514
} else {
477515
highsLogUser(
478-
log_options, HighsLogType::kWarning,
479-
"%s has excessively large bounds: consider scaling the bounds "
480-
"by 1e%+1d or less, "
481-
"or setting option user_bound_scale to %d or less\n",
482-
problem.c_str(), int(-suggested_bound_scale_exponent),
483-
int(suggested_user_bound_scale));
516+
log_options, HighsLogType::kWarning,
517+
"%s has excessively large bounds: consider scaling the bounds "
518+
"by 1e%+1d or less, "
519+
"or setting option user_bound_scale to %d or less\n",
520+
problem.c_str(), int(-suggested_bound_scale_exponent),
521+
int(suggested_user_bound_scale));
484522
}
485523
}
486524
if (max_row_bound > kExcessivelyLargeBoundValue) {
487525
// Warn that bounds are excessively large, and suggest scaling
488526
double ratio =
489-
kExcessivelyLargeBoundValue / (max_row_bound / user_bound_scale_value);
527+
kExcessivelyLargeBoundValue / (max_row_bound / user_bound_scale_value);
490528
HighsInt suggested_user_bound_scale = std::floor(std::log2(ratio));
491529
HighsInt suggested_bound_scale_exponent = std::floor(std::log10(ratio));
492530
if (lp.isMip()) {
493531
highsLogUser(
494-
log_options, HighsLogType::kWarning,
495-
"%s has excessively large bounds: consider scaling the bounds "
496-
"by 1e%+1d or less\n",
497-
problem.c_str(), int(-suggested_bound_scale_exponent));
532+
log_options, HighsLogType::kWarning,
533+
"%s has excessively large bounds: consider scaling the bounds "
534+
"by 1e%+1d or less\n",
535+
problem.c_str(), int(-suggested_bound_scale_exponent));
498536
} else {
499537
highsLogUser(
500-
log_options, HighsLogType::kWarning,
501-
"%s has excessively large bounds: consider scaling the bounds "
502-
"by 1e%+1d or less, "
503-
"or setting option user_bound_scale to %d or less\n",
504-
problem.c_str(), int(-suggested_bound_scale_exponent),
505-
int(suggested_user_bound_scale));
538+
log_options, HighsLogType::kWarning,
539+
"%s has excessively large bounds: consider scaling the bounds "
540+
"by 1e%+1d or less, "
541+
"or setting option user_bound_scale to %d or less\n",
542+
problem.c_str(), int(-suggested_bound_scale_exponent),
543+
int(suggested_user_bound_scale));
506544
}
507545
}
508546
// Now consider warning relating to small maximum costs and bounds
509547
if (max_col_cost > 0 && max_col_cost < kExcessivelySmallCostValue) {
510548
// Warn that costs are excessively small, and suggest scaling
511549
double ratio =
512-
kExcessivelySmallCostValue / (max_col_cost / user_cost_scale_value);
550+
kExcessivelySmallCostValue / (max_col_cost / user_cost_scale_value);
513551
HighsInt suggested_user_cost_scale_setting = std::ceil(std::log2(ratio));
514552
HighsInt suggested_cost_scale_exponent = std::ceil(std::log10(ratio));
515553
highsLogUser(
516-
log_options, HighsLogType::kWarning,
517-
"%s has excessively small costs: consider scaling the costs up "
518-
"by 1e%+1d or more, "
519-
"or setting option user_cost_scale to %d or more\n",
520-
problem.c_str(), int(suggested_cost_scale_exponent),
521-
int(suggested_user_cost_scale_setting));
554+
log_options, HighsLogType::kWarning,
555+
"%s has excessively small costs: consider scaling the costs up "
556+
"by 1e%+1d or more, "
557+
"or setting option user_cost_scale to %d or more\n",
558+
problem.c_str(), int(suggested_cost_scale_exponent),
559+
int(suggested_user_cost_scale_setting));
522560
}
523561
if (max_col_bound > 0 && max_col_bound < kExcessivelySmallBoundValue) {
524562
// Warn that bounds are excessively small, and suggest scaling
525563
double ratio =
526-
kExcessivelySmallBoundValue / (max_col_bound / user_bound_scale_value);
564+
kExcessivelySmallBoundValue / (max_col_bound / user_bound_scale_value);
527565
HighsInt suggested_user_bound_scale = std::ceil(std::log2(ratio));
528566
HighsInt suggested_bound_scale_exponent = std::ceil(std::log10(ratio));
529567
if (lp.isMip()) {
530568
highsLogUser(
531-
log_options, HighsLogType::kWarning,
532-
"%s has excessively small bounds: consider scaling the bounds "
533-
"by 1e%+1d or more\n",
534-
problem.c_str(), int(suggested_bound_scale_exponent));
569+
log_options, HighsLogType::kWarning,
570+
"%s has excessively small bounds: consider scaling the bounds "
571+
"by 1e%+1d or more\n",
572+
problem.c_str(), int(suggested_bound_scale_exponent));
535573
} else {
536574
highsLogUser(
537-
log_options, HighsLogType::kWarning,
538-
"%s has excessively small bounds: consider scaling the bounds "
539-
"by 1e%+1d or more, "
540-
"or setting option user_bound_scale to %d or more\n",
541-
problem.c_str(), int(suggested_bound_scale_exponent),
542-
int(suggested_user_bound_scale));
575+
log_options, HighsLogType::kWarning,
576+
"%s has excessively small bounds: consider scaling the bounds "
577+
"by 1e%+1d or more, "
578+
"or setting option user_bound_scale to %d or more\n",
579+
problem.c_str(), int(suggested_bound_scale_exponent),
580+
int(suggested_user_bound_scale));
543581
}
544582
}
545583
if (max_row_bound > 0 && max_row_bound < kExcessivelySmallBoundValue) {
546584
// Warn that bounds are excessively small, and suggest scaling
547585
double ratio =
548-
kExcessivelySmallBoundValue / (max_row_bound / user_bound_scale_value);
586+
kExcessivelySmallBoundValue / (max_row_bound / user_bound_scale_value);
549587
HighsInt suggested_user_bound_scale = std::ceil(std::log2(ratio));
550588
HighsInt suggested_bound_scale_exponent = std::ceil(std::log10(ratio));
551589
if (lp.isMip()) {
552590
highsLogUser(
553-
log_options, HighsLogType::kWarning,
554-
"%s has excessively small bounds: consider scaling the bounds "
555-
"by 1e%+1d or more\n",
556-
problem.c_str(), int(suggested_bound_scale_exponent));
591+
log_options, HighsLogType::kWarning,
592+
"%s has excessively small bounds: consider scaling the bounds "
593+
"by 1e%+1d or more\n",
594+
problem.c_str(), int(suggested_bound_scale_exponent));
557595
} else {
558596
highsLogUser(
559-
log_options, HighsLogType::kWarning,
560-
"%s has excessively small bounds: consider scaling the bounds "
561-
"by 1e%+1d or more, "
562-
"or setting option user_bound_scale to %d or more\n",
563-
problem.c_str(), int(suggested_bound_scale_exponent),
564-
int(suggested_user_bound_scale));
597+
log_options, HighsLogType::kWarning,
598+
"%s has excessively small bounds: consider scaling the bounds "
599+
"by 1e%+1d or more, "
600+
"or setting option user_bound_scale to %d or more\n",
601+
problem.c_str(), int(suggested_bound_scale_exponent),
602+
int(suggested_user_bound_scale));
565603
}
566604
}
567605
}

0 commit comments

Comments
 (0)