一个任务调度问题

原创作品 转载请注明出处http://blog.csdn.net/always2015/article/details/46531245

一、问题描述

在单处理器上具有期限和惩罚的单位时间任务调度问题

(1)实现这个问题的贪心算法
(2)将每个Wi替换为max{W1,W2,W3,…,Wn}-Wi,运行算法比较结果.

二、 算法原理:

考虑一个给定的调度. 我们说一个任务调度迟了, 也就是说它在规定的时间之后完成; 否则, 这个任务在该调度中是早的. 一个任意的调度总可以安排成早任务优先的形式, 其中早的任务总是在迟的任务之前。为了搞清这一点, 请注意如果某个早任务 a(i)跟在某个迟任务 a(j)之后,就可以交换 a(i)和 a(j)的位置, 并不影响 a(i)是早的 a(j)是迟的状态。
类似的,任意一个调度可以安排成一个规范形式 , 其中早的任务先于迟的任务 , 且按期限单调递增顺序对早任务进行调度。 为了做到这一点, 将调度安排成早任务优先形式。 然而, 只要在该调度中有两个分别完成于时间 k 和 k+1 的早任务 a(i)和 a(j) 使得 d(j)小于d(i), 就交换 a(i)和 a(j)的位置. 因为在交换前任务 j 是早的, k+1小于等于d(j) . 所以 k+1小于d(i) , 则 a(i)在交换之后任 然是早的. 任务 a(j) 被已到了调度中的更前位置,故它在交换后任然是早的.

如此, 寻找最优调度问题就成为找一个由最优调度中早的任务构成的集合 A 的问题. 一 旦 A 被确定后, 就可按期限的单调递增顺序列出 A 中的所有元素,从而给出实际的调度, 然后 按任意顺序列出迟的任务(S-A), 就可以产生出最优调度的一个规范次序. 称一个任务的集合 A 是独立的, 如果存在关于 A 中任务的一个调度, 使得没有一个任务 是迟的. 显然, 某一调度中早任务的集合就构成一个独立的任务集。

任务调度一般有两种方法:
首先我们知道一个任务包含两个信息:截止时间di,任务惩罚wi.考虑确定一个任务集A是否独立的问题。对于t=0,1,2,3,…..n,设Nt(A)表示A中期限为t或者更早的任务的个数。注意:对于任意的集合A,N0(A)=0.

1、解法一:

将wi按照递减的顺序排好序,然后逐次将任务添加至Nt(A)中,每次添加一个元素后进行计算,计算方法:

这里写图片描述这里写图片描述

2、解法二

这里写图片描述

实验数据
本实验采用对7个随机任务进行调度,显示加入最早任务的队列,显示最小的惩罚
运行结果如图:
一个任务调度问题_第1张图片

三、代码分析:
本实验的代码稍微有点长,所以我将整个工程文件放在这里,希望大家多多支持:
http://download.csdn.net/detail/always2015/8814745

下面只针对我的部分代码进行分析:
首先来看一下调度算法,我使用的是第二种解法,对代码的解析在注释里已经全部给出,这里就不多说啦。

/*调度的算法:
  设置刚开始有n+1个时间空位a[n+1](其实a[0]是用不上的)都是空的,
  然后按照罚款的单调递减的循序对各个子任务进行贪心选择,再考虑任务i时,
  如果a中的di位置或前于第di(di是第i个任务截止时间)的位置仍有空位,则将任务i放到与空位
  a[di]最近的空位,如果不存在,则表示该任务放弃。
*/
void sched(Task* input_task,int *sum_weight,int total_weight,int *A)
{
    cout<<"选入的任务有:";

    for(int j=0;jint k=input_task[j].d;
        while(k>0)
        {
            if(A[k]==0)
            {
                A[k]=input_task[j].d;
                //输出放入的任务
                cout<<"a"<" ";
                //记录加入的惩罚
                *sum_weight+=input_task[j].w;
                break;
            }

            --k;
        }
    }
    cout<<"最小惩罚为:"<

工程里面的代码都有详细的注释。希望能帮助到大家。

你可能感兴趣的:(【算法导论】)