@@ -1057,6 +1057,7 @@ select_next_pair <- function(state, step_id = NULL, candidates = NULL) {
10571057 link_phase_b <- .adaptive_link_mode_active(controller ) && identical(phase_ctx $ phase , " phase_b" )
10581058 link_phase_b_concurrent <- isTRUE(link_phase_b ) &&
10591059 identical(as.character(controller $ multi_spoke_mode %|| % " independent" ), " concurrent" )
1060+ frozen_map <- link_controller $ link_transform_frozen_by_spoke %|| % list ()
10601061 active_link_spoke <- as.integer(NA_integer_ )
10611062 ranked_link_spokes <- integer()
10621063 link_progress <- NULL
@@ -1177,6 +1178,7 @@ select_next_pair <- function(state, step_id = NULL, candidates = NULL) {
11771178 local_priority_mode <- NA_character_
11781179 is_explore_step <- FALSE
11791180 selected_link_spoke_attempt <- as.integer(NA_integer_ )
1181+ selected_is_probe_ordering <- FALSE
11801182 selected_round_stage <- as.character(round_stage )
11811183 selected_stage_quota <- as.integer(stage_quota )
11821184 selected_stage_committed_so_far <- as.integer(stage_committed_so_far )
@@ -1258,18 +1260,24 @@ select_next_pair <- function(state, step_id = NULL, candidates = NULL) {
12581260 if (is.null(cand ) || nrow(cand ) == 0L ) {
12591261 next
12601262 }
1263+ spoke_for_utility <- as.integer(NA_integer_ )
1264+ stage_is_probe_ordering <- FALSE
12611265 if (isTRUE(is_link_mode ) && isTRUE(link_phase_b )) {
12621266 spoke_for_utility <- if (" link_spoke_id" %in% names(cand )) {
12631267 as.integer(unique(stats :: na.omit(as.integer(cand $ link_spoke_id )))[1L ] %|| % NA_integer_ )
12641268 } else {
12651269 as.integer(spoke_attempt %|| % NA_integer_ )
12661270 }
1267- cand <- .adaptive_link_attach_predictive_utility(
1268- candidates = cand ,
1269- state = state ,
1270- controller = link_controller ,
1271- spoke_id = as.integer(spoke_for_utility )
1272- )
1271+ stage_is_probe_ordering <- ! is.na(spoke_for_utility ) &&
1272+ isTRUE(frozen_map [[as.character(spoke_for_utility )]])
1273+ if (! isTRUE(stage_is_probe_ordering )) {
1274+ cand <- .adaptive_link_attach_predictive_utility(
1275+ candidates = cand ,
1276+ state = state ,
1277+ controller = link_controller ,
1278+ spoke_id = as.integer(spoke_for_utility )
1279+ )
1280+ }
12731281 }
12741282
12751283 explore_rate <- defaults $ explore_rate
@@ -1379,9 +1387,9 @@ select_next_pair <- function(state, step_id = NULL, candidates = NULL) {
13791387 na.rm = TRUE
13801388 )
13811389 selected_utility_mode <- .adaptive_selection_utility_mode(
1382- run_mode = controller $ run_mode ,
1390+ run_mode = if (isTRUE( stage_is_probe_ordering )) " within_set " else controller $ run_mode ,
13831391 has_regularization = isTRUE(has_regularized_utility ),
1384- is_cross_set = isTRUE(is_link_mode ) && isTRUE(link_phase_b )
1392+ is_cross_set = isTRUE(is_link_mode ) && isTRUE(link_phase_b ) && ! isTRUE( stage_is_probe_ordering )
13851393 )
13861394 if (isTRUE(is_link_mode ) && isTRUE(link_phase_b )) {
13871395 # Linking mode keeps canonical candidate generation/filtering via
@@ -1420,6 +1428,7 @@ select_next_pair <- function(state, step_id = NULL, candidates = NULL) {
14201428 local_priority_mode <- stage_local_priority_mode
14211429 selected_stage <- stage
14221430 selected_link_spoke_attempt <- as.integer(spoke_attempt %|| % NA_integer_ )
1431+ selected_is_probe_ordering <- isTRUE(stage_is_probe_ordering )
14231432 selected_round_stage <- as.character(attempt_round_stage )
14241433 selected_stage_quota <- as.integer(attempt_stage_quota )
14251434 selected_stage_committed_so_far <- as.integer(attempt_stage_committed_so_far )
@@ -1545,16 +1554,20 @@ select_next_pair <- function(state, step_id = NULL, candidates = NULL) {
15451554 B_id <- as.character(order_vals [[" B_id" ]] %|| % NA_character_ )
15461555 p_ij_ts <- trueskill_win_probability(A_id , B_id , state $ trueskill_state )
15471556 p_ij <- as.double(p_ij_ts )
1548- has_regularized_utility <- " u" %in% names(selected_pair ) &&
1549- " u0" %in% names(selected_pair ) &&
1550- is.finite(as.double(selected_pair $ u [[1L ]])) &&
1551- is.finite(as.double(selected_pair $ u0 [[1L ]])) &&
1552- abs(as.double(selected_pair $ u [[1L ]]) - as.double(selected_pair $ u0 [[1L ]])) > sqrt(.Machine $ double.eps )
1553- utility_mode <- .adaptive_selection_utility_mode(
1554- run_mode = controller $ run_mode ,
1555- has_regularization = isTRUE(has_regularized_utility ),
1556- is_cross_set = isTRUE(selected_is_cross_set )
1557- )
1557+ if (isTRUE(selected_is_cross_set ) && isTRUE(selected_is_probe_ordering )) {
1558+ utility_mode <- NA_character_
1559+ } else {
1560+ has_regularized_utility <- " u" %in% names(selected_pair ) &&
1561+ " u0" %in% names(selected_pair ) &&
1562+ is.finite(as.double(selected_pair $ u [[1L ]])) &&
1563+ is.finite(as.double(selected_pair $ u0 [[1L ]])) &&
1564+ abs(as.double(selected_pair $ u [[1L ]]) - as.double(selected_pair $ u0 [[1L ]])) > sqrt(.Machine $ double.eps )
1565+ utility_mode <- .adaptive_selection_utility_mode(
1566+ run_mode = controller $ run_mode ,
1567+ has_regularization = isTRUE(has_regularized_utility ),
1568+ is_cross_set = isTRUE(selected_is_cross_set )
1569+ )
1570+ }
15581571 if (isTRUE(is_link_mode ) && ! is.na(selected_spoke_id )) {
15591572 p_link_oriented <- .adaptive_link_predictive_prob_oriented(
15601573 state = state ,
0 commit comments