HalvingGridSearchCV giving non-optimal results with min_resources='exhaust'

### Describe the bug

I am using `HalvingGridSearchCV` with 160 combinations and 1050 samples. When I use `min_resources` with `'exhaust'`, I get 6 iterations with the last iteration including 5 candidates and 640 samples. The process starts with 20 samples.

When I set `min_resources=30`, I also get 6 iterations with the last iteration having 5 candidates, but with 960 samples.

### Steps/Code to Reproduce

```python
halving_cv = HalvingGridSearchCV(
    knn_model, knn_grid,  #our model and the parameter combos we want to try
    scoring="roc_auc",  #could alternatively choose f1, accuracy or others
    n_jobs=-1,  #use all available cpus
    min_resources=30,  #"exhaust" sets this to 20, which is non-optimal. Possible bug in algorithm.
    factor=2,  #double samples and take top half of combos on each iteration
    cv=5, random_state=1234,
    refit=True,  #remembers the best combo and gives us back that model already trained and ready for testing
)

grid_result = halving_cv.fit(x_train, y_train)
```

### Expected Results

My understanding is that by using 'exhaust', the algorithm should figure out that 30 is a better value for min_resources. Instead it sets it to 20.

My ideal case would be for the last iteration to use all 1050 samples with the 5 candidates but I see no way to set parameters to make this happen.

My question is whether there is a bug in the min_resources=exhaust algorithm.

### Actual Results

With min_resources=30:
```
310	5	960	{'algorithm': 'auto', 'n_neighbors': 15, 'p': 1, 'weights': 'uniform'}	0.804883
311	5	960	{'algorithm': 'brute', 'n_neighbors': 5, 'p': 1, 'weights': 'uniform'}	0.793407
312	5	960	{'algorithm': 'ball_tree', 'n_neighbors': 5, 'p': 1, 'weights': 'uniform'}	0.789650
313	5	960	{'algorithm': 'auto', 'n_neighbors': 5, 'p': 1, 'weights': 'uniform'}	0.789410
314	5	960	{'algorithm': 'kd_tree', 'n_neighbors': 5, 'p': 1, 'weights': 'uniform'}	0.789410
```

### Versions

```shell
System:
    python: 3.10.12 (main, Jun 11 2023, 05:26:28) [GCC 11.4.0]
executable: /usr/bin/python3
   machine: Linux-5.15.109+-x86_64-with-glibc2.35

Python dependencies:
      sklearn: 1.2.2
          pip: 23.1.2
   setuptools: 67.7.2
        numpy: 1.23.5
        scipy: 1.11.2
       Cython: 3.0.2
       pandas: 1.5.3
   matplotlib: 3.7.1
       joblib: 1.3.2
threadpoolctl: 3.2.0

Built with OpenMP: True

threadpoolctl info:
       user_api: blas
   internal_api: openblas
    num_threads: 2
         prefix: libopenblas
       filepath: /usr/local/lib/python3.10/dist-packages/numpy.libs/libopenblas64_p-r0-742d56dc.3.20.so
        version: 0.3.20
threading_layer: pthreads
   architecture: Zen

       user_api: openmp
   internal_api: openmp
    num_threads: 2
         prefix: libgomp
       filepath: /usr/local/lib/python3.10/dist-packages/scikit_learn.libs/libgomp-a34b3233.so.1.0.0
        version: None

       user_api: blas
   internal_api: openblas
    num_threads: 2
         prefix: libopenblas
       filepath: /usr/local/lib/python3.10/dist-packages/scipy.libs/libopenblasp-r0-23e5df77.3.21.dev.so
        version: 0.3.21.dev
threading_layer: pthreads
   architecture: Zen

       user_api: blas
   internal_api: openblas
    num_threads: 2
         prefix: libopenblas
       filepath: /usr/local/lib/python3.10/dist-packages/cvxopt.libs/libopenblasp-r0-5c2b7639.3.23.so
        version: 0.3.23
threading_layer: pthreads
   architecture: Zen
```
```

COMMENT:
Still confused. My goal was to use max number of samples on last iteration. So when using `'exhaust'` I would like this goal met. Given that there are 1050 rows, my ideal would be to use 1050 on last iteration. If doubling goes over 1050 on last iteration then take the min of 1050 and doubled value. This does not seem to happen.

Second best would be to set `min_resources` to a value that gets me closest to 1050 on last iteration without going over it. When I use `min_resources=30`, I get to 960. When I use 'exhaust', it starts at 20 and I get 640.

So I am left with my question: does exhaust have a bug in setting `min_resources` if the goal is to use max resources on last iteration?

My second question is whether the behavior can be changed to allow overstepping max rows on the last iteration and then just use the max, e.g., 1050 in the example code.

At least some of the bugs seen are related to my range of neighbors. I changed this line and removed some. Would need to do more digging to squash others, all of which I believe are related to having too few rows per specific parameter settings.

`knn_grid = dict(n_neighbors=range(1,11),`

Labels: Needs Decision