@@ -99,13 +99,16 @@ void rins_t<i_t, f_t>::run_rins()
9999
100100 if (!dm.population .is_feasible ()) return ;
101101
102- cuopt_assert (lp_optimal_solution.size () == problem_ptr ->n_variables , " Assignment size mismatch" );
102+ cuopt_assert (lp_optimal_solution.size () == problem_copy ->n_variables , " Assignment size mismatch" );
103103 cuopt_assert (problem_copy->handle_ptr == &rins_handle, " Handle mismatch" );
104- cuopt_assert (problem_copy->n_variables == problem_ptr->n_variables , " Problem size mismatch" );
105- cuopt_assert (problem_copy->n_constraints == problem_ptr->n_constraints , " Problem size mismatch" );
106- cuopt_assert (problem_copy->n_integer_vars == problem_ptr->n_integer_vars ,
107- " Problem size mismatch" );
108- cuopt_assert (problem_copy->n_binary_vars == problem_ptr->n_binary_vars , " Problem size mismatch" );
104+ // Do not make assertions based on problem_ptr. The original problem may have been modified within
105+ // the FP loop relaxing integers cuopt_assert(problem_copy->n_variables ==
106+ // problem_ptr->n_variables, "Problem size mismatch"); cuopt_assert(problem_copy->n_constraints ==
107+ // problem_ptr->n_constraints, "Problem size mismatch"); cuopt_assert(problem_copy->n_integer_vars
108+ // == problem_ptr->n_integer_vars,
109+ // "Problem size mismatch");
110+ // cuopt_assert(problem_copy->n_binary_vars == problem_ptr->n_binary_vars, "Problem size
111+ // mismatch");
109112 cuopt_assert (dm.population .current_size () > 0 , " No solutions in population" );
110113
111114 solution_t <i_t , f_t > best_sol (*problem_copy);
@@ -128,21 +131,21 @@ void rins_t<i_t, f_t>::run_rins()
128131
129132 i_t sol_size_before_rins = best_sol.assignment .size ();
130133 auto lp_opt_device = cuopt::device_copy (this ->lp_optimal_solution , rins_handle.get_stream ());
131- cuopt_assert (lp_opt_device.size () == problem_ptr ->n_variables , " Assignment size mismatch" );
132- cuopt_assert (best_sol.assignment .size () == problem_ptr ->n_variables , " Assignment size mismatch" );
134+ cuopt_assert (lp_opt_device.size () == problem_copy ->n_variables , " Assignment size mismatch" );
135+ cuopt_assert (best_sol.assignment .size () == problem_copy ->n_variables , " Assignment size mismatch" );
133136
134- rmm::device_uvector<i_t > vars_to_fix (problem_ptr ->n_integer_vars , rins_handle.get_stream ());
137+ rmm::device_uvector<i_t > vars_to_fix (problem_copy ->n_integer_vars , rins_handle.get_stream ());
135138 auto end = thrust::copy_if (rins_handle.get_thrust_policy (),
136- problem_ptr ->integer_indices .begin (),
137- problem_ptr ->integer_indices .end (),
139+ problem_copy ->integer_indices .begin (),
140+ problem_copy ->integer_indices .end (),
138141 vars_to_fix.begin (),
139142 [lpopt = lp_opt_device.data (),
140- pb = problem_ptr ->view (),
143+ pb = problem_copy ->view (),
141144 incumbent = best_sol.assignment .data ()] __device__ (i_t var_idx) {
142145 return pb.integer_equal (lpopt[var_idx], incumbent[var_idx]);
143146 });
144147 vars_to_fix.resize (end - vars_to_fix.begin (), rins_handle.get_stream ());
145- f_t fractional_ratio = (f_t )(vars_to_fix.size ()) / (f_t )problem_ptr ->n_integer_vars ;
148+ f_t fractional_ratio = (f_t )(vars_to_fix.size ()) / (f_t )problem_copy ->n_integer_vars ;
146149
147150 // abort if the fractional ratio is too low
148151 if (fractional_ratio < settings.min_fractional_ratio ) {
@@ -164,7 +167,7 @@ void rins_t<i_t, f_t>::run_rins()
164167 cuopt_assert (thrust::all_of (rins_handle.get_thrust_policy (),
165168 vars_to_fix.begin (),
166169 vars_to_fix.end (),
167- [pb = problem_ptr ->view ()] __device__ (i_t var_idx) {
170+ [pb = problem_copy ->view ()] __device__ (i_t var_idx) {
168171 return pb.is_integer_var (var_idx);
169172 }),
170173 " All variables to fix must be integer variables" );
@@ -180,15 +183,15 @@ void rins_t<i_t, f_t>::run_rins()
180183 CUOPT_LOG_DEBUG (" Running RINS on solution with objective %g, fixing %d/%d" ,
181184 best_sol.get_user_objective (),
182185 vars_to_fix.size (),
183- problem_ptr ->n_integer_vars );
186+ problem_copy ->n_integer_vars );
184187 CUOPT_LOG_DEBUG (" RINS fixrate %g time limit %g" , fixrate, time_limit);
185188 CUOPT_LOG_DEBUG (" RINS fractional ratio %g%%" , fractional_ratio * 100 );
186189
187190 f_t prev_obj = best_sol.get_user_objective ();
188191
189192 auto [fixed_problem, fixed_assignment, variable_map] = best_sol.fix_variables (vars_to_fix);
190193 CUOPT_LOG_DEBUG (
191- " new var count %d var_count %d" , fixed_problem.n_variables , problem_ptr ->n_integer_vars );
194+ " new var count %d var_count %d" , fixed_problem.n_variables , problem_copy ->n_integer_vars );
192195
193196 // should probably just do an spmv to get the objective instead. ugly mess of copies
194197 solution_t <i_t , f_t > best_sol_fixed_space (fixed_problem);
@@ -271,7 +274,8 @@ void rins_t<i_t, f_t>::run_rins()
271274 CUOPT_LOG_DEBUG (" RINS submip solution found. Objective %.16e. Status %d" ,
272275 branch_and_bound_solution.objective ,
273276 int (branch_and_bound_status));
274- cuopt_assert (rins_solution_queue.size () > 0 , " RINS solution queue is unexpectedly empty" );
277+ // RINS submip may have just proved the initial guess is the optimal, therefore the queue might
278+ // be empty in that case
275279 }
276280 if (branch_and_bound_status == dual_simplex::mip_status_t ::OPTIMAL) {
277281 CUOPT_LOG_DEBUG (" RINS submip optimal" );
@@ -328,7 +332,7 @@ void rins_t<i_t, f_t>::run_rins()
328332 cuopt_assert (best_sol.test_number_all_integer (), " All must be integers after RINS" );
329333 if (best_sol.get_user_objective () < prev_obj) { improvement_found = true ; }
330334 cuopt_assert (best_sol.assignment .size () == sol_size_before_rins, " Assignment size mismatch" );
331- cuopt_assert (best_sol.assignment .size () == problem_ptr ->n_variables ,
335+ cuopt_assert (best_sol.assignment .size () == problem_copy ->n_variables ,
332336 " Assignment size mismatch" );
333337 dm.population .add_external_solution (
334338 best_sol.get_host_assignment (), best_sol.get_objective (), solution_origin_t ::RINS);
0 commit comments