FCFS,HRRN,SPF,SRT,四种调度算法简单实现(C++版)

1.数据

输入数据由三部分组成:
在这里插入图片描述

2.结构体

四种算法的数据组成是一样的,所以使用相同的结构体(全局变量在最后完整代码中)

struct P
{
    
    
    string name; //名称
    int arrive,longg,start,endd,cyc;//到达时间,服务时间,开始时间,结束时间,周转时间
	double qcyc;//平均周转时间
    int id;//数据顺序
}p[10000];

因为在调度中顺序会改变,所以要保留输入时的数据顺序,这样才能按原本顺序输出

3.FCFS

这个算法只按照到达时间排序,且不会因为后面的进程而改变顺序,因此只需要全部排一次就可以

bool cmpFCFS(P p1,P p2)
{
    
    
    return p1.arrive<p2.arrive;//按到达时间从小到大
}
void FCFS(string infilename,string outfilename)//(输入文件名与保存文件名)
{
    
    
    readfile(infilename);//读入数据(可改为手动输入)
    sort(p,p+n,cmpFCFS);//sort不解释,cmp是自定义排序方式,如上
    now=0;//当前时间
    for(int i=0;i<n;i++)
    {
    
    
        now=max(now,p[i].arrive);//如果当前无到达进程,则直接跳到下一个到来进程的到达时间
        p[i].start=now;//p[i]开始执行
        now+=p[i].longg;//p[i]时间
        p[i].endd=now;//p[i]执行完毕
    }
    savefile(outfilename);//保存数据
}

4.HRRN

这个排序会受后来进程影响,所以每执行完一个就要重排,但因为一次执行一个进程,所以只需要找到优先级最高的,即p[0]是优先级最高,因此只需和p[0]比较,而不用全部sort排序,执行完的交换到数组最后,进程数n-1,则将已执行完进程排除序列

void sortHRRN()
{
    
    
    for(int i=1;i<n;i++)
    {
    
    
        if(p[0].arrive>now&&p[i].arrive>now&&p[0].arrive>p[i].arrive)//都未达,先到达先开始
            swap(p[0],p[i]);
        else if(p[0].arrive<=now&&p[i].arrive<=now&&(double)1.0*(now-p[0].arrive+p[0].longg)/p[0].longg<(double)1.0*(now-p[i].arrive+p[i].longg)/p[i].longg)//都已达,根据HRRN规则计算,得到优先级较高的
            swap(p[0],p[i]);
        else if(p[0].arrive>now)//剩下两种情况都是一个已达,一个未达,已达的排在前,所以p[0]未达则交换,p[0]已达则不动
            swap(p[0],p[i]);
    }
}
void HRRN(string infilename,string outfilename)
{
    
    
    readfile(infilename);
    now=0;
    while(n>0){
    
    
        sortHRRN();//每次找
        now=max(now,p[0].arrive);
        p[0].start=now;
        now+=p[0].longg;
        p[0].endd=now;  //同上
        swap(p[0],p[n-1]);
        n--;//排除已执行
    }
    savefile(outfilename);
}

5.SPF

基本同上,仅排序规则不同

void sortSPF()
{
    
    
    for(int i=1;i<n;i++)
    {
    
    
        if(p[0].arrive>now&&p[i].arrive>now&&p[0].arrive>p[i].arrive)
            swap(p[0],p[i]);
        else if(p[0].arrive<=now&&p[i].arrive<=now&&p[0].longg>p[i].longg)//此处不同
            swap(p[0],p[i]);
        else if(p[0].arrive>now)
            swap(p[0],p[i]);
    }
}
void SPF(string infilename,string outfilename)
{
    
    
    readfile(infilename);
    now=0;
    while(n>0){
    
    
        sortSPF();
        now=max(now,p[0].arrive);
        p[0].start=now;
        now+=p[0].longg;
        p[0].endd=now;
        swap(p[0],p[n-1]);
        n--;
    }
    savefile(outfilename);
}

6.SRT

排序规则与SPF一样,但它能够抢占,所以最简单的方法就是每执行一个时间单位就重排一次,而且因为要改变longg值来记录,所以在开始要保留初始longg值,执行完回复原数据,还要注意开始时间的记录

void sortSRT()//与SPF完全一致
{
    
    
    for(int i=1;i<n;i++)
    {
    
    
        if(p[0].arrive>now&&p[i].arrive>now&&p[0].arrive>p[i].arrive)
            swap(p[0],p[i]);
        else if(p[0].arrive<=now&&p[i].arrive<=now&&p[0].longg>p[i].longg)
            swap(p[0],p[i]);
        else if(p[0].arrive>now)
            swap(p[0],p[i]);
    }
}
void SRT(string infilename,string outfilename)
{
    
    
    readfile(infilename);
    now=0;
    int l[10000];//记录longg的数组
    for(int i=0;i<n2;i++)
    {
    
    
        l[i]=p[i].longg;//记录
    }
    while(n>0){
    
    
        sortSRT();
        now=max(now,p[0].arrive);
        if(p[0].start==-1)//已开始的不用记录开始时间
            p[0].start=now;
        now++;//执行一时间单位
        p[0].longg--;//执行一时间单位
        if(!p[0].longg)//执行结束
        {
    
    
            p[0].endd=now;
            swap(p[0],p[n-1]);
            n--;
        }
    }
    sort(p,p+n2,cmpfirst);//恢复原顺序
    for(int i=0;i<n2;i++)
    {
    
    
        p[i].longg=l[i];//恢复longg
    }
    savefile(outfilename);
}

完整代码

#include<iostream>
#include<algorithm>
#include<cmath>
#include<ostream>
#include<sstream>
#include<fstream>
#include<iomanip>
#include<stdio.h>
using namespace std;

struct P
{
    
    
    string name;
    int arrive,longg,start,endd,cyc;
	double qcyc;
    int id;
}p[10000];

int n,n2,now,choice;
string s;

bool cmpfirst(P p1,P p2)
{
    
    
    return p1.id<p2.id;
}

void split(string s)
{
    
    
    stringstream sstream;
    string s2;
    int l1=0,l2=0;
    while(s[l1]!=' ')
        l1++;
    l2=l1+1;
    while(s[l2]!=' ')
        l2++;
    p[n].name=s.substr(0,l1);
    s2=s.substr(l1+1,l2-l1-1);
    sstream<<s2;
    sstream>>p[n].arrive;
    sstream.clear();
    s2=s.substr(l2+1,s.length()-l2-1);
    sstream<<s2;
    sstream>>p[n].longg;
    p[n].id=n;
    p[n].start=-1;
    //p[n].start=stoi(s.substr(l1+1,l2-l1-1));
    //p[n].longg=stoi(s.substr(l2+1,s.length()-l2-1));
    //cout<<p[n].name<<" "<<p[n].start<<" "<<p[n].longg<<endl;
}

void readfile(string infilename)
{
    
    
    n=0;
    ifstream infile(infilename);
    if (!infile.is_open())
    {
    
    
        cout << "file can't open" << endl;
    }
    getline(infile,s);
    while(getline(infile,s))
    {
    
    
        split(s);
        n++;
    }
    n2=n;
    infile.close();
}

void savefile(string outfilename)
{
    
    
    sort(p,p+n2,cmpfirst);
    cout<<"finish"<<endl;

    ofstream outfile(outfilename, ios::app);
    switch(choice)
    {
    
    
        case 1:outfile<<"FCFS:"<<endl;break;
        case 2:outfile<<"SPF:"<<endl;break;
        case 3:outfile<<"HRRN:"<<endl;break;
        case 4:outfile<<"SRT:"<<endl;break;


        default:;
    }
    outfile<<"name\tarrive\tlongg\tstart\tend\tcyc\tqcyc"<<endl;
    for(int i=0;i<n2;i++)
    {
    
    
        p[i].cyc=p[i].endd-p[i].arrive;
        p[i].qcyc=1.0*p[i].cyc/p[i].longg;
        outfile<<left<<setw(7)<<p[i].name
               <<left<<setw(7)<<p[i].arrive
               <<left<<setw(7)<<p[i].longg
               <<left<<setw(7)<<p[i].start
               <<left<<setw(7)<<p[i].endd
               <<left<<setw(7)<<p[i].cyc
               <<left<<setw(7)<<p[i].qcyc<<endl;
    }
    outfile.close();
}

bool cmpFCFS(P p1,P p2)
{
    
    
    return p1.arrive<p2.arrive;
}
void FCFS(string infilename,string outfilename)
{
    
    
    readfile(infilename);
    sort(p,p+n,cmpFCFS);
    now=0;
    for(int i=0;i<n;i++)
    {
    
    
        now=max(now,p[i].arrive);
        p[i].start=now;
        now+=p[i].longg;
        p[i].endd=now;
    }
    savefile(outfilename);
}

void sortHRRN()
{
    
    
    for(int i=1;i<n;i++)
    {
    
    
        if(p[0].arrive>now&&p[i].arrive>now&&p[0].arrive>p[i].arrive)
            swap(p[0],p[i]);
        else if(p[0].arrive<=now&&p[i].arrive<=now&&(double)1.0*(now-p[0].arrive+p[0].longg)/p[0].longg<(double)1.0*(now-p[i].arrive+p[i].longg)/p[i].longg)
            swap(p[0],p[i]);
        else if(p[0].arrive>now)
            swap(p[0],p[i]);
    }
}
void HRRN(string infilename,string outfilename)
{
    
    
    readfile(infilename);
    now=0;
    while(n>0){
    
    
        sortHRRN();
        now=max(now,p[0].arrive);
        p[0].start=now;
        now+=p[0].longg;
        p[0].endd=now;
        swap(p[0],p[n-1]);
        n--;
    }
    savefile(outfilename);
}

void sortSPF()
{
    
    
    for(int i=1;i<n;i++)
    {
    
    
        if(p[0].arrive>now&&p[i].arrive>now&&p[0].arrive>p[i].arrive)
            swap(p[0],p[i]);
        else if(p[0].arrive<=now&&p[i].arrive<=now&&p[0].longg>p[i].longg)
            swap(p[0],p[i]);
        else if(p[0].arrive>now)
            swap(p[0],p[i]);
    }
}
void SPF(string infilename,string outfilename)
{
    
    
    readfile(infilename);
    now=0;
    while(n>0){
    
    
        sortSPF();
        now=max(now,p[0].arrive);
        p[0].start=now;
        now+=p[0].longg;
        p[0].endd=now;
        swap(p[0],p[n-1]);
        n--;
    }
    savefile(outfilename);
}

void sortSRT()
{
    
    
    for(int i=1;i<n;i++)
    {
    
    
        if(p[0].arrive>now&&p[i].arrive>now&&p[0].arrive>p[i].arrive)
            swap(p[0],p[i]);
        else if(p[0].arrive<=now&&p[i].arrive<=now&&p[0].longg>p[i].longg)
            swap(p[0],p[i]);
        else if(p[0].arrive>now)
            swap(p[0],p[i]);
    }
}
void SRT(string infilename,string outfilename)
{
    
    
    readfile(infilename);
    now=0;
    int l[10000];
    for(int i=0;i<n2;i++)
    {
    
    
        l[i]=p[i].longg;
    }
    while(n>0){
    
    
        sortSRT();
        now=max(now,p[0].arrive);
        if(p[0].start==-1)
            p[0].start=now;
        now++;
        p[0].longg--;
        if(!p[0].longg)
        {
    
    
            p[0].endd=now;
            swap(p[0],p[n-1]);
            n--;
        }
    }
    sort(p,p+n2,cmpfirst);//恢复原顺序
    for(int i=0;i<n2;i++)
    {
    
    
        p[i].longg=l[i];
    }
    savefile(outfilename);
}

int main()
{
    
    
	string infilename,outfilename;

    cout<<"input the filename:";
    cin>>infilename;

	cout<<"input the name of saved file:";
    cin>>outfilename;

    choice = 1;//初始化choice
    while(choice != 0)
    {
    
    
        cout<<"input your choice:0.exit 1.FCFS  2.SPF  3.HRRN 4.SRT"<<endl;
        cin>>choice;
        switch(choice)
        {
    
    
            case 1:FCFS(infilename,outfilename);break;
            case 2:SPF(infilename,outfilename);break;
            case 3:HRRN(infilename,outfilename);break;
            case 4:SRT(infilename,outfilename);break;
            case 0:cout<<"退出程序\n";break;
            default:cout<<"";
        }
    }
    return 0;
}

哦对了ifstream infile(infilename);这种写法至少c++11才能运行(传入一个string),或者你可以全部改成c的形式:在string变量名后面加个.c_str(),就像这样->ifstream infile(infilename.c_str());

有疑问欢迎在评论区指出(っ•̀ω•́)っ✎⁾⁾ 我爱学习

猜你喜欢

转载自blog.csdn.net/qq_44616044/article/details/110486098