Самый простой способ сделать это без смещения - это продолжать генерировать случайные числа, пока они не удовлетворяют критериям:
#include <stdbool.h>
#include <stddef.h>
#include <math.h>
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
bool check_spacing(float* of, size_t count, float spacing) {
// n^2 algorithm, but can be reduced to n lg n if you sort and then just compare to
// previous item and either allocate a copy to sort or shuffle afterwards
for (size_t i = 1; i < count; ++i) {
for (size_t j = 0; j < i; ++j) {
if (fabsf(of[i] - of[j]) <= spacing) return false;
}
}
return true;
}
void generate_until_spacing(float* to, size_t count, float spacing, float rng(void*), void* context) {
do {
for (size_t i = 0; i < count; ++i) to[i] = rng(context);
} while (!check_spacing(to, count, spacing));
}
float frng(void* context) {
// Your original rng should have looked like `1 + rand() / (RAND_MAX / 9f)`
// for range [1, 10], or `rand() / (RAND_MAX / 10f)` for range [0, 10]
float* min_max = context;
float min = min_max[0];
float max = min_max[1];
return min + (rand() / (RAND_MAX / (max - min)));
}
int main(void) {
srand(time(NULL));
float spacing = 0.2;
float min = 1;
float max = 10;
float numbers[10];
generate_until_spacing(numbers, 10, spacing, frng, (float[]) { min, max });
for (size_t i = 0; i < 10; ++i) {
printf(i == 0 ? "%f" : ", %f", numbers[i]);
}
putchar('\n');
}
Это гарантирует, что все сгенерированные числа действительно независимы (насколько позволяет ваш rng) .
Если после выбора номера вы должны были сгенерировать числа из уменьшенного диапазона, числа с экстремальными значениями более вероятны, так как они с меньшей вероятностью окажутся в уменьшенном диапазоне. Хотя это может быть хорошо для вашего приложения и, вероятно, будет намного быстрее.
Генерация в большем диапазоне и деление эквивалентны генерации в меньшем диапазоне, поэтому это не решает проблему (или Вы ограничиваете себя целочисленными коэффициентами dx
, что, вероятно, не то, что вы хотите).