开发者

How to select a random number in a range based on date?

I have a list of hundreds of Sector开发者_开发百科 types with ID values that range from 1..999. The user wants to see a different random Sector displayed on the web site every day.

One way to solve this is to store the randomly selected Sector's ID for the day, and use that, and then update that field with a new Sector Id the next day. But that's a bit messy, because it means I need to store an arbitrary value somewhere in the database... (or alternatively the Application state or something)

I was also thinking that I could take the list of 1..999 and use some Random algorythm to select a random number based on the date, so as long as the date is the same as the last time the random number was selected, the same number will come out.

But I'm not sure how to implement this, so I'm looking for suggestions?

Also, given the size of the range (999), and the number of available days in a year (365), would this mean that the algorythm would always miss certain Sectors because their ID doesn't map to however the Random number selection process selects the Sector ID? Is there any way around this?


You can use the date as seed for the Random class:

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

Note that the day is calculated from a fixed start date instead of DateTime.DayOfYear, so it will not restart each year and only use 365 of the values.


Do you really want a random value, or do you just want to display a different Sector every day? Random gives the possibility that the same Sector information will be displayed two (or possibly more) days in a row. It's also quite likely that over a 365 day period, you will get several duplicates. Using random selection from a list of 999 items, it's highly *un*likely that you'll get 365 non-duplicated numbers in 365 tries.

Is there some reason you have to start over every year? Why not set some date (say, January 1, 2011) as your "epoch" date. Then, to pick an item, simply subtract that date from the current date to get the number of days, divide by 999 and take the remainder, giving you the index. That is:

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

At this point, index is a number in the range 0..998. You can then use that number to index into your Sector IDs. Either index directly (so Jan 1 2011 will get the first sector ID, Jan 2 will get the second, etc.), or do some kind of calculation on the index to "randomize" it.


Answering your second question on combinatorics:

You have 999 numbers and 365 days. You can select one random number each day, which means in no case can you show more than 365 (distinct) numbers. Ofcoure some numbers might repeat as well. You have to devise logic based on how you want to represent.

It is indeed desirable that your random object must persist for 365 days in that case.


You can use the Cache class and expire the content at midnight. When the cache entry doesn't exist, create a new one with a random value, expiring at midnight...

For the random value, use System.Random - no need to reinvent the wheel here.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜