Подтвердить что ты не робот

Как я могу генерировать N случайных значений, которые суммируются с заданным значением?

Мне нужна твоя помощь с небольшой проблемой. У меня есть четыре ярлыка, и я хочу отобразить на них случайное значение от 0 до 100, а сумма их должна быть 100.

Это мой код:

private void randomly_Click(object sender, EventArgs e)
{
    double alpha = 0, beta = 0, gamma = 0, delta = 0;
    double temp;
    int tempDouble;

    Random rnd = new Random();

    alpha = rnd.Next(0, 100);

    temp = 100 - alpha;
    tempDouble = (int)temp;
    beta = rnd.Next(0, tempDouble);

    temp = 100 - (alpha + beta);
    tempDouble = (int)temp;
    gamma = rnd.Next(0, tempDouble);

    temp = 100 - (alpha + beta + gamma);
    tempDouble = (int)temp;
    delta = rnd.Next(0, tempDouble);

    temp = alpha + beta + delta + gamma;
    temp = 100 - temp;
    temp = temp / 4;

    alpha = alpha + temp;
    beta = beta + temp;
    gamma = gamma + temp;
    delta = delta + temp;

    cInsertion.Text = alpha.ToString();
    cMoyens.Text = beta.ToString();
    cInternational.Text = gamma.ToString();
    cRecherche.Text = delta.ToString();
}   

Проблема в том, что я даю альфа шанс иметь значение biggest, а для delta - значение lowest.

Есть ли способ дать им все тот же шанс иметь реальное значение random?

4b9b3361

Ответ 1

Вы можете сделать что-то вроде этого:

double alpha = 0, beta = 0, gamma = 0, delta = 0, k = 0;
Random rnd = new Random();

alpha = rnd.Next(0, 100);
beta = rnd.Next(0, 100);
gamma = rnd.Next(0, 100);
delta = rnd.Next(0, 100);

k = (alpha + beta + gamma + delta) / 100;

alpha /= k;
beta /= k;
gamma /= k;
delta /= k;

cInsertion.Text = alpha.ToString();
cMoyens.Text = beta.ToString();
cInternational.Text = gamma.ToString();
cRecherche.Text = delta.ToString();

Таким образом, вы говорите, что допустим случайное значение для всех 4 переменных, а затем будем масштабировать их с коэффициентом k, который сделает их сумму равной 100.

Ответ 2

Что делать, если вы вставляете все четыре значения в массив, затем перетасовываете их, а затем назначаете их в соответствии с их порядковой позицией? Таким образом, каждая переменная (гамма, тета и т.д.) Имеет равную вероятность получения высокого и низкого числа.

Ответ 3

Это очень интересная проблема. Мне нравится решение @Ivan_Ferić, я думаю, оно идеально, но у меня есть другая идея:

int total = 100;
Random rand = new Random();

int half = rand.next(0,total);   // the line

a = rand.Next(0,half);
b = max - a;
c = rand.Next(0,half);
d = max - c;

(Не проверено, возможно, +/- 1 необходимо добавить в некоторые из vars.) Кроме того, вы можете перетасовать значения.

Интересная часть наступает сейчас. Если мы изменим "линию":

min = <some_value>
max = <another_value>;
int half = rand.next(min,max);

... тогда мы можем завершить результат:

  • min = 0; max = 100: оригинал;
  • min = 20; max = 80: избегать небольших чисел;
  • min = 33; max = 100: заставить два числа быть меньше 32.

Ответ 4

Вместо того, чтобы генерировать отдельные числа случайным образом, сгенерируйте частичные суммы, затем вычислите части:

double alpha, beta, gama, delta = 0;

var rnd = new System.Random();
var cuts = new List<double>();

cuts.Add(Math.Floor(rnd.Next(0, 101)));
cuts.Add(Math.Floor(rnd.Next(0, 101)));
cuts.Add(Math.Floor(rnd.Next(0, 101)));

cuts.Sort();

alpha = cuts[0];
beta = cuts[1] - cuts[0];
gamma = cuts[2] - cuts[1];
delta = 100 - cuts[2];

Ответ 5

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

В коде вы просто то, что предложил Иван, за исключением того, что альфа, бета, гамма и дельта должны быть взяты из гамма-распределений с параметрами формы alpha_shape, beta_shape, gamma_shape и delta_shape. (Пусть другой параметр распределения Гамма равен 1.) Эти параметры формы управляют ожидаемыми относительными пропорциями.

Ответ 6

A реальный случайный номер? Короче говоря, нет. Только псевдослучайное число.

Генератор случайных чисел работает от тактовых циклов, и типично видеть повторяющиеся последовательности. Используемое семя зависит от свойства .Tick текущего DateTime.Now(если я правильно помню). Есть много достойных генераторов случайных чисел и API для .NET. Я бы рекомендовал их искать, если вы чувствуете, что у вас нет времени или желания вставить свои собственные.

Перемещено к комментариям, поскольку это кажется более подходящим.