【问题标题】:What's the complexity of this (non-preemptive) scheduling algorithm?这种(非抢占式)调度算法的复杂性是多少?
【发布时间】:2018-02-04 16:23:38
【问题描述】:

我有一个关于作业(非抢占式)调度算法的算法复杂性的问题,特别是用于获得 1||sum(Uj) 问题(仅限一台机器)的最优解,其中 Uj 是单一惩罚(即:如果作业在截止日期前终止,则等于 0,如果晚终止,则等于 1。

我需要最小化单一惩罚的总和(即:迟到工作的总和)。给出了作业处理时间,以及它们的截止日期,并且没有发布时间(因此,所有作业在时间 t=0 时同步发布)。 该算法的工作原理如下:

1- 根据最早到期日对所有作业进行排序

2- 确定第一个迟到的工作 Jj。如果没有迟到的作业,请转到第 4 步。

3- 确定 Jj 与其前任之间处理时间最长的作业。删除该作业并返回第 2 步,考虑没有删除作业的新序列

4- 最佳序列由以下公式给出:当前序列 [后跟] 在步骤 3 中以任意顺序移除的作业子集。

我被要求计算这个算法的最坏情况 O(...) 复杂度,在一般和良好实现的情况下(所以,我现在必须尝试猜测“无实现”的复杂度,给定所有算法步骤)。

我认为第 1 步需要 O(nlogn),因为(使用 QuickSort 或 MergeSort)这只是一个排序问题。

但是,步骤 2-3-4 呢?如果我们尝试在 C/C++ 中实现这个最终复杂度可能是 O(n^2) 是否正确?还是由于 EDD“优化”了后续搜索,它是 O(n*logn)?确定其复杂性的可能证据是什么?

非常感谢。

【问题讨论】:

    标签: algorithm time-complexity complexity-theory scheduling


    【解决方案1】:

    在我看来,整个算法可以在O(n log n) 时间内完成。基本思想是摊销移除前辈的成本。每次移除前任,我们都会支付O(log n),最多有n移除。

    这里是细节。在第 1 步之后,您只需对作业进行一次遍历,因为从序列中删除作业只会使作业更快完成。每次考虑序列中的作业时,都会反复删除其最大的前任,直到它按时完成。请注意,“删除最大的前任”操作的总数最多为n,因为每个作业最多将被删除一次。 [注:我认为这里需要注意,因为“前任”应该是一个包容性的概念。也就是说,当考虑一个特定的工作 j 时,如果 j 比任何以前的工作都大,那么你应该删除 j 并继续下一个工作。]

    如何高效地实现“移除最大前驱”操作?您可以通过维护(当您从左到右遍历作业时)按作业规模对前辈进行排序来做到这一点。这种排序可以用例如二叉搜索树来实现,它允许在O(log n) 中插入和删除。每次您开始考虑一份工作时,您都会将其插入树中,并支付@​​987654326@。删除最大的前任只是从树中删除最大的作业。

    之前我们注意到最多会删除n,对应于树中最多删除n。因此,我们为删除支付了O(n log n) 的总成本。我们还为插入支付了O(n log n) 的总成本(每个作业恰好一个插入)。对所有数据进行排序的预处理步骤为O(n log n),因此所有步骤的总成本为O(n log n)

    这是一些伪代码:

    J = input sorted by earliest due date
    T = empty tree
    for each j in J, from left to right:
      insert j into T
      while j does not finish on time:
        j' = delete largest from T
        if j' == j:
          break to next job in J
    

    我遗漏的唯一细节是如何检查工作是否按时完成。但这非常简单,因为您可以在从树中插入和删除作业时简单地通过在计数器中添加和减去来跟踪“当前完成时间”。

    【讨论】:

      猜你喜欢
      • 2016-09-26
      • 1970-01-01
      • 2018-09-16
      • 2019-05-23
      • 1970-01-01
      • 2017-03-27
      • 1970-01-01
      • 2023-03-07
      相关资源
      最近更新 更多