基于日期的加权随机选择
本文关键字:加权 随机 选择 日期 于日期 | 更新日期: 2023-09-27 18:28:07
我有一个现有的windows应用程序,它在设置的时间间隔在屏幕上显示消息。该消息是从SQL Server数据库中随机选择的,通过将消息标记为当前日期,确保每条消息在当天只显示一次。表格结构如下:
Id int
Text nvarchar
LastDateUsed datetime
我希望通过制定选择消息的逻辑来改进现有代码,这样最近使用的消息就不太可能被选中。
我现有的随机选择消息的代码如下:
IQueryable<Message> filteredMessages = db.Messages;
var currentDate = DateTime.Today;
IQueryable<int> filteredMessageIds = filteredMessages.Where(x => x.LastDateUsed < currentDate).Select(x => x.Id);
int filteredMessagesCount = filteredMessageIds.Count();
// Select one Id
int selectedId = filteredMessageIds.ToList()[SelectRandomIndex(filteredMessagesCount)];
// Display selected message
DisplayMessage(selectedId)
private static int SelectRandomIndex(int filteredMessagesCount)
{
Random rnd = new Random();
int selectedIndex = rnd.Next(1, filteredMessagesCount - 1);
return selectedIndex;
}
只要消息的数量和自上次显示以来的天数不太多,那么此代码就可以工作:
Random rnd = new Random();
int selectedId =
db
.Messages
.Where(x => x.LastDateUsed < DateTime.Today)
.Select(x => new { x.Id, x.LastDateUsed })
.ToArray()
.SelectMany(x =>
Enumerable.Repeat(x.Id, DateTime.Today.Subtract(x.LastDateUsed).Days))
.OrderBy(x => rnd.Next())
.Concat(new [] { -1 })
.First();
这段代码的主要部分是.SelectMany(...)
。它为每条消息重复Id
,重复次数为自上次使用消息以来的天数。因此,7天前最后一次使用的邮件被选中的几率是一天前使用的邮件的7倍。
OrderBy
有点浪费,您确实需要检查-1
以查看是否没有消息,但应该可以。