关于 作业调度算法 (FCSF)的学习笔记

关于 作业调度算法 (FCSF)的学习笔记

学习作业调度算法。

作业调度算法研究的是对于多个作业的时候,找寻最优解的方法,即如何使多项工作能有条理的完成

FCSF算法

FCSF算法即为First Come Serve First(先来先服务。

即根据不同作业到来的时间进行完成,不考虑完成作业的优先性和重要性,作业完成所需要的时间长短问题,每个作业的周转时间,或者是效率问题。同时当遇到开始时间相同的情况,以输入的顺序进行完成。

因此,FCSF算法是作业调度算法中书写难度&理解难度最低的,同时也是效率比较低。

输入

首先输入所需要完成的作业数量。

再分别输入每个作业的开始时间&运行时间

输出

输出每项作业的开始时间,运行时间,开始时间,结束时间,周转时间,带权周转时间

最后输出平均周转时间,平均带权周转时间

思路

1.在循环过程中,找到最早的程序到达时间。

具体代码

int GetNextTask(int now)
{
    int minx=100000,index=-1;
    for(int i=1; i<=tasknum; i++)
        if(!arrayTask[i].flag&&arrayTask[i].arrive<=now&&arrayTask[i].arrive<minx)
        {
            minx=arrayTask[i].arrive;//更新最早到达时间
            index=i;//更新最早更新的项目代码
        }
    return index;
}

2.找到到达时间最早的作业之后,计算该作业的各项数据。

void RunTask(int n)
{
    arrayTask[n].start  = nowtime;//更新任务开始时间
    arrayTask[n].endtime = nowtime + arrayTask[n].service;//计算任务结束时间
    arrayTask[n].runtime = arrayTask[n].endtime - arrayTask[n].arrive;//计算周转时间
    avgruntime += arrayTask[n].runtime;//记录总的周转时间,用于计算平均周转时间
    arrayTask[n].dqzztime = arrayTask[n].runtime / arrayTask[n].service;//计算加权周转时间
    avgdqzztime += arrayTask[n].dqzztime;//记录总的带权周转时间,用于计算平均带权周转时间
    arrayTask[n].flag=1;//标记该任务已经完成
}

3.依次输出每个作业的各项数据

总代码

#include<iostream>
#include<string>
#include<fstream>
#include<iomanip>

using namespace std;
const int MAXN = 100000;

int tasknum;//作业数量
int nowtime; //从第一个到达的作业时间开始
double avgruntime; //平均周转时间
double avgdqzztime; //平均带权周转时间
struct StruTask
{
    int id; //序号
    int flag=0;
    int arrive; //到达时间(输入)
    int service; //服务时间(输入)
    int start; //开始时间(设置)
    int endtime; //结束时间(设置)
    int runtime; //周转时间:endtime - arrive
    double dqzztime; //带权周转时间runtime/service
}arrayTask[MAXN];
void GetTask()
{
    cout<<"请输入任务数:"<<endl;
    cin>>tasknum;
    if(tasknum <= 0) return;
    for(int i = 1; i <= tasknum; ++i)
    {
        cout<<"请输入第"<<i<<"个任务的到达时间和服务时间: ";
        arrayTask[i].id = i;
        cin>>arrayTask[i].arrive;
        cin>>arrayTask[i].service;
    }
}

int GetNextTask(int now)
{
    int minx=100000,index=-1;
    for(int i=1; i<=tasknum; i++)
        if(!arrayTask[i].flag&&arrayTask[i].arrive<=now&&arrayTask[i].arrive<minx)
        {
            minx=arrayTask[i].arrive;
            index=i;
        }
    return index;
}


void RunTask(int n)
{
    arrayTask[n].start  = nowtime;
    arrayTask[n].endtime = nowtime + arrayTask[n].service;
    arrayTask[n].runtime = arrayTask[n].endtime - arrayTask[n].arrive;
    avgruntime += arrayTask[n].runtime;
    arrayTask[n].dqzztime = arrayTask[n].runtime / arrayTask[n].service;
    avgdqzztime += arrayTask[n].dqzztime;
    arrayTask[n].flag=1;
}

void PrintResult(int n)
{
    cout<<" 序号: "<<arrayTask[n].id
        <<" 到达时间: "<<arrayTask[n].arrive<<" 服务时间: "<<arrayTask[n].service;
    cout<<" 开始时间: "<<arrayTask[n].start<<" 结束时间: "<<arrayTask[n].endtime;
    cout<<" 周转时间: "<<arrayTask[n].runtime<<" 带权周转时间: "<<arrayTask[n].dqzztime<<endl;
}

int main()
{
    GetTask();
    nowtime = 0;
    avgruntime = 0;
    avgdqzztime = 0;
    for(int i = 1; i <= tasknum; ++i)
    {
        int id = GetNextTask(nowtime);
        RunTask(id);
        PrintResult(id);
        nowtime=arrayTask[id].endtime;
    }
    avgruntime /= tasknum;
    avgdqzztime /= tasknum;
    cout<<" 平均周转时间: "<<avgruntime<<" 平均带权周转时间: "<<avgdqzztime<<endl;
    return 0;
}

补充

1.周转时间=运行时间+等待时间

2.带权周转时间=运行时间/周转时间

因此带权周转时间越接近1,效率越佳。

3.代码输出的顺序等同于作业完成顺序,如果想要以输入顺序需要再写一个循环程序。即把PrintResult函数放在循环之外,在使用一次for循环,即可按输入顺序输出

再补

C语言重写FCSF算法

#include <stdio.h>

#define MAXN 100000

struct StruTask
{
    int id;           // 序号
    int flag;         // 标记是否已执行
    int arrive;       // 到达时间(输入)
    int service;      // 服务时间(输入)
    int start;        // 开始时间(设置)
    int endtime;      // 结束时间(设置)
    int runtime;      // 周转时间: endtime - arrive
    double dqzztime;  // 带权周转时间: runtime / service
};

int tasknum;           // 作业数量
int nowtime;           // 从第一个到达的作业时间开始
double avgruntime;     // 平均周转时间
double avgdqzztime;    // 平均带权周转时间
struct StruTask arrayTask[MAXN];

void GetTask()
{
    printf("请输入任务数:\n");
    scanf("%d", &tasknum);
    
    if (tasknum <= 0)
        return;
    
    for (int i = 1; i <= tasknum; ++i)
    {
        printf("请输入第%d个任务的到达时间和服务时间: ", i);
        arrayTask[i].id = i;
        scanf("%d %d", &arrayTask[i].arrive, &arrayTask[i].service);
    }
}

int GetNextTask(int now)
{
    int minx = 100000;
    int index = -1;
    
    for (int i = 1; i <= tasknum; i++)
    {
        if (!arrayTask[i].flag && arrayTask[i].arrive <= now && arrayTask[i].arrive < minx)
        {
            minx = arrayTask[i].arrive;
            index = i;
        }
    }
    
    return index;
}

void RunTask(int n)
{
    arrayTask[n].start = nowtime;
    arrayTask[n].endtime = nowtime + arrayTask[n].service;
    arrayTask[n].runtime = arrayTask[n].endtime - arrayTask[n].arrive;
    avgruntime += arrayTask[n].runtime;
    arrayTask[n].dqzztime = (double)arrayTask[n].runtime / arrayTask[n].service;
    avgdqzztime += arrayTask[n].dqzztime;
    arrayTask[n].flag = 1;
}

void PrintResult(int n)
{
    printf(" 序号: %d 到达时间: %d 服务时间: %d", arrayTask[n].id, arrayTask[n].arrive, arrayTask[n].service);
    printf(" 开始时间: %d 结束时间: %d", arrayTask[n].start, arrayTask[n].endtime);
    printf(" 周转时间: %d 带权周转时间: %.2f\n", arrayTask[n].runtime, arrayTask[n].dqzztime);
}

int main()
{
    GetTask();
    nowtime = 0;
    avgruntime = 0;
    avgdqzztime = 0;
    
    for (int i = 1; i <= tasknum; ++i)
    {
        int id = GetNextTask(nowtime);
        RunTask(id);
        PrintResult(id);
        nowtime = arrayTask[id].endtime;
    }
    
    avgruntime /= tasknum;
    avgdqzztime /= tasknum;
    printf(" 平均周转时间: %.2f 平均带权周转时间: %.2f\n", avgruntime, avgdqzztime);
    
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值