基于日期的加权随机选择

本文关键字:加权 随机 选择 日期 于日期 | 更新日期: 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以查看是否没有消息,但应该可以。