Skip to content

Run without diversification field - #6

Merged
PhilippVerpoort merged 3 commits into
mainfrom
feature/run-without-div-field
Aug 31, 2026
Merged

Run without diversification field#6
PhilippVerpoort merged 3 commits into
mainfrom
feature/run-without-div-field

Conversation

@PhilippVerpoort

@PhilippVerpoort PhilippVerpoort commented Aug 31, 2026

Copy link
Copy Markdown
Collaborator

Allow DREAM/HERMES to run without a diversify field

LEGACY genuinely needs at least one Diversify-mode field, but DREAM and HERMES's swap machinery degrades gracefully to optimising unique meetings only when no diversity fields are configured -- so drop the same upfront guard for those two algorithms.

Doing so surfaces two latent crashes in the now-reachable degenerate path, both fixed here:

  • HERMES's pareto_prob_for() called max() on the empty pareto_probs dict whenever a candidate improved no diversity field, which is every candidate once there are no diversity fields at all -- a guaranteed ValueError on the first swap. Falls back to 0.0 instead, which keeps select_key() on its meeting-uniqueness branch, DREAM's own natural behaviour in this case.
  • (Investigated, not a real bug: DREAM/HERMES's shared select_key() divides by the summed pareto score of the tied candidates, which looked like a possible zero-division once no diversity fields contribute a nonzero score -- but pareto_swaps()'s own distinct-value collapsing always leaves exactly one candidate whenever every candidate's score is 0, so that branch's division is never reached with >1 candidates. Verified empirically across many seeds/configs.)

Confirmed byte-identical DREAM/HERMES output before/after this patch whenever a diversify field is present -- this only changes behaviour in what used to be exception paths.

Adds regression tests for both algorithms running without a diversify field, and for LEGACY still requiring one.

Fix dtype crash in allocate_pandas() with an empty fields dict

participants[list(fields.keys())].apply(...) on a zero-column selection (fields={}) returns an empty DataFrame with no columns to infer a dtype from, so pandas defaults it to float64. to_numpy() then carries that float64 dtype through to allocate_numpy(), which rejects it with "Argument participants must only contain integers." -- masking whatever the algorithm would otherwise have said (including LEGACY's own, more meaningful "One diversification field required!" for this same input).

Build the (n_participants, 0) array directly, with an explicit integer dtype, when fields is empty, instead of going through to_numpy() on the empty-column selection. Confirmed byte-identical allocate_pandas() output before/after this patch whenever fields is non-empty -- the new branch only fires for the previously-broken fields={} case.

Adds regression tests for DREAM/HERMES allocating with fields={} (needs the DREAM/HERMES-without-diversify-field patch stacked below this one, since fields={} implies no diversify field either), and for LEGACY now raising its own diversification-field error for fields={} instead of the dtype error.

PhilippVerpoort and others added 3 commits August 31, 2026 23:11
LEGACY genuinely needs at least one Diversify-mode field, but DREAM and
HERMES's swap machinery degrades gracefully to optimising unique
meetings only when no diversity fields are configured -- so drop the
same upfront guard for those two algorithms.

Doing so surfaces two latent crashes in the now-reachable degenerate
path, both fixed here:
- HERMES's pareto_prob_for() called max() on the empty pareto_probs
  dict whenever a candidate improved no diversity field, which is
  every candidate once there are no diversity fields at all -- a
  guaranteed ValueError on the first swap. Falls back to 0.0 instead,
  which keeps select_key() on its meeting-uniqueness branch, DREAM's
  own natural behaviour in this case.
- (Investigated, not a real bug: DREAM/HERMES's shared select_key()
  divides by the summed pareto score of the tied candidates, which
  looked like a possible zero-division once no diversity fields
  contribute a nonzero score -- but pareto_swaps()'s own
  distinct-value collapsing always leaves exactly one candidate
  whenever every candidate's score is 0, so that branch's division is
  never reached with >1 candidates. Verified empirically across many
  seeds/configs.)

Confirmed byte-identical DREAM/HERMES output before/after this patch
whenever a diversify field is present -- this only changes behaviour
in what used to be exception paths.

Adds regression tests for both algorithms running without a diversify
field, and for LEGACY still requiring one.
`participants[list(fields.keys())].apply(...)` on a zero-column
selection (fields={}) returns an empty DataFrame with no columns to
infer a dtype from, so pandas defaults it to float64. to_numpy() then
carries that float64 dtype through to allocate_numpy(), which rejects
it with "Argument participants must only contain integers." -- masking
whatever the algorithm would otherwise have said (including LEGACY's
own, more meaningful "One diversification field required!" for this
same input).

Build the (n_participants, 0) array directly, with an explicit integer
dtype, when fields is empty, instead of going through to_numpy() on the
empty-column selection. Confirmed byte-identical allocate_pandas()
output before/after this patch whenever fields is non-empty -- the new
branch only fires for the previously-broken fields={} case.

Adds regression tests for DREAM/HERMES allocating with fields={}
(needs the DREAM/HERMES-without-diversify-field patch stacked below
this one, since fields={} implies no diversify field either), and for
LEGACY now raising its own diversification-field error for fields={}
instead of the dtype error.
@PhilippVerpoort PhilippVerpoort self-assigned this Aug 31, 2026
@PhilippVerpoort
PhilippVerpoort merged commit be9fdb1 into main Aug 31, 2026
5 checks passed
@PhilippVerpoort
PhilippVerpoort deleted the feature/run-without-div-field branch August 31, 2026 21:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant