abdul subhan mohammed Ответов: 3

Как выбрать случайным образом, но одинаково все элементы в C#


Дорогие Все,

У меня есть приложение Windows для тестирования. Где я должен выбирать вопросы(элементы) случайным образом, и он выбирает случайным образом, но не все вопросы.

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

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

Например, если у меня есть 100 предметов и я выбрал предметы случайным образом 10 раз, значит, все предметы должны быть выбраны одинаково.

Что я уже пробовал:

List<QuestionInfo> allQuestions = QuestionController.Instance.GetByOutcome(outcome.ID).ToList();
                    List<QuestionInfo> outcomeQuestions = allQuestions.Cast<QuestionInfo>().ToList();

                    int outcomeQuestionNumber = (outcome.PercentageOfQuestions ?? 0) * module.TotalQuestions / 100;
                    if (outcomeQuestionNumber == 0)
                        notConsideredOutcomeList.Add(outcome.ID);

                    if (outcomeQuestions.Count < outcomeQuestionNumber)
                        throw new Exception("Something wrong in generating questions. Not enough questions in Outcome :" + outcome.NameEN);

                    List<QuestionInfo> easyQuestions = outcomeQuestions.FindAll(item => item.DifficultyLevel.DifficultyLevel == DifficultyLevel.Easy).ToList();
                    List<QuestionInfo> mediumQuestions = outcomeQuestions.FindAll(item => item.DifficultyLevel.DifficultyLevel == DifficultyLevel.Medium).ToList();
                    List<QuestionInfo> hardQuestions = outcomeQuestions.FindAll(item => item.DifficultyLevel.DifficultyLevel == DifficultyLevel.Hard).ToList();

                    int easyQuestionsNumber = outcomeQuestionNumber * module.ModuleQuestionDifficultyLevel.FindAll(item => item.DifficultyLevel == DifficultyLevel.Easy).FirstOrDefault().PercentageOfQuestions / 100;
                    int mediumQuestionsNumber = outcomeQuestionNumber * module.ModuleQuestionDifficultyLevel.FindAll(item => item.DifficultyLevel == DifficultyLevel.Medium).FirstOrDefault().PercentageOfQuestions / 100;
                    int hardQuestionsNumber = outcomeQuestionNumber * module.ModuleQuestionDifficultyLevel.FindAll(item => item.DifficultyLevel == DifficultyLevel.Hard).FirstOrDefault().PercentageOfQuestions / 100;

                    if (easyQuestions.Count < easyQuestionsNumber)
                        throw new Exception("Something wrong in generating questions. Not enough easy questions in Outcome :" + outcome.NameEN);

                    if (mediumQuestions.Count < mediumQuestionsNumber)
                        throw new Exception("Something wrong in generating questions. Not enough medium questions in Outcome :" + outcome.NameEN);

                    if (hardQuestions.Count < hardQuestionsNumber)
                        throw new Exception("Something wrong in generating questions. Not enough hard questions in Outcome :" + outcome.NameEN);

                    for (int count = 0; count < easyQuestionsNumber; count++)
                    {
                        int randomIndex = new Random().Next(0, easyQuestions.Count - 1);
                        questions.Add(easyQuestions[randomIndex]);
                        easyQuestions.Remove(easyQuestions[randomIndex]);
                    }

                    for (int count = 0; count < mediumQuestionsNumber; count++)
                    {
                        int randomIndex = new Random().Next(0, mediumQuestions.Count - 1);
                        questions.Add(mediumQuestions[randomIndex]);
                        mediumQuestions.Remove(mediumQuestions[randomIndex]);
                    }

                    for (int count = 0; count < hardQuestionsNumber; count++)
                    {
                        int randomIndex = new Random().Next(0, hardQuestions.Count - 1);
                        questions.Add(hardQuestions[randomIndex]);
                        hardQuestions.Remove(hardQuestions[randomIndex]);
                    }

                    processedQuestions.AddRange(easyQuestions);
                    processedQuestions.AddRange(mediumQuestions);
                    processedQuestions.AddRange(hardQuestions);


Кто-нибудь может пожалуйста помочь мне.

Спасибо

3 Ответов

Рейтинг:
25

OriginalGriff

Вся идея случайных чисел состоит в том, что они не "выбирают одинаково", поскольку это заставляет смещение на поток чисел. Когда вы читаете случайные числа от 0 до 9, шансы 5 на первое число такие же, как и шансы 5 на второе число независимо от значения, выбранного в качестве первого числа. То же самое относится и к третьему, четвертому, пятому ... предыдущие значения не имеют значения, они не влияют на следующее число.

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

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


Maciej Los

5ed!

Рейтинг:
20

Thomas Daniels

Я не совсем понимаю, что вы подразумеваете под "одинаково".

Если вы имеете в виду, что хотите равномерного распределения случайных величин (то есть каждое значение имеет одинаковый шанс произойти):

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

Если вы имеете в виду, что хотите получить все значения в определенной коллекции, но в случайном порядке:


  1. Создайте список индексов, например:
    List<int> indices = Enumerable.Range(0, 100).ToList(); // 100 is the count, replace it by the value you need
  2. Перетасуйте список[^].
  3. Если вам нужно новое значение из вашей коллекции, получите его на основе следующего индекса в indices (так что следите за тем, где вы находитесь в этом списке).


Maciej Los

5ed!

Thomas Daniels

Спасибо!

Рейтинг:
2

Patrice T

Цитата:
Я хочу выбирать элементы случайным образом, но они должны быть выбраны одинаково друг с другом.

эти две идеи являются взаимоисключающими, вы не можете иметь обе одновременно. Случайные подразумевают не равные.
Ваш вопрос попадает в категорию "перетасовка колоды карт" и запоминается между сеансами.
Перетасовка - Википедия[^]
В основном, с колодой карт:
Нарисуйте случайным образом карту на столе 52, а затем замените ее картой 52.
Нарисуйте случайным образом карту в первых 51 картах, а затем поменяйте ее местами с картой 51.
Нарисуйте случайным образом карту в первых 50 картах, а затем поменяйте ее местами с картой 50.
и повторяйте до последней карты.
Затем сохраните порядок карт, чтобы отслеживать их между сеансами.