performance - 调度最优记录列表的算法

标签 performance algorithm language-agnostic scheduling

我正在寻找一种算法,用于为给定以下项目列表的记录设备生成最佳记录列表:

Image link here http://img692.imageshack.us/img692/7952/recordlist.png

目前的约束是:

  • 不得存在任何重叠。
  • 在计算速度和已解决的冲突之间进行折衷。

将来可能会添加更多选项:

  • 用户拥有多个录音设备的可能性。
  • 用户可以为他/她最喜欢的节目设置录制优先级(1 最高 - 3 最低)。

上下文如下:

  • 项目列表最长为 1 周。(当前时间 - 当前时间 + 1 周)
  • 平均项目列表大小为 100 项,最多 300 项。

另外我想知道是否有办法生成最优化的记录列表(发送记录的节目百分比最高) 在这种情况下,无论处理时间如何,我们都无法解决 100% 的冲突。

提前致谢。

最佳答案

class Recording
{
    public int ProgrammeId { get; set; }
    public string ProgrammeTitle { get; set; }
    public DateTime StartTime { get; set; }
    public DateTime EndTime { get; set; }
    public int ChannelId { get; set; }
    public string ChannelName { get; set; }
    public int Weight { get { return 1; } } // Constant weight
}

一种贪婪的方法是按start_time 递增的顺序考虑程序。如果某个程序与之前选择的程序兼容,请选择它:

public static IEnumerable<Recording> GreedySelection(IList<Recording> data)
{
    data = data
        .OrderBy(r => r.StartTime)
        .ThenBy(r => r.EndTime)
        .ToList();

    DateTime? lastEnd = null;
    foreach (var rec in data)
    {
        if (lastEnd == null || rec.StartTime >= lastEnd.Value)
        {
            yield return rec;
            lastEnd = rec.EndTime;
        }
    }
}

要获得最佳加权解决方案,您可以使用动态规划:

public static IEnumerable<Recording> WeightedSelection(IList<Recording> data)
{
    data = data
        .OrderBy(r => r.EndTime)
        .ThenBy(r => r.StartTime)
        .ToList();

    int count = data.Count;
    var lastCompatible = new int?[count];

    // Compute the closest program before in time, that is compatible.
    // This nested loop might be optimizable in some way.
    for (int i = 0; i < count; i++)
    {
        for (int j = i - 1; j >= 0; j--)
        {
            if (data[j].EndTime <= data[i].StartTime)
            {
                lastCompatible[i] = j;
                break; // inner loop
            }
        }
    }

    // Dynamic programming to calculate the best path
    var optimalWeight = new int[count];
    var cameFrom = new int?[count];
    for (int i = 0; i < count; i++)
    {
        int weightWithItem = data[i].Weight;
        if (lastCompatible[i] != null)
        {
            weightWithItem += optimalWeight[lastCompatible[i].Value];
        }

        int weightWithoutItem = 0;
        if (i > 0) weightWithoutItem = optimalWeight[i-1];

        if (weightWithItem < weightWithoutItem)
        {
            optimalWeight[i] = weightWithoutItem;
            cameFrom[i] = i - 1;
        }
        else
        {
            optimalWeight[i] = weightWithItem;
            cameFrom[i] = lastCompatible[i];
        }
    }

    // This will give the programs in reverse order.
    for (int? i = count - 1; i != null; i = cameFrom[i.Value])
    {
        yield return data[i.Value];
    }
}

并不是说这个版本加入了权重,而是试图最大化权重和。如果所有权重都设置为一 (1),则两种算法的结果大小将相同,因为大小等于权重。

贪心的结果:

ProgrammeTitle           StartTime         EndTime
Star Trek                2012-09-03 02:05  2012-09-03 03:05
Everybody Loves Raymond  2012-09-03 06:00  2012-09-03 07:00
CSI                      2012-09-03 07:00  2012-09-03 08:00
Mythbusters              2012-09-03 08:00  2012-09-03 09:00
CSI                      2012-09-03 10:00  2012-09-03 11:00
Mythbusters              2012-09-03 11:00  2012-09-03 12:00
Star Trek                2012-09-04 02:05  2012-09-04 03:05
Everybody Loves Raymond  2012-09-04 06:00  2012-09-04 07:00
CSI                      2012-09-04 07:00  2012-09-04 08:00
Mythbusters              2012-09-04 08:00  2012-09-04 09:00
CSI                      2012-09-04 10:00  2012-09-04 11:00
Mythbusters              2012-09-04 11:00  2012-09-04 12:00

动态结果(排序):

ProgrammeTitle           StartTime         EndTime
Everybody Loves Raymond  2012-09-03 03:00  2012-09-03 04:00
Everybody Loves Raymond  2012-09-03 06:00  2012-09-03 07:00
CSI                      2012-09-03 07:00  2012-09-03 08:00
CSI                      2012-09-03 08:30  2012-09-03 09:30
CSI                      2012-09-03 10:00  2012-09-03 11:00
Star Trek                2012-09-03 11:05  2012-09-03 12:05
Everybody Loves Raymond  2012-09-04 03:00  2012-09-04 04:00
Everybody Loves Raymond  2012-09-04 06:00  2012-09-04 07:00
CSI                      2012-09-04 07:00  2012-09-04 08:00
CSI                      2012-09-04 08:30  2012-09-04 09:30
CSI                      2012-09-04 10:00  2012-09-04 11:00
Star Trek                2012-09-04 11:05  2012-09-04 12:05

算法基于此文档:

关于performance - 调度最优记录列表的算法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12244807/

相关文章:

python - 在 python 中使用大型字典? (性能和崩溃)

python - 倒下的多米诺骨牌,调试

language-agnostic - 语言何时消亡?

algorithm - 无除法快速平均

python - python 中的 OpenGL 因 glCheckError 调用而变慢

mysql - 优化大表中的 MySQL SELECT

algorithm - LZW算法可变长度解码程序的问题

string - 基于有序的字符串对生成直观的唯一字符串?

language-agnostic - 创建在历史日期不起作用的软件是一种不好的做法吗?

Android 在本地存储数据以供离线访问