@@ -484,16 +484,18 @@ void simplexScaleLp(const HighsOptions& options, HighsLp& lp,
484484 max_cost = std::max (abs_cost, max_cost);
485485 }
486486 }
487- printf (" grepSimplexRangeTxt HighsScale: costs in [%g, %g]; matrix in [%g, %g]; %s: %s\n " ,
488- min_cost, max_cost,
489- original_matrix_min_value, original_matrix_max_value,
490- lp.model_name_ .c_str (),
491- lp.origin_name_ .c_str ());
492- printf (" grepSimplexRangeCsv,%g,%g,%g,%g,%s,%s\n " ,
493- min_cost, max_cost,
494- original_matrix_min_value, original_matrix_max_value,
495- lp.model_name_ .c_str (),
496- lp.origin_name_ .c_str ());
487+ if (kSimplexScaleDevReport ) {
488+ printf (" grepSimplexRangeTxt HighsScale: costs in [%g, %g]; matrix in [%g, %g]; %s: %s\n " ,
489+ min_cost, max_cost,
490+ original_matrix_min_value, original_matrix_max_value,
491+ lp.model_name_ .c_str (),
492+ lp.origin_name_ .c_str ());
493+ printf (" grepSimplexRangeCsv,%g,%g,%g,%g,%s,%s\n " ,
494+ min_cost, max_cost,
495+ original_matrix_min_value, original_matrix_max_value,
496+ lp.model_name_ .c_str (),
497+ lp.origin_name_ .c_str ());
498+ }
497499 }
498500 // Possibly force scaling, otherwise base the decision on the range
499501 // of values in the matrix, values that will be used later for
@@ -504,21 +506,20 @@ void simplexScaleLp(const HighsOptions& options, HighsLp& lp,
504506 no_scaling_original_matrix_min_value) &&
505507 (original_matrix_max_value <=
506508 no_scaling_original_matrix_max_value);
509+ HighsScale& scale = lp.scale_ ;
507510 bool scaled_matrix = false ;
508511 if (no_scaling) {
509- // No matrix scaling, but possible cost scaling
510- if (options.highs_analysis_level )
511- highsLogDev (options.log_options , HighsLogType::kInfo ,
512- " Scaling: Matrix has [min, max] values of [%g, %g] within "
513- " [%g, %g] so no scaling performed\n " ,
514- original_matrix_min_value, original_matrix_max_value,
515- no_scaling_original_matrix_min_value,
516- no_scaling_original_matrix_max_value);
512+ // No matrix scaling
513+ highsLogDev (options.log_options , HighsLogType::kInfo ,
514+ " Scaling: Matrix has [min, max] values of [%g, %g] within "
515+ " [%g, %g] so no scaling performed\n " ,
516+ original_matrix_min_value, original_matrix_max_value,
517+ no_scaling_original_matrix_min_value,
518+ no_scaling_original_matrix_max_value);
517519 } else {
518520 // Try scaling, so assign unit factors - partly because initial
519521 // factors may be assumed by the scaling method, but also because
520522 // scaling factors may not be computed for empty rows/columns
521- HighsScale& scale = lp.scale_ ;
522523 scale.col .assign (numCol, 1 );
523524 scale.row .assign (numRow, 1 );
524525 const bool equilibration_scaling =
@@ -549,17 +550,18 @@ void simplexScaleLp(const HighsOptions& options, HighsLp& lp,
549550 scale.cost = 1.0 ;
550551 lp.is_scaled_ = true ;
551552 }
552- bool scaled_costs = false ;
553- if (kSimplexScaleDev &&
554- use_scale_strategy == kSimplexScaleStrategyMaxValue0157 ) {
555- // Consider cost scaling
556- simplexScaleCost (options, lp);
557- scaled_costs = scale.cost != 1.0 ;
558- lp.is_scaled_ = true ;
559- }
560- // If neither costs nor matrix are scaled, then clear the scaling
561- if (!scaled_costs && !scaled_matrix) lp.clearScaling ();
562553 }
554+ bool scaled_costs = false ;
555+ if (kSimplexScaleDev &&
556+ use_scale_strategy == kSimplexScaleStrategyMaxValueMatrixAndCost ) {
557+ // Consider cost scaling
558+ simplexScaleCost (options, lp);
559+ scaled_costs = scale.cost != 1.0 ;
560+ scale.has_scaling = true ;
561+ lp.is_scaled_ = true ;
562+ }
563+ // If neither costs nor matrix are scaled, then clear the scaling
564+ if (!scaled_costs && !scaled_matrix) lp.clearScaling ();
563565 // Record the scaling strategy used
564566 lp.scale_ .strategy = use_scale_strategy;
565567}
@@ -898,26 +900,7 @@ bool maxValueScaleMatrix(const HighsOptions& options, HighsLp& lp,
898900 vector<HighsInt>& Aindex = lp.a_matrix_ .index_ ;
899901 vector<double >& Avalue = lp.a_matrix_ .value_ ;
900902
901- assert (options.simplex_scale_strategy == kSimplexScaleStrategyMaxValue );
902- assert (kSimplexScaleStrategyMaxValue015 == kSimplexScaleStrategyMaxValue );
903- assert (kSimplexScaleStrategyMaxValue0157 == kSimplexScaleStrategyMaxValue );
904-
905- // The 015(7) values refer to bit settings in FICO's scaling options.
906- // Specifically
907- //
908- // 0: Row scaling
909- //
910- // 1: Column scaling
911- //
912- // 5: Scale by maximum element
913- //
914- // 7: Scale objective function for the simplex method
915- //
916- // Note that 7 is not yet implemented, so
917- // kSimplexScaleStrategyMaxValue015 and
918- // kSimplexScaleStrategyMaxValue0157 are equivalent. However, cost
919- // scaling could be well worth adding, now that the unscaled problem
920- // can be solved using scaled NLA
903+ assert (options.simplex_scale_strategy >= kSimplexScaleStrategyMaxValue );
921904
922905 const double log2 = log (2.0 );
923906 const double max_allow_scale = pow (2.0 , options.allowed_matrix_scale_factor );
@@ -1093,40 +1076,38 @@ void simplexScaleCost(const HighsOptions& options, HighsLp& lp) {
10931076 // Scale the costs by no less than minAlwCostScale
10941077 double max_allowed_cost_scale = pow (2.0 , options.allowed_cost_scale_factor );
10951078 double max_nonzero_cost = 0 ;
1096- for (HighsInt iCol = 0 ; iCol < lp.num_col_ ; iCol++) {
1097- if (lp.col_cost_ [iCol]) {
1079+ for (HighsInt iCol = 0 ; iCol < lp.num_col_ ; iCol++)
1080+ if (lp.col_cost_ [iCol])
10981081 max_nonzero_cost = max (fabs (lp.col_cost_ [iCol]), max_nonzero_cost);
1099- }
1100- }
1101- // Scaling the costs up effectively increases the dual tolerance to
1102- // which the problem is solved - so, if the max cost is small the
1103- // scaling factor pushes it up by a power of 2 so it's close to 1
1104- // Scaling the costs down effectively decreases the dual tolerance
1105- // to which the problem is solved - so this can't be done too much
1106- cost_scale = 1 ;
1107- const double ln2 = log ( 2.0 );
1108- // Scale if the max cost is positive and outside the range [1/16, 16]
1109- if ((max_nonzero_cost > 0 ) &&
1110- (( max_nonzero_cost < ( 1.0 / 16 )) || (max_nonzero_cost > 16 )) ) {
1082+ // Scaling the costs up effectively means that the problem is solved
1083+ // to a smaller dual tolerance, which seems pointless. HiGHS will
1084+ // warn about excessively small costs, and users can set
1085+ // user_objective_scale to a positive value.
1086+ //
1087+ // Scaling the costs down effectively means that the problem is
1088+ // solved to a larger dual tolerance, which may require clean-up
1089+ // iterations when the scaling is removed after solving the scaled
1090+ // problem
1091+ cost_scale = 1.0 ;
1092+ // Scale if the max cost is greater than 16
1093+ if ( max_nonzero_cost > 16 ) {
11111094 cost_scale = max_nonzero_cost;
1112- cost_scale = pow (2.0 , floor (log (cost_scale) / ln2 + 0.5 ));
1095+ cost_scale = pow (2.0 , floor (log (cost_scale) / log ( 2.0 ) + 0.5 ));
11131096 cost_scale = min (cost_scale, max_allowed_cost_scale);
11141097 }
1115- if (cost_scale == 1 ) {
1116- highsLogUser (options.log_options , HighsLogType::kInfo ,
1117- " LP cost vector not scaled down: max cost is %g\n " ,
1118- max_nonzero_cost);
1119- return ;
1120- }
1121- // Scale the costs (and record of max_nonzero_cost) by cost_scale, being at
1122- // most max_allowed_cost_scale
1123- for (HighsInt iCol = 0 ; iCol < lp.num_col_ ; iCol++) {
1124- lp.col_cost_ [iCol] /= cost_scale;
1098+ if (cost_scale == 1.0 ) {
1099+ highsLogDev (options.log_options , HighsLogType::kInfo ,
1100+ " LP cost vector not scaled down: max cost is %g\n " ,
1101+ max_nonzero_cost);
1102+ } else {
1103+ // Scale the costs (and record of max_nonzero_cost) by cost_scale, being at
1104+ // most max_allowed_cost_scale
1105+ for (HighsInt iCol = 0 ; iCol < lp.num_col_ ; iCol++)
1106+ lp.col_cost_ [iCol] /= cost_scale;
1107+ highsLogDev (options.log_options , HighsLogType::kInfo ,
1108+ " LP cost vector scaled down by %g: max scaled cost is %g\n " , cost_scale,
1109+ max_nonzero_cost/cost_scale);
11251110 }
1126- max_nonzero_cost /= cost_scale;
1127- highsLogUser (options.log_options , HighsLogType::kInfo ,
1128- " LP cost vector scaled down by %g: max cost is %g\n " , cost_scale,
1129- max_nonzero_cost);
11301111}
11311112
11321113void simplexUnscaleCost (HighsLp& lp) {
0 commit comments