[Meta] consistently break ties randomly in scikit-learn estimators (with random_state) in an unbiased way

Some estimators have arbitrary ways to break ties:

- k-nearest neighbors with data points lying on a uniform 1d grid (see #23667 for the BallTree for instance);
- tied splits on different features in histogram gradient boosted trees with redundant features.
- decision tree splits on the same feature with equivalent threshods: `X = [[0], [1], [2], [3]]` and `y = [0, 1, 1, 0]`: `X > 0.5` and `X > 2.5` are tied splits but only `X > 0.5` is considered;
- possibly other models (please feel free to edit this list or suggest missing estimators in the comments).

If the tie breaking logic is deterministic, then it might introduce a non-controllable bias in a datascience pipeline. For instance when analyzing the feature importance of an histogram gradient boosting model (via permutations or SHAP values), the first feature of a group of redundant features would always deterministically be picked up by the model and could lead a naive datascientist to believe that the other features of the group are not as predictive.

Note that this is not the case for our traditional `DecisionTreeClassifier/Regressor` / `RandomForestClassifier/Regressor` and extra trees because they all do [feature shuffling](https://github.com/scikit-learn/scikit-learn/blob/c217527af5744b9d0db8761c1e3667552312e5e7/sklearn/tree/_splitter.pyx#L322) (controllable by `random_state`) by default even when `max_features == 1.0`. This makes it easy to conduct the same study many times with different seeds to see if the results are an artifact of an arbitrary tie breaking or not.

COMMENT:
Here is a notebook to showcase some exact/close split ties that happen in small trees.
https://gist.github.com/antoinebaker/461ab61f80ea8538a52e80491319f670

To summarize, we refit the same decision tree for 100 random states and collect the splits.
There is a unique split for the root node. For the left and right child, we get (exact or close) tied splits:
- we can get different (but allclose) impurities for the same (feature, threshold) pair, see for example node=left, feature=2.
- we can get different (but allclose) values for the same (feature, threshold) pair, see for example node=right, feature=6.

As mentioned above this is likely due to some systematic (but uncontrolled) rounding errors, and is not solved by shuffling the features or samples.

node | node_id | feature | threshold | impurity | value | size
-- | -- | -- | -- | -- | -- | -- 
left | 1 | 2 | -0.5120572894811630 | 0.3224197418352606 | 0.6375592996157050 | 34
left | 1 | 2 | -0.5120572894811630 | 0.3224197418352607 | 0.6375592996157050 | 19
left | 1 | 10 | -0.9393941909074783 | 0.3224197418352606 | 0.6375592996157050 | 28
left | 1 | 10 | -0.9393941909074783 | 0.3224197418352607 | 0.6375592996157050 | 19
right | 6 | 2 | -0.7026711404323578 | 0.2909537914759641 | -0.5731517908772066 | 3
right | 6 | 2 | -0.7026711404323578 | 0.2909537914759643 | -0.5731517908772066 | 15
right | 6 | 2 | -0.7026711404323578 | 0.2909537914759646 | -0.5731517908772066 | 3
right | 6 | 11 | 1.2267193496227264 | 0.2909537914759641 | -0.5731517908772066 | 5
right | 6 | 11 | 1.2267193496227264 | 0.2909537914759641 | -0.5731517908772065 | 18
right | 6 | 11 | 1.2267193496227264 | 0.2909537914759643 | -0.5731517908772066 | 9
right | 6 | 11 | 1.2267193496227264 | 0.2909537914759643 | -0.5731517908772065 | 28
right | 6 | 11 | 1.2267193496227264 | 0.2909537914759646 | -0.5731517908772066 | 3
right | 6 | 14 | -2.0491334795951843 | 0.2909537914759641 | -0.5731517908772066 | 5
right | 6 | 14 | -2.0491334795951843 | 0.2909537914759643 | -0.5731517908772066 | 10
right | 6 | 14 | -2.0491334795951843 | 0.2909537914759646 | -0.5731517908772066 | 1
root | 0 | 11 | 0.0169256031513214 | 0.6616304844057505 | 0.1532748634185404 | 100

Labels: Needs Decision