@@ -65,38 +65,117 @@ branch_variable_t<i_t> line_search_diving(const std::vector<i_t>& fractional,
6565 return {branch_var, round_dir};
6666}
6767
68- template <typename i_t , typename f_t >
69- branch_variable_t <i_t > pseudocost_diving (pseudo_costs_t <i_t , f_t >& pc,
68+ template <typename i_t , typename f_t , branch_and_bound_mode_t Mode >
69+ branch_variable_t <i_t > pseudocost_diving (pseudo_costs_t <i_t , f_t , Mode >& pc,
7070 const std::vector<i_t >& fractional,
7171 const std::vector<f_t >& solution,
7272 const std::vector<f_t >& root_solution,
7373 logger_t & log)
7474{
75- return pseudocost_diving_from_arrays (pc.pseudo_cost_sum_down .data (),
76- pc.pseudo_cost_sum_up .data (),
77- pc.pseudo_cost_num_down .data (),
78- pc.pseudo_cost_num_up .data (),
79- (i_t )pc.pseudo_cost_sum_down .size (),
80- fractional,
81- solution,
82- root_solution);
75+ const i_t num_fractional = fractional.size ();
76+ if (num_fractional == 0 ) return {-1 , rounding_direction_t ::NONE};
77+
78+ pseudo_cost_averages_t <i_t , f_t > avgs = pc.compute_averages ();
79+
80+ i_t branch_var = fractional[0 ];
81+ f_t max_score = std::numeric_limits<f_t >::lowest ();
82+ rounding_direction_t round_dir = rounding_direction_t ::DOWN;
83+ constexpr f_t eps = f_t (1e-6 );
84+
85+ for (i_t j : fractional) {
86+ f_t f_down = solution[j] - std::floor (solution[j]);
87+ f_t f_up = std::ceil (solution[j]) - solution[j];
88+ f_t pc_down = pc.pseudo_cost_num_down [j] != 0
89+ ? pc.pseudo_cost_sum_down [j] / pc.pseudo_cost_num_down [j]
90+ : avgs.down_avg ;
91+ f_t pc_up = pc.pseudo_cost_num_up [j] != 0 ? pc.pseudo_cost_sum_up [j] / pc.pseudo_cost_num_up [j]
92+ : avgs.up_avg ;
93+
94+ f_t score_down = std::sqrt (f_up) * (1 + pc_up) / (1 + pc_down);
95+ f_t score_up = std::sqrt (f_down) * (1 + pc_down) / (1 + pc_up);
96+
97+ f_t score = 0 ;
98+ rounding_direction_t dir = rounding_direction_t ::DOWN;
99+
100+ f_t root_val = (j < static_cast <i_t >(root_solution.size ())) ? root_solution[j] : solution[j];
101+
102+ if (solution[j] < root_val - f_t (0.4 )) {
103+ score = score_down;
104+ dir = rounding_direction_t ::DOWN;
105+ } else if (solution[j] > root_val + f_t (0.4 )) {
106+ score = score_up;
107+ dir = rounding_direction_t ::UP;
108+ } else if (f_down < f_t (0.3 )) {
109+ score = score_down;
110+ dir = rounding_direction_t ::DOWN;
111+ } else if (f_down > f_t (0.7 )) {
112+ score = score_up;
113+ dir = rounding_direction_t ::UP;
114+ } else if (pc_down < pc_up + eps) {
115+ score = score_down;
116+ dir = rounding_direction_t ::DOWN;
117+ } else {
118+ score = score_up;
119+ dir = rounding_direction_t ::UP;
120+ }
121+
122+ if (score > max_score) {
123+ max_score = score;
124+ branch_var = j;
125+ round_dir = dir;
126+ }
127+ }
128+
129+ if (round_dir == rounding_direction_t ::NONE) {
130+ branch_var = fractional[0 ];
131+ round_dir = rounding_direction_t ::DOWN;
132+ }
133+
134+ return {branch_var, round_dir};
83135}
84136
85- template <typename i_t , typename f_t >
86- branch_variable_t <i_t > guided_diving (pseudo_costs_t <i_t , f_t >& pc,
137+ template <typename i_t , typename f_t , branch_and_bound_mode_t Mode >
138+ branch_variable_t <i_t > guided_diving (pseudo_costs_t <i_t , f_t , Mode >& pc,
87139 const std::vector<i_t >& fractional,
88140 const std::vector<f_t >& solution,
89141 const std::vector<f_t >& incumbent,
90142 logger_t & log)
91143{
92- return guided_diving_from_arrays (pc.pseudo_cost_sum_down .data (),
93- pc.pseudo_cost_sum_up .data (),
94- pc.pseudo_cost_num_down .data (),
95- pc.pseudo_cost_num_up .data (),
96- (i_t )pc.pseudo_cost_sum_down .size (),
97- fractional,
98- solution,
99- incumbent);
144+ const i_t num_fractional = fractional.size ();
145+ if (num_fractional == 0 ) return {-1 , rounding_direction_t ::NONE};
146+
147+ pseudo_cost_averages_t <i_t , f_t > avgs = pc.compute_averages ();
148+
149+ i_t branch_var = fractional[0 ];
150+ f_t max_score = std::numeric_limits<f_t >::lowest ();
151+ rounding_direction_t round_dir = rounding_direction_t ::DOWN;
152+ constexpr f_t eps = f_t (1e-6 );
153+
154+ for (i_t j : fractional) {
155+ f_t f_down = solution[j] - std::floor (solution[j]);
156+ f_t f_up = std::ceil (solution[j]) - solution[j];
157+ f_t down_dist = std::abs (incumbent[j] - std::floor (solution[j]));
158+ f_t up_dist = std::abs (std::ceil (solution[j]) - incumbent[j]);
159+ rounding_direction_t dir =
160+ down_dist < up_dist + eps ? rounding_direction_t ::DOWN : rounding_direction_t ::UP;
161+
162+ f_t pc_down = pc.pseudo_cost_num_down [j] != 0
163+ ? pc.pseudo_cost_sum_down [j] / pc.pseudo_cost_num_down [j]
164+ : avgs.down_avg ;
165+ f_t pc_up = pc.pseudo_cost_num_up [j] != 0 ? pc.pseudo_cost_sum_up [j] / pc.pseudo_cost_num_up [j]
166+ : avgs.up_avg ;
167+ f_t score1 = dir == rounding_direction_t ::DOWN ? 5 * pc_down * f_down : 5 * pc_up * f_up;
168+ f_t score2 = dir == rounding_direction_t ::DOWN ? pc_up * f_up : pc_down * f_down;
169+ f_t score = (score1 + score2) / 6 ;
170+
171+ if (score > max_score) {
172+ max_score = score;
173+ branch_var = j;
174+ round_dir = dir;
175+ }
176+ }
177+
178+ return {branch_var, round_dir};
100179}
101180
102181template <typename i_t , typename f_t >
@@ -187,12 +266,26 @@ template branch_variable_t<int> pseudocost_diving(pseudo_costs_t<int, double>& p
187266 const std::vector<double >& root_solution,
188267 logger_t & log);
189268
269+ template branch_variable_t <int > pseudocost_diving (
270+ pseudo_costs_t <int , double , branch_and_bound_mode_t ::DETERMINISTIC>& pc,
271+ const std::vector<int >& fractional,
272+ const std::vector<double >& solution,
273+ const std::vector<double >& root_solution,
274+ logger_t & log);
275+
190276template branch_variable_t <int > guided_diving (pseudo_costs_t <int , double >& pc,
191277 const std::vector<int >& fractional,
192278 const std::vector<double >& solution,
193279 const std::vector<double >& incumbent,
194280 logger_t & log);
195281
282+ template branch_variable_t <int > guided_diving (
283+ pseudo_costs_t <int , double , branch_and_bound_mode_t ::DETERMINISTIC>& pc,
284+ const std::vector<int >& fractional,
285+ const std::vector<double >& solution,
286+ const std::vector<double >& incumbent,
287+ logger_t & log);
288+
196289template void calculate_variable_locks (const lp_problem_t <int , double >& lp_problem,
197290 std::vector<int >& up_locks,
198291 std::vector<int >& down_locks);
0 commit comments