Генерация серии случайных чисел, которые складываются в N в c #

Как мне сгенерировать 30 случайных чисел в диапазоне от 1 до 9, которые в сумме составляют до 200 (или несколько произвольных N), в C #?

Я пытаюсь сгенерировать строку цифр, которая может складываться в N.

12 голосов | спросил Fatal510 23 Jam1000000amFri, 23 Jan 2009 08:47:41 +030009 2009, 08:47:41

16 ответов


0

Я не уверен, какова статистика по этому вопросу, но проблема в том, что вы не хотите случайным образом выбирать число, которое делает невозможным суммирование N с числом M записей, как в результате превышения, так и в результате отрицательного или отрицательного значения. Вот как бы я это сделал:

static void Main()
{
    int count = 30;
    int[] numbers = getNumbers(count, 155);
    for (int index = 0; index < count; index++)
    {
        Console.Write(numbers[index]);
        if ((index + 1) % 10 == 0)
            Console.WriteLine("");
        else if (index != count - 1)
            Console.Write(",");
    }
    Console.ReadKey();
}
static int[] getNumbers(int count, int total)
{
    const int LOWERBOUND = 1;
    const int UPPERBOUND = 9;

    int[] result = new int[count];
    int currentsum = 0;
    int low, high, calc;

    if((UPPERBOUND * count) < total ||
        (LOWERBOUND * count) > total ||
        UPPERBOUND < LOWERBOUND)
        throw new Exception("Not possible.");

    Random rnd = new Random();

    for (int index = 0; index < count; index++)
    {
        calc = (total - currentsum) - (UPPERBOUND * (count - 1 - index));
        low = calc < LOWERBOUND ? LOWERBOUND : calc;
        calc = (total - currentsum) - (LOWERBOUND * (count - 1 - index));
        high = calc > UPPERBOUND ? UPPERBOUND : calc;

        result[index] = rnd.Next(low, high + 1);

        currentsum += result[index];
    }

    // The tail numbers will tend to drift higher or lower so we should shuffle to compensate somewhat.

    int shuffleCount = rnd.Next(count * 5, count * 10);
    while (shuffleCount-- > 0)
        swap(ref result[rnd.Next(0, count)], ref result[rnd.Next(0, count)]);

    return result;
}
public static void swap(ref int item1, ref int item2)
{
    int temp = item1;
    item1 = item2;
    item2 = temp;
}

У меня не было много времени, чтобы проверить это, поэтому извиняюсь, если где-то есть ошибки в моей логике.

РЕДАКТИРОВАТЬ:

Я провел некоторое тестирование, и все кажется надежным. Если вы хотите получить симпатичное распространение, это выглядит так, как будто вы хотите что-то вроде Total = Count * ((UPPER + LOWER) / 2). Хотя я вполне уверен, что разница между UPPER и LOWER увеличивается, чем гибче это становится.

ответил Spencer Ruport 23 Jam1000000amFri, 23 Jan 2009 09:58:57 +030009 2009, 09:58:57
0

Проблема в том, что мы хотим, чтобы все числа были ограничены 1-9 и складывались в N. Таким образом, мы должны сгенерировать каждое число одно за другим и определить действительные границы для следующего числа.

Это, конечно, приведет к статистическому смещению к концу списка, поэтому я рекомендую перетасовывать массив один раз после генерации.

Чтобы определить границы следующего числа, сделайте следующее: Верхняя граница = взять оставшуюся сумму минус (количество оставшихся элементов * мин). Нижняя граница = взять оставшуюся сумму минус (количество оставшихся элементов * max).

Что-то вроде (не проверено):

public static List<int> RandomList(int digitMin, int digitMax, 
                                   int targetSum, int numDigits)
{
    List<int> ret = new List<int>(numDigits);

    Random random = new Random();
    int localMin, localMax, nextDigit;
    int remainingSum = targetSum;

    for(int i=1; i<=numDigits; i++)
    {
          localMax = remainingSum - ((numDigits - i) * min);
          if(localMax > max)
              localMax = max;

          localMin = remainingSum - ((length - i) * max);
          if(localMin > min)
              localMin = min;

          nextDigit = random.Next(localMin, localMax);
          ret.Add(nextDigit);
          remainingSum -= nextDigit;
    }

    return ret;
}

Идея заключается в том, что при генерации чисел диапазон возможных значений для оставшихся чисел уменьшается, как предельная функция, нацеленная на целевую сумму. Вроде.

Редактировать: мне пришлось изменить цикл for на 1, потому что мы хотим, чтобы количество элементов осталось ПОСЛЕ генерации этого.

Edit2: поместите его в метод для полноты и измените length на numDigits для удобства чтения.

ответил lc. 23 Jam1000000amFri, 23 Jan 2009 09:28:01 +030009 2009, 09:28:01
0

Мое оригинальное заявление:

Вы можете создать только 29 случайных чисел. 30-е число будет определяться другими 29 и суммой. Это статистически важно ...

Я хотел бы добавить некоторые пояснения, подумав об этом, и пинговать сообщество ...

Теперь я верю, что мое первоначальное утверждение было ложным. Это было слишком снисходительно (на что указал lc). Вы даже не можете сгенерировать 29 действительно случайных чисел. Когда вы подходите ближе и ближе к 30, последние цифры не случайны так же, как случайный rnd [1..9]. Я пытался смягчить это, чтобы найти решение, но я думаю, что решение, которое он придумал (и Спенсер), отвечает на совершенно другой вопрос. Этот вопрос звучит так: «Из всех наборов из 30 цифр от 1 до 9, которые составляют до 200, строят один случайным образом».

Я считаю, что дело в том, что заявленный вопрос неразрешим, что, я считаю, можно доказать с помощью Принцип Pigeonhole (также используется Кнутом, чтобы показать, что некоторые" случайные "тасовки не были действительно случайными), но я не сделал математику.

Хороший разговор всем.

ответил Jason Punyon 23 Jam1000000amFri, 23 Jan 2009 08:57:51 +030009 2009, 08:57:51
0

Эта программа попытается дать вам ответ. Но поскольку вы имеете дело со случайными числами, есть вероятность, что это никогда не даст вам ответа.

public static IEnumerable<int> GetRandom()
{
    var rand = new Random();
    while (true)
    {
        yield return
        rand.Next(1, 9);
    }
}

public static List<int> GetThirtyThatAddToTwoHundred()
{
    do
    {
        var current = GetRandom().Take(30);
        if (200 == current.Sum())
        {
            return current.ToList();
        }
    } while (true);
}
ответил JaredPar 23 Jam1000000amFri, 23 Jan 2009 08:56:27 +030009 2009, 08:56:27
0

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

public static List<int> RandomListByIncrementing(int digitMin, int digitMax, 
                                                 int targetSum, int numDigits)
{
    if(targetSum < digitMin * numDigits || targetSum > digitMax * numDigits)
        throw new ArgumentException("Impossible!", "targetSum");

    List<int> ret = new List<int>(Enumerable.Repeat(digitMin, numDigits));
    List<int> indexList = new List<int>(Enumerable.Range(0, numDigits-1));

    Random random = new Random();
    int index;

    for(int currentSum=numDigits * digitMin; currentSum<targetSum; currentSum++)
    {
        //choose a random digit in the list to increase by 1
        index = random.Next(0,indexList.Length-1);

        if(++ret[indexList[index]] == digitMax)
        {
            //if you've increased it up to the max, remove its reference
            //because you can't increase it anymore
            indexList.RemoveAt(index);
        }
    }

    return ret;
}

Идея в том, что вы ведете список ссылок на ваш список номеров. Выберите ссылку случайным образом и увеличьте соответствующее число. Если вы не можете увеличить его больше, удалите ссылку, чтобы не выбирать ее в следующий раз.

Теперь в конце дня перестановки делать нельзя, хотя, возможно, это все равно даст один из доступных наборов ответов на вопрос, и вопрос в том, какой из них «лучше» или быстрее запустить .

ответил lc. 23 Jpm1000000pmFri, 23 Jan 2009 18:49:19 +030009 2009, 18:49:19
0

Поэтому я должен спросить: Есть ли для этого реальная цель, или это просто упражнение или домашнее задание? Продолжается большая работа по предотвращению «предвзятости». Это фактическое требование, или подойдет какое-нибудь довольно случайное решение? Не зная требований, очень легко тратить много времени. Если это реальная проблема, пожалуйста, объясните, каковы фактические требования.

ответил 21 J0000006Europe/Moscow 2009, 01:16:00
0

Если допустимо статистическое отклонение от истинной случайности, вы можете добавить числа до N - [максимальное случайное число], а затем выбрать последнее число как N-сумму (выбрано до сих пор).

ответил Silver Dragon 23 Jam1000000amFri, 23 Jan 2009 09:02:09 +030009 2009, 09:02:09
0

Алгоритм:

  1. Установить общее количество = 200 (или что-то еще)
  2. Создать случайное число от 1 до 9
  3. Проверьте, если (total - newRandomNumber> = 0), если нет перехода к 6
  4. total - = newRandomNumber
  5. Добавить newRandomNumber в массив, перейти к 2.
  6. newRandomNumber = total
  7. Добавьте newRandomNumber в массив, если newRandomNumber! = 0
  8. End
ответил Alec Smart 23 Jam1000000amFri, 23 Jan 2009 09:21:25 +030009 2009, 09:21:25
0

Нет гарантии, что 30 случайных чисел от 1 до 9 будут суммироваться с любым конкретным N.

То, что вы можете найти, это список чисел, которые будут складываться из N и ограничены 1-9, но число не обязательно будет 30. Я считаю, что минимальное количество нужных вам номеров - 23, то есть (22 * 9) + 2. Максимум, конечно, будет 200 (200 * 1). Таким образом, длина списка где-то внутри [23,200]. Шансы на то, что случайный список может быть длиной 30, таким образом, довольно низки. Если все длины списка доступны (я думаю, что они есть), ваши шансы в долгосрочной перспективе около 0,5%.

ответил Simon P 23 Jam1000000amFri, 23 Jan 2009 09:59:56 +030009 2009, 09:59:56
0

Я думаю, что это самый простой способ сделать это, поэтому может не хватить какой-то изощренности, однако он приведет вас туда.

        String output = "";
        int sum = 0;
        int result = 200;       //enter the "end number"

        Random r = new Random();

        while (sum != result) {
            int add;
            if ((result - sum) > 10)
            {
                add = r.Next(1, 10);
            }
            else
            {
                add = r.Next(result - sum + 1);
            }

            sum += add;
            output += add.ToString() + " + ";
        }

        output = output.Remove(output.Length - 2);

        Console.WriteLine(output);

Надеюсь, это поможет!

ответил David Božjak 23 Jam1000000amFri, 23 Jan 2009 11:29:42 +030009 2009, 11:29:42
0

Если вам нужен беспристрастный алгоритм, то наивная реализация выглядит примерно так:

while (true) {
  numbers = [];
  total = 0;
  for (i = 0; i < COUNT; ++i) {
    next = rand(BOUNDS);
    total += next;
    numbers.push(next);
  }

  if (total == TARGET) {
    return numbers;
  }
}

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

ответил 23 Jpm1000000pmFri, 23 Jan 2009 18:04:34 +030009 2009, 18:04:34
0

Этот метод возвращает 30 случайных чисел, которые складываются в произвольный N. Можно сделать, чтобы иметь около 0 значений. если это невозможно, просто инициализируйте массив все в единицу и, если сумма больше, чем произвольное N, установите для vals [nextIdx] значение 1 вместо 0. Надеюсь, это поможет.

    private int[] getNumbers(int arbitraryN) {
        int[] vals = new int[30];
        int nextIdx = 0;
        int nextNumber=0;
        Random r = new Random();
        if (arbitraryN > 270 || arbitraryN < 30)
            throw new Exception("Not a Valid number");
        while (vals.Sum() < arbitraryN)
        {
            nextNumber = r.Next(1, 9);
            nextIdx = r.Next(29);
            vals[nextIdx] = nextNumber;
            if (vals.Sum() > arbitraryN)
            {
                vals[nextIdx] = 0;
                vals[nextIdx] = 270 - vals.Sum();
                break;
            }
        }
        return vals;
    }
ответил Igor Zelaya 23 Jam1000000amFri, 23 Jan 2009 09:48:00 +030009 2009, 09:48:00
0

Чтобы ответ не был смещен в сторону меньших чисел (или любого другого отклонения), в идеале вы должны генерировать все возможные наборы чисел, которые в сумме составляют N. После того, как у вас есть все наборы, случайным образом выберите один из наборов. После того, как вы выбрали выигрышный набор, вы можете, если нужно, случайным образом изменить порядок чисел в этом наборе.

ответил codingoutloud 24 Jam1000000amSat, 24 Jan 2009 04:27:59 +030009 2009, 04:27:59
0

Я думал, что попробую подход «разделяй и властвуй». Кажется, работает довольно хорошо. Я уверен, что результаты не являются действительно случайными из-за ограничивающих элементов алгоритма, но это близко. По сути, я делю список на две части и целевую сумму пополам и повторяю до тех пор, пока не получу списки из 3 элементов или менее. Затем я использую итерацию случайных цифр методом грубой силы до тех пор, пока не будут получены эти меньшие суммы. Вот код с примером запуска под ним.

using System;
using System.Collections.Generic;

namespace AddUpClient {
    class Program {

        static void Main() {
            AddUpWorker worker = new AddUpWorker();
            int MinDigit = 1;
            int MaxDigit = 9;
            int ItemsToSum = 30;
            int TargetSum = 150;

            try {
                //Attempt to get a list of pseudo-random list of integers that add up to the target sum
                IList<int> Results = worker.AddUp(MinDigit, MaxDigit, ItemsToSum, TargetSum);

                EvaluateResults(TargetSum, Results);
                Console.ReadLine();
            }
            catch (Exception E) {
                Console.Out.WriteLine("Error: {0}", E.Message);
                return;
            }

        }

        private static void EvaluateResults(int TargetSum, IList<int> Results)
        {
            Console.Out.WriteLine("Results have {0} items.", Results.Count);

            int Sum = 0;
            foreach (int Result in Results) {
                Sum += Result;
                Console.Out.WriteLine("Result: {0} Running total: {1}", Result, Sum);
            }
            Console.Out.WriteLine();
            Console.Out.WriteLine("Result = {0}", (Sum == TargetSum ? "SUCCESS" : "FAIL"));
        }
    }

    internal class AddUpWorker {

        Random RGenerator = new Random();

        public IList<int> AddUp(int MinDigit, int MaxDigit, int ItemsToSum, int TargetSum) {

            Console.Out.WriteLine("AddUp called to sum {0} items to get {1}", ItemsToSum, TargetSum);
            if (ItemsToSum > 3) {

                int LeftItemsToSum = ItemsToSum/2;
                int RightItemsToSum = ItemsToSum - LeftItemsToSum;

                int LeftTargetSum = TargetSum/2;
                int RightTargetSum = TargetSum - LeftTargetSum;


                IList<int> LeftList = AddUp(MinDigit, MaxDigit, LeftItemsToSum, LeftTargetSum);
                IList<int> RightList = AddUp(MinDigit, MaxDigit, RightItemsToSum, RightTargetSum);

                List<int> Results = new List<int>();
                Results.AddRange(LeftList);
                Results.AddRange(RightList);
                return Results;
            }

            // 3 or less

            int MinSumWeCanAchieve = ItemsToSum*MinDigit;
            int MaxSumWeCanAchieve = ItemsToSum*MaxDigit;


            if (TargetSum < MinSumWeCanAchieve)
                throw new ApplicationException("We added up too fast");

            if (TargetSum > MaxSumWeCanAchieve)
                throw new ApplicationException("We added up too slow");

            //Now we know we can achieve the result -- but it may not be too efficient...

            int[] TrialNumbers = new int[ItemsToSum];
            int MaxIteration = 100000;
            int IterationPrintInterval = 1000;
            int TrialSum;
            bool PrintIteration;

            for (int Iteration = 1; Iteration <= MaxIteration; ++Iteration) {

                PrintIteration = ((Iteration % IterationPrintInterval) == 0);

                if (PrintIteration)
                    Console.Out.WriteLine("Iteration {0} attempting to sum {1} numbers to {2}",
                        Iteration, ItemsToSum, TargetSum);

                TrialSum = 0;
                for (int j=0; j < ItemsToSum; ++j) {
                    TrialNumbers[j] = RGenerator.Next(MinDigit, MaxDigit + 1);
                    TrialSum += TrialNumbers[j];
                }
                if (PrintIteration)
                    ShowArray(string.Format("Iteration: {0}", Iteration), TrialNumbers);

                if (TrialSum == TargetSum) {    //Yay
                    ShowArray(string.Format("Success in {0} iterations: ", Iteration), TrialNumbers);
                    return new List<int>(TrialNumbers);
                }
                //try again....
            }

            throw new ApplicationException(string.Format("Maximum of {0} trials exceeded", MaxIteration));
        }

        private void ShowArray(string Prefix, int[] numbers)
        {
            for (int i = 0; i < numbers.Length; ++i) {
                if (i == 0)
                    Console.Write("{0} {1}", Prefix, numbers[i]);
                else
                    Console.Write(", {0}", numbers[i]);
            }
            Console.WriteLine();
        }
    }
}

AddUp called to sum 30 items to get 150
AddUp called to sum 15 items to get 75
AddUp called to sum 7 items to get 37
AddUp called to sum 3 items to get 18
Success in 10 iterations:  7, 2, 9
AddUp called to sum 4 items to get 19
AddUp called to sum 2 items to get 9
Success in 12 iterations:  5, 4
AddUp called to sum 2 items to get 10
Success in 2 iterations:  1, 9
AddUp called to sum 8 items to get 38
AddUp called to sum 4 items to get 19
AddUp called to sum 2 items to get 9
Success in 11 iterations:  4, 5
AddUp called to sum 2 items to get 10
Success in 6 iterations:  8, 2
AddUp called to sum 4 items to get 19
AddUp called to sum 2 items to get 9
Success in 3 iterations:  8, 1
AddUp called to sum 2 items to get 10
Success in 1 iterations:  4, 6
AddUp called to sum 15 items to get 75
AddUp called to sum 7 items to get 37
AddUp called to sum 3 items to get 18
Success in 3 iterations:  4, 6, 8
AddUp called to sum 4 items to get 19
AddUp called to sum 2 items to get 9
Success in 17 iterations:  3, 6
AddUp called to sum 2 items to get 10
Success in 24 iterations:  1, 9
AddUp called to sum 8 items to get 38
AddUp called to sum 4 items to get 19
AddUp called to sum 2 items to get 9
Success in 3 iterations:  2, 7
AddUp called to sum 2 items to get 10
Success in 3 iterations:  1, 9
AddUp called to sum 4 items to get 19
AddUp called to sum 2 items to get 9
Success in 4 iterations:  5, 4
AddUp called to sum 2 items to get 10
Success in 2 iterations:  9, 1
Results have 30 items.
Result: 7 Running total: 7
Result: 2 Running total: 9
Result: 9 Running total: 18
Result: 5 Running total: 23
Result: 4 Running total: 27
Result: 1 Running total: 28
Result: 9 Running total: 37
Result: 4 Running total: 41
Result: 5 Running total: 46
Result: 8 Running total: 54
Result: 2 Running total: 56
Result: 8 Running total: 64
Result: 1 Running total: 65
Result: 4 Running total: 69
Result: 6 Running total: 75
Result: 4 Running total: 79
Result: 6 Running total: 85
Result: 8 Running total: 93
Result: 3 Running total: 96
Result: 6 Running total: 102
Result: 1 Running total: 103
Result: 9 Running total: 112
Result: 2 Running total: 114
Result: 7 Running total: 121
Result: 1 Running total: 122
Result: 9 Running total: 131
Result: 5 Running total: 136
Result: 4 Running total: 140
Result: 9 Running total: 149
Result: 1 Running total: 150

Result = SUCCESS
ответил Howard Pinsley 24 Jam1000000amSat, 24 Jan 2009 07:01:47 +030009 2009, 07:01:47
0

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

Основываясь на идеях в этом посте, я предложил два возможных решения.

Первый метод:

  1. Определите наименьшее целочисленное значение, которое можно повторить, чтобы сложить число рядом с желаемой суммой. По сути, просто делите целочисленное деление.
  2. Инициализируйте массив со всеми значениями, равными числу, найденному на шаге 1.
  3. Если есть остаток (обычно он будет), случайным образом добавьте его к элементам в массиве и уменьшайте остаток до тех пор, пока остаток не станет равным 0. На данный момент у нас есть массив, который будет равен желаемому итогу, но он быть очень неслучайным.
  4. Для ряда итераций случайным образом складывайте и вычитайте из двух мест в массиве. Пример: добавьте 1 к позиции 0 и вычтите 1 из позиции 4. При этом выполните проверку границ (все числа должны быть не менее 0, а все числа не должны превышать верхнюю границу).

Второй метод намного проще, но приводит к менее случайному распределению:

  1. Инициализируйте массив из 0 желаемой длины.
  2. Выберите случайный индекс в массиве и добавьте 1. Если значение этого индекса превысит верхнюю границу, проигнорируйте его и выберите другой индекс.
  3. Повторите шаг 2 количество раз, указанное желаемым итогом.

Вот код:

public static int[] getRandomsWithTotalA(int desiredTotal, int desiredNumbers, int upperBound)
{
    Random r = new Random();

    // Is this even a possible feat?
    if (desiredNumbers * upperBound < desiredTotal) throw new ArgumentException("This is not possible!", "desiredTotal");

    // Start by figuring out the closest number we can get to by repeating the initial number.
    int lowestRepeating = desiredTotal / desiredNumbers;

    // Determine the remainder
    int lowestRepeatingRemainder = desiredTotal % desiredNumbers;

    // Initialize and populate an array of numbers with the lowest repeater.
    int[] results = Enumerable.Repeat(lowestRepeating, desiredNumbers).ToArray();

    // We will perform (n*desiredTotal) shuffles.
    int shuffles = (desiredTotal * desiredNumbers);

    while (shuffles > 0)
    {
        int a = r.Next(desiredNumbers);
        int b= r.Next(desiredNumbers);
        if (a==b) continue; // do nothing if they're equal - try again.

        // Test bounds.
        if (results[a]+1>upperBound) continue;
        if (results[b]-1<0) continue;

        // Add one to the first item.
        results[a]++;

        // Do we still have a remainder left? If so, add one but don't subtract from
        // somewhere else.
        if (lowestRepeatingRemainder>0)
        {
            lowestRepeatingRemainder--;
            continue;
        }
        // Otherwise subtract from another place.
        results[b]--;
        // decrement shuffles
        shuffles--;
    }

    return results;
}

public static int[] getRandomsWithTotalB(int desiredTotal, int desiredNumbers, int upperBound)
{
    Random r = new Random();

    // Is this even a possible feat?
    if (desiredNumbers * upperBound < desiredTotal) throw new ArgumentException("This is not possible!", "desiredTotal");

    // Initialize and populate an array of numbers with the lowest repeater.
    int[] results = new int[desiredNumbers];

    while (desiredTotal > 0)
    {
        int a = r.Next(desiredNumbers);

        // Test bounds.
        if (results[a] + 1 > upperBound) continue;

        // Add one to the first item.
        results[a]++;

        desiredTotal--;
    }

    return results;
}

Пример прогона:

static void Main(string[] args)
{
    foreach (int i in getRandomsWithTotalA(200, 30, 9))
    {
        Console.Write("{0}, ", i);
    }
    Console.WriteLine("\n");
    foreach (int i in getRandomsWithTotalB(200, 30, 9))
    {
        Console.Write("{0}, ", i);
    }
}

3, 8, 7, 5, 9, 9, 8, 9, 9, 6, 8, 7, 4, 8, 7, 7, 8, 9, 2, 7, 9, 5, 8, 1, 4, 5, 4, 8, 9, 7,

6, 8, 5, 7, 6, 9, 9, 8, 5, 4, 4, 6, 7, 7, 8, 4, 9, 6, 6, 5, 8, 9, 9, 6, 6, 8, 7, 4, 7, 7, 

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

Я чувствую, что возможно улучшить хотя бы первый метод, введя некоторую форму смещения в выбор индекса, или, возможно, рандомизировать то, сколько мы добавляем и вычитаем (не всегда 1), или рандомизировать, мы на самом деле делаем сложение /вычитание или нет. Кажется, простое изменение количества итераций меняет распределение, но через некоторое время мы начинаем отдавать предпочтение внешним границам. (Возможно, невозможно получить действительно равномерное распределение!)

В любом случае, вы идете ... Хорошее место для начала, по крайней мере.

ответил fdmillion 20 MaramFri, 20 Mar 2015 04:01:05 +03002015-03-20T04:01:05+03:0004 2015, 04:01:05
0
public static List<int> getNumbers(int n)
    {
        Random random = new Random(DateTime.Now.Millisecond);
        List<int> obtainedNumbers = new List<int>(); 
        do
        {
            obtainedNumbers.Add(random.Next(1, 9));
        }
        while (n - obtainedNumbers.Sum() > 0);
        return obtainedNumbers;
    }

Код JaredPar нравится мне, но он медленный, это все равно, что бросить монетку и надеяться получить значение n. Хорошие фрагменты кода

ответил Rulas 23 Jam1000000amFri, 23 Jan 2009 09:36:29 +030009 2009, 09:36:29

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132