Как выбрать случайное число в диапазоне на основе даты? - PullRequest
3 голосов
/ 22 февраля 2011

У меня есть список сотен типов секторов со значениями идентификаторов, которые находятся в диапазоне от 1,999. Пользователь хочет видеть разные случайные сектора отображаются на веб-сайте каждый день.

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

Я также подумал, что я мог бы взять список 1..999 и использовать некоторый Случайный алгоритм, чтобы выбрать случайное число на основе даты, при условии, что дата совпадает с прошлым разом, когда случайное число было выбран, тот же номер выйдет.

Но я не уверен, как это реализовать, поэтому я ищу предложения?

Кроме того, учитывая размер диапазона (999) и количество доступных дней в году (365), это будет означать, что алгоритм всегда будет пропускать определенные Секторы, поскольку их идентификатор не сопоставляется с Случайным процесс выбора номера выбирает Sector ID? Есть ли способ обойти это?

Ответы [ 4 ]

4 голосов
/ 22 февраля 2011

Вы можете использовать дату в качестве начального числа для класса Random:

int day = (DateTime.Today - new DateTime(2000,1,1)).TotalDays;
Random rnd = new Random(day);
int id = rnd.Next(1, 1000);

Обратите внимание, что день рассчитывается по фиксированной дате начала вместо DateTime.DayOfYear, поэтому он не будет перезапускаться каждый год и будет использовать только 365 значений.

3 голосов
/ 22 февраля 2011

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

Есть ли какая-то причина, по которой вы должны начинать каждый год? Почему бы не установить какую-то дату (скажем, 1 января 2011 года) в качестве даты "эпохи". Затем, чтобы выбрать элемент, просто вычтите эту дату из текущей даты, чтобы получить количество дней, разделите на 999 и возьмите остаток, давая вам индекс. То есть:

DateTime EpochDate = new DateTime(2011, 01, 01);
TimeSpan Elapsed = DateTime.Now.Date - EpochDate;
int index = Elapsed.Days % 999;

В этот момент index - это число в диапазоне 0..998. Затем вы можете использовать этот номер для индексации ваших идентификаторов секторов. Либо индексируйте напрямую (например, 1 января 2011 года получит идентификатор первого сектора, 2 января получит второй и т. Д.), Либо выполните какой-либо расчет индекса, чтобы «рандомизировать» его.

2 голосов
/ 22 февраля 2011

Отвечая на ваш второй вопрос по комбинаторике:

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

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

1 голос
/ 22 февраля 2011

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

Для случайного значения используйте System.Random - здесь не нужно заново изобретать колесо.

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