@@ -2195,6 +2195,57 @@ dual::status_t dual_phase2(i_t phase,
2195
2195
std::vector<i_t > nonbasic_list;
2196
2196
std::vector<i_t > superbasic_list;
2197
2197
2198
+ phase2::bound_info (lp, settings);
2199
+ get_basis_from_vstatus (m, vstatus, basic_list, nonbasic_list, superbasic_list);
2200
+ assert (superbasic_list.size () == 0 );
2201
+ assert (nonbasic_list.size () == n - m);
2202
+
2203
+ basis_update_mpf_t <i_t , f_t > ft (m, settings.refactor_frequency );
2204
+
2205
+ if (ft.factorize_basis (lp.A , settings, basic_list, nonbasic_list, vstatus) > 0 ) {
2206
+ return dual::status_t ::NUMERICAL;
2207
+ }
2208
+
2209
+ if (toc (start_time) > settings.time_limit ) { return dual::status_t ::TIME_LIMIT; }
2210
+ return dual_phase2_with_basis_update (phase,
2211
+ slack_basis,
2212
+ start_time,
2213
+ lp,
2214
+ settings,
2215
+ vstatus,
2216
+ ft,
2217
+ basic_list,
2218
+ nonbasic_list,
2219
+ sol,
2220
+ iter,
2221
+ delta_y_steepest_edge);
2222
+ }
2223
+
2224
+ template <typename i_t , typename f_t >
2225
+ dual::status_t dual_phase2_with_basis_update (i_t phase,
2226
+ i_t slack_basis,
2227
+ f_t start_time,
2228
+ const lp_problem_t <i_t , f_t >& lp,
2229
+ const simplex_solver_settings_t <i_t , f_t >& settings,
2230
+ std::vector<variable_status_t >& vstatus,
2231
+ basis_update_mpf_t <i_t , f_t >& ft,
2232
+ std::vector<i_t >& basic_list,
2233
+ std::vector<i_t >& nonbasic_list,
2234
+ lp_solution_t <i_t , f_t >& sol,
2235
+ i_t & iter,
2236
+ std::vector<f_t >& delta_y_steepest_edge)
2237
+ {
2238
+ const i_t m = lp.num_rows ;
2239
+ const i_t n = lp.num_cols ;
2240
+ assert (m <= n);
2241
+ assert (vstatus.size () == n);
2242
+ assert (lp.A .m == m);
2243
+ assert (lp.A .n == n);
2244
+ assert (lp.objective .size () == n);
2245
+ assert (lp.lower .size () == n);
2246
+ assert (lp.upper .size () == n);
2247
+ assert (lp.rhs .size () == m);
2248
+
2198
2249
std::vector<f_t >& x = sol.x ;
2199
2250
std::vector<f_t >& y = sol.y ;
2200
2251
std::vector<f_t >& z = sol.z ;
@@ -2208,35 +2259,6 @@ dual::status_t dual_phase2(i_t phase,
2208
2259
std::vector<variable_status_t > vstatus_old = vstatus;
2209
2260
std::vector<f_t > z_old = z;
2210
2261
2211
- phase2::bound_info (lp, settings);
2212
- get_basis_from_vstatus (m, vstatus, basic_list, nonbasic_list, superbasic_list);
2213
- assert (superbasic_list.size () == 0 );
2214
- assert (nonbasic_list.size () == n - m);
2215
-
2216
- // Compute L*U = A(p, basic_list)
2217
- csc_matrix_t <i_t , f_t > L (m, m, 1 );
2218
- csc_matrix_t <i_t , f_t > U (m, m, 1 );
2219
- std::vector<i_t > pinv (m);
2220
- std::vector<i_t > p;
2221
- std::vector<i_t > q;
2222
- std::vector<i_t > deficient;
2223
- std::vector<i_t > slacks_needed;
2224
-
2225
- if (factorize_basis (lp.A , settings, basic_list, L, U, p, pinv, q, deficient, slacks_needed) ==
2226
- -1 ) {
2227
- settings.log .debug (" Initial factorization failed\n " );
2228
- basis_repair (lp.A , settings, deficient, slacks_needed, basic_list, nonbasic_list, vstatus);
2229
- if (factorize_basis (lp.A , settings, basic_list, L, U, p, pinv, q, deficient, slacks_needed) ==
2230
- -1 ) {
2231
- return dual::status_t ::NUMERICAL;
2232
- }
2233
- settings.log .printf (" Basis repaired\n " );
2234
- }
2235
- if (toc (start_time) > settings.time_limit ) { return dual::status_t ::TIME_LIMIT; }
2236
- assert (q.size () == m);
2237
- reorder_basic_list (q, basic_list);
2238
- basis_update_mpf_t <i_t , f_t > ft (L, U, p, settings.refactor_frequency );
2239
-
2240
2262
std::vector<f_t > c_basic (m);
2241
2263
for (i_t k = 0 ; k < m; ++k) {
2242
2264
const i_t j = basic_list[k];
@@ -2872,48 +2894,27 @@ dual::status_t dual_phase2(i_t phase,
2872
2894
#endif
2873
2895
if (should_refactor) {
2874
2896
bool should_recompute_x = false ;
2875
- if (factorize_basis (lp.A , settings, basic_list, L, U, p, pinv, q, deficient, slacks_needed) ==
2876
- -1 ) {
2897
+ if (ft.factorize_basis (lp.A , settings, basic_list, nonbasic_list, vstatus) > 0 ) {
2877
2898
should_recompute_x = true ;
2878
2899
settings.log .printf (" Failed to factorize basis. Iteration %d\n " , iter);
2879
2900
if (toc (start_time) > settings.time_limit ) { return dual::status_t ::TIME_LIMIT; }
2880
- basis_repair (lp.A , settings, deficient, slacks_needed, basic_list, nonbasic_list, vstatus);
2881
2901
i_t count = 0 ;
2882
- while (factorize_basis (
2883
- lp.A , settings, basic_list, L, U, p, pinv, q, deficient, slacks_needed) == -1 ) {
2902
+ i_t deficient_size;
2903
+ while ((deficient_size =
2904
+ ft.factorize_basis (lp.A , settings, basic_list, nonbasic_list, vstatus)) > 0 ) {
2884
2905
settings.log .printf (" Failed to repair basis. Iteration %d. %d deficient columns.\n " ,
2885
2906
iter,
2886
- static_cast <int >(deficient. size () ));
2907
+ static_cast <int >(deficient_size ));
2887
2908
if (toc (start_time) > settings.time_limit ) { return dual::status_t ::TIME_LIMIT; }
2888
2909
settings.threshold_partial_pivoting_tol = 1.0 ;
2910
+
2889
2911
count++;
2890
2912
if (count > 10 ) { return dual::status_t ::NUMERICAL; }
2891
- basis_repair (
2892
- lp.A , settings, deficient, slacks_needed, basic_list, nonbasic_list, vstatus);
2893
-
2894
- #ifdef CHECK_BASIS_REPAIR
2895
- csc_matrix_t <i_t , f_t > B (m, m, 0 );
2896
- form_b (lp.A , basic_list, B);
2897
- for (i_t k = 0 ; k < deficient.size (); ++k) {
2898
- const i_t j = deficient[k];
2899
- const i_t col_start = B.col_start [j];
2900
- const i_t col_end = B.col_start [j + 1 ];
2901
- const i_t col_nz = col_end - col_start;
2902
- if (col_nz != 1 ) {
2903
- settings.log .printf (" Deficient column %d has %d nonzeros\n " , j, col_nz);
2904
- }
2905
- const i_t i = B.i [col_start];
2906
- if (i != slacks_needed[k]) {
2907
- settings.log .printf (" Slack %d needed but found %d instead\n " , slacks_needed[k], i);
2908
- }
2909
- }
2910
- #endif
2911
2913
}
2912
2914
2913
2915
settings.log .printf (" Successfully repaired basis. Iteration %d\n " , iter);
2914
2916
}
2915
- reorder_basic_list (q, basic_list);
2916
- ft.reset (L, U, p);
2917
+
2917
2918
phase2::reset_basis_mark (basic_list, nonbasic_list, basic_mark, nonbasic_mark);
2918
2919
if (should_recompute_x) {
2919
2920
std::vector<f_t > unperturbed_x (n);
0 commit comments