C # Формула для распределения чисел - PullRequest
1 голос
/ 30 июля 2009

Я ищу формулу, которая может распределять числа в линейном формате на основе минимального числа, максимального числа и количества чисел (или точек) между ними. Уловка в том, что чем ближе к максимуму, тем больше должно быть цифр.

Пример (число будет меняться и будет примерно в 100 раз больше)

Min = 0
Max = 16
AmountOfNumbersToSpread = 6

0 1 2 3 4 5 6 7 8 9 A B C D E F

1           2       3   4   5 6 

Заранее спасибо за помощь.

Ответы [ 4 ]

2 голосов
/ 30 июля 2009

Основываясь на ответе Тала Прессмана, вы можете написать функцию распределения следующим образом:

IEnumerable<double> Spread(int min, int max, int count, Func<double, double> distribution)
    {
    double start = min;
    double scale = max - min;
    foreach (double offset in Redistribute(count, distribution))
        yield return start + offset * scale;
    }

IEnumerable<double> Redistribute(int count, Func<double, double> distribution)
    {
    double step = 1.0 / (count - 1);
    for (int i = 0; i < count; i++)
        yield return distribution(i * step);
    }

Вы можете использовать любой тип функции распределения, которая таким образом отображает [0; 1] в [0; 1]. Примеры:

квадратичная

Spread(0, 16, 6, x => 1-(1-x)*(1-x))

Output: 0 5.76 10.24 13.44 15.36 16

синус

Spread(0, 16, 6, x => Math.Sin(x * Math.PI / 2))

Output: 0 4.94427190999916 9.40456403667957 12.9442719099992 15.2169042607225 16
1 голос
/ 30 июля 2009

По сути, у вас должно быть что-то похожее на:

  1. Создать случайное число от 0 до 1.
  2. Реализация желаемой функции распределения (функция 1: 1 из [0,1] -> [0,1]).
  3. Масштабировать результат функции распределения в соответствии с желаемым диапазоном.

Точная функция, используемая для второй точки, определяется в зависимости от того, как именно вы хотите, чтобы числа были распределены, но в соответствии с вашими требованиями вы захотите, чтобы функция имела больше значений, близких к 1, чем 0. Например, функция sin или cos.

0 голосов
/ 30 июля 2009

Закрыть ответ, хотя и не совсем, нужно работать для больших чисел.

List<int> lstMin = new List<int>();

int Min = 1;
int Max = 1500;

int Length = Max - Min;
int Current = Min;
int ConnectedClient = 7;
double Space;

while(ConnectedClient > 0)
{
    Space = Math.Ceiling((double)(Length * ConnectedClient / (Max - Min)));
    Current += (int)Space;

    ConnectedClient--;
    Length--;

    lstMin.Add(Current);
}
0 голосов
/ 30 июля 2009

Пробовал это на бумаге, и это сработало:

с учетом MIN, MAX, AMOUNT:

Length = MAX - MIN
"mark" MIN and MAX
Length--, AMOUNT--
Current = MIN
While AMOUNT > 1
  Space = Ceil(Length * Amount / (MAX - MIN))
  Current += Space
  "mark" Current

Под "отметкой" я подразумеваю выбрать это число или все, что вам нужно с ним сделать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...