任务调度问题实验

一、问题描述

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

二、算法原理

  任务调度问题就是给定一个有穷单位时间任务的集合S,集合S中的每个任务都有一个截止期限di和超时惩罚wi,需要找出集合S的一个调度,使得因任务误期所导致的总惩罚最小,这个调度也称为S的一个最优调度。

  实现任务的最优调度主要就是利用贪心算法中拟阵的思想。如果S是一个带期限的单位时间任务的集合,且I是所有独立的任务集构成的结合,则对应的系统M=(S,I)是一个拟阵。利用拟阵解决任务调度问题的算法原理主要就是将最小化迟任务的惩罚之和问题转化为最大化早任务的惩罚之和的问题,也就是说在任务调度的时候优先选择当前任务序列中惩罚最大的任务。这里,假设集合A存放任务的一个调度。如果存在关于A中任务的一个调度,使得没有一个任务是迟的,称任务集合A是独立的。实现该问题的贪心算法如下:

  A <- Ø

  Sort S[M] into monotonically decreasing order by w

  for each x∈S[M]

       do if AU{x} ∈ I[M]

            then A <- AU{x}

  初始时A为空集,然后对S中的所有任务按惩罚大小降序排序,然后进入循环。循环的过程中依次访问S的中所有任务,然后进行独立性检查,如果当前任务x加入集合A之后A依然是独立的,则将A置为AU{x},否则检查下一个任务直到扫描结束,最后所得到的集合A即是一个最优子集,然后进行相应的调整得到最后的输出。

三、实验数据

  (1)任务调度问题的输入:

    a)    任务的数量n,即表示当前任务集合S={a1,a2,a3……an};

    b)   n个任务的期限d1,d2,d3……dn,每个任务的di满足1≤ di ≤n,且任

      务要求ai在di之前完成;

    c)    n个任务的权(惩罚)w1,w2,w3……wn。表示任务ai如果没在时间di

  之前完成,则导致惩罚wi,如果任务在期限之前完成,则没有惩罚; 同时在本实验中,还会将每个wi值替换为max{w1,w2,w3……wn}-wi,并运行算法进行第二次实验,然后比较两次实验所得结果。

  在本次实验中,n取值为7,每个任务的期限为4,2,4,3,1,4,6,对应的惩罚为70,60,50,40,30,20,10。

  (2)任务调度问题的输出:

    a)     贪心算法所选的任务以及放弃的任务,所选的任务即表示最终会在期限

      内完成的任务。放弃的任务表示最终会因误期而受到惩罚的任务。

    b)     最终的最优调度序列

    c)     最优调度所带来的总的惩罚数

四、实验截图

  

五、源代码

  

#include <stdio.h>
#include <stdlib.h>

void swap(int *x, int *y)
{
    int temp;
    temp = *x;
    *x = *y;
    *y = temp;
}
/*任务调度算法,满足拟阵性质,利用GREEDY贪心策略*/
/*期限序列d[], d1,d2……dn*/
/*惩罚序列w[], w1,w2……wn*/
/*任务个数n*/
void taskSchedule(int *d, int *w, int n)
{
    int i = 0;
    int j = 0;
    int k = 1;                           
    int s = 0;
    int t = 1;                                  
    int a[n+1];                                
    int b[n+1];                                
    int sn[n+1];                               
    int flag = 0;                             
    int count = 0;                           
    memset(a, 0, sizeof(a));
    memset(b, 0, sizeof(b));
    for(i = 0; i <= n; i++)
    {
        sn[i] = i;
    }

    for(i = 1; i < n; i++)
    {
        for(j = i + 1; j <= n; j++)
        {
            if(w[sn[i]] <= w[sn[j]])
            {
                swap(&sn[i], &sn[j]);
            }
        }
     }
     k = 1;

     for(i = 1; i <= n; i++)
     {

         flag = 0;
         a[k] = sn[i];
         for(j = 1; j <= k; j++)
         {
             count = 0;
             for(s = 1; s <= k; s++)
             {
                 if(d[a[s]] <= j) count++;
             }
             if(count > j)
             {
                 flag = 1;
                 break;
             }
         }
         if(flag == 1)
         {
             b[t] = sn[i];
             a[k] = 0;
             t++;
         }
         else
         {
             k++;
         }
     }

     if(b[t] == 0) t--;
     if(a[k] == 0) k--;

     printf("\n贪心算法选择了任务:\n");
     //printf("k==%d\n",k);
     for(i = 1; i <= k && i<=n; i++)
        printf("a%d  ",a[i]);
     printf("\n");
     printf("放弃了任务:\n");
     int w_sum = 0;
     //printf("t==%d\n",t);
     for(i = 1; i <= t  && i <= n ; i++)
     {
         printf("a%d  ",b[i]);
         w_sum = w_sum + w[b[i]];
     }

     int temp = 0;
     for(i = 2; i <= k; i++)
     {
         temp = a[i];
         s = i - 1;
         while(s < n && s >= 1 && d[temp] < d[a[s]])
         {
             a[s+1] = a[s];
             s--;
         }
         a[s+1] = temp;
     }

     for(i = 1; i <= t; i++)
     {
         k++;
         a[k] = b[i];
     }
     printf("\n最终的最优调度为:\n");
     for(i = 1; i <= k && i <= n; i++)
        printf("a%d  ", a[i]);
     printf("\n总的惩罚数为:%d\n", w_sum);
}

int main()
{
    int n = 0;
    int i = 0;

    printf("请输入任务个数:\n");
    scanf("%d", &n);

    int *d = (int *) malloc ((n+1) * sizeof(int));
    printf("请输入每个任务的期限\n");
    d[0] = 0;
    for(i = 1; i < n+1; i++)
    {
        scanf("%d", &d[i]);
    }
    for(i = 1; i  < n+1; i++)
    {
        if(d[i] > n)
        {
            printf("\n任务a%d的期限非法,请重新输入:",i);
            scanf("%d", &d[i]);
        }
    }

    int *w = (int *) malloc ((n+1) * sizeof(int));
    printf("\n请输入每个任务的惩罚:\n");
    w[0] = 0;
    for(i = 1; i < n+1; i++)
    {
        scanf("%d", &w[i]);
    }
    taskSchedule(d, w, n);
    printf("\n\n使用max{w}-wi替换wi后的各任务惩罚为:\n");
    int max = 0;
    for(i = 1; i <= n; i++)
        if(w[i] > max)
            max = w[i];
    for(i = 1; i <= n; i++)
    {
        w[i] = max - w[i];
        printf("%d  ",w[i]);
    }
    printf("\n\n算法运行结果为:");
    taskSchedule(d, w, n);
    system("pause");
    return 0;
}

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
实验原理: 在独立任务调度问题中,每个任务都有一个执行时间和一个截止时间,任务之间没有任何依赖关系。任务调度的目标是在满足所有任务的截止时间的前提下,最大化已完成任务的数量。这是一个经典的NP完全问题,因此需要采用高效的算法来解决。 动态规划是一种重要的解决最优化问题算法,可以用于解决独立任务调度问题。动态规划算法的基本思想是将问题分解成一系列重叠的子问题,并通过求解问题的最优解来求解问题的最优解。 解题步骤: 1. 确定状态:在独立任务调度问题中,状态可以用一个二元组(i, t)来表示,其中i表示任务的编号,t表示当前时间。 2. 确定状态转移方程:根据题目中的约束条件和目标函数,设计状态转移方程,用于计算每个状态的最优解。 3. 初始化状态:将第一个任务的状态作为初始状态,即(i, 0),其中i为第一个任务的编号,时间为0。 4. 递推求解:利用状态转移方程,从初始状态开始逐步计算每个状态的最优解,直到达到最终状态,即(n, T),其中n为任务数量,T为所有任务的最大截止时间。 5. 回溯求解:根据递推计算所得的最优解,回溯求解出每个任务的最优调度方案。 以上是解决独立任务调度问题的动态规划算法的基本步骤。需要根据具体情况进行算法的设计和实现。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值