2009-07-30 2 views
1

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

В качестве примера (номер будет меняться и будет примерно в 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 

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

+1

Является ли это домашнее задание вопрос? –

+0

выглядит как вопрос интервью – nairdaen

+0

Нет, я просто сосать по математике. У меня есть люди, входящие в программу клиент/сервер. При этом мне нужно назначить им число, которое по существу будет паузой для действия, которое клиент говорит им делать. Серверу необходимо вычислить паузу и передать их клиентам. – 2009-07-30 02:31:12

ответ

1

В принципе, вы должны иметь что-то, что выглядит как:

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

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

0

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

данный MIN, MAX, СУММА:

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

Под «знаком» Я имею в виду, что выбрать номер, или все, что вам нужно сделать с ним.

+0

близко, но не работает с большими числами. Список lstMin = новый Список (); int Min = 1; int Max = 1500; int Length = Max - Min; int Current = Min; int ConnectedClient = 7; двойное пространство; while (ConnectedClient> 0) { Space = Math.Ceiling ((double) (Length * ConnectedClient/(Max - Min))); Ток + = (int) Пробел; ConnectedClient--; Длина--; lstMin.Add (текущий); } – 2009-07-30 03:12:12

+0

, который не опубликовал хорошо, введите ответ ниже. – 2009-07-30 03:12:48

0

Близкий ответ, не совсем, хотя он должен работать для больших чисел.

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); 
} 
2

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

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 
+0

Это сработало отлично, и в то же время научило меня чему-то крутому. Спасибо A TON за это. – 2009-07-30 23:44:23

Смежные вопросы