1. 程式人生 > >幾種程序排程演算法模擬C++實現

幾種程序排程演算法模擬C++實現

先到先服務(FCFS)最短作業優先排程演算法(SJF)

#include <iostream>
#include <queue>
#include <algorithm>
#include <cstdio>
#include <cstring>


using namespace std;
const int MAXN = 1000;//假設能夠容納的程序最多的個數


struct Process
{
    int pos;                          //代表第幾個輸入的程序
    char Process_name[50];            //程序名字,預設最長長度佔用50字元
    double Arrival_time;             //程序到達時間
    double Service_time;             //服務時間       程序所需要的時間
    double Start_time;               //服務開始時間
    double End_time;                 //服務結束的時間
    double Turnaround_time;          //週轉時間    程序結束的時間-程序到達時間
    double Weight_Turnaround_time;   //帶權週轉時間       週轉時間 / 服務時間
    bool operator < (const Process &a)const
    {
        if(Service_time == a.Service_time)
            return Arrival_time > a.Arrival_time;
        return Service_time > a.Service_time;
    }
}process[MAXN];
int n;                           //程序的數量!
bool cmp1(Process &a,Process &b)
{
    return a.Arrival_time < b.Arrival_time;
}
void Init()
{
    printf("請輸入程序的數量:");
    scanf("%d",&n);
    for(int i = 0;i < n;i ++)
    {
        cout<<"請輸入第"<<i+1<<"個程序的名字  到達時間  服務時間"<<endl;
        scanf("%s",process[i].Process_name);
        scanf("%lf",&process[i].Arrival_time);
        scanf("%lf",&process[i].Service_time);
        process[i].pos = i;
    }
}
void Solve_FCFS()
{
    /*
    先到先服務演算法:是第一個排隊,誰就先被執行,在執行過程中,不會中斷他,當別人想要進入記憶體被執行,那麼只能在後面排隊
    */
    printf("先到先服務演算法\n");
    sort(process,process+n,cmp1);
    printf("程序的執行順序為:\n");
    printf("%s",process[0].Process_name);
    for(int i = 1;i < n;i ++)
        printf("-->%s",process[i].Process_name);
    printf("\n");
    double time = max(0.0,process[0].Arrival_time);//記錄總的時間!
    for(int i = 0;i < n;i ++)
    {
        process[i].Start_time = time;                           //更新開始時間
        process[i].End_time = time + process[i].Service_time;   //更新結束時間
        process[i].Turnaround_time = process[i].End_time - process[i].Arrival_time; //更新週轉時間
        process[i].Weight_Turnaround_time = process[i].Turnaround_time / process[i].Service_time;  //更新帶權週轉時間
        time += process[i].Service_time;
        if(i != n-1)   //當這時的結束時間小於下一個程序的到達時間的話,就要重新更新time
            time = max(time,process[i+1].Arrival_time);
    }
    printf("name\tarrive_time\tservice_time\tstart_time\tend_time\tTA_time\tWTA_time\n");
    for(int i= 0;i < n;i ++)  
        printf("%s\t%.2lf\t\t%.2lf\t\t%.2lf\t\t%.2lf\t\t%.2lf\t%.2lf\n",process[i].Process_name,process[i].Arrival_time,process[i].Service_time,process[i].Start_time,process[i].End_time,process[i].Turnaround_time,process[i].Weight_Turnaround_time);
//    for(int i= 0;i < index;i ++)
//        cout<<ans[i].Process_name<<"\t"<<ans[i].Arrival_time<<"\t\t"<<ans[i].Service_time<<"\t\t"<<ans[i].Start_time<<"\t\t"<<ans[i].End_time<<endl;


}
void Solve_SJF()
{
    /*
    最短作業優先排程演算法:程序的時間長短作為優先順序,程序時間越短,優先順序越高
    尋找就緒佇列中,程序時間最短的先執行,當存在多個長度相同的短作業時,按照提交時間的先後順序進行排程
    */
    printf("最短作業優先排程演算法:\n");
    priority_queue<Process> que;
    sort(process,process+n,cmp1);
    bool vis[MAXN];      //表示這個程序有沒有在完成,完成使用true表示
    Process ans[MAXN];
    double time = max(0.0,process[0].Arrival_time);int index = 0;
    memset(vis,false,sizeof(vis));
    //首先將第一個放到優先佇列中!
    que.push(process[0]);vis[process[0].pos] = 1;
    for(int i = 0;i < n;i ++)
    {
        while(!que.empty())
        {
            Process temp = que.top();   que.pop();
            temp.Start_time = time;temp.End_time = time + temp.Service_time;temp.Turnaround_time = temp.End_time - temp.Arrival_time;
            temp.Weight_Turnaround_time = temp.Turnaround_time / temp.Service_time;
            for(int j = 0;j< n;j ++)
                if(!vis[process[j].pos] && process[j].Arrival_time <= temp.End_time)
                {
                    vis[process[j].pos] = 1;
                    que.push(process[j]);
                }
            time += temp.Service_time;       //這裡面的時間都是有聯絡的,所以不用再次更新time
            ans[index++] = temp;             //將順序儲存到最終的答案序列中
        }
        bool flag = false; //判斷是否所有的程序都已經完成
        for(int j = 0;j < n;j ++)
            if(!vis[process[j].pos])
            {
                que.push(process[j]);//將一個時間最靠前的新增到佇列中
                time = process[j].Arrival_time;   //這裡就要更新time了,因為這裡的時間和上面的有些脫節!
                flag = true;break;
            }
        if(!flag) break;
    }
    printf("程序的執行順序為:\n");
    printf("%s",ans[0].Process_name);
    for(int i = 1;i < n;i ++)
        printf("-->%s",ans[i].Process_name);
    printf("\n");
    printf("name\tarrive_time\tservice_time\tstart_time\tend_time\tTA_time\tWTA_time\n");
    for(int i= 0;i < n;i ++)
        printf("%s\t%.2lf\t\t%.2lf\t\t%.2lf\t\t%.2lf\t\t%.2lf\t%.2lf\n",ans[i].Process_name,ans[i].Arrival_time,ans[i].Service_time,ans[i].Start_time,ans[i].End_time,ans[i].Turnaround_time,ans[i].Weight_Turnaround_time);
//    for(int i= 0;i < index;i ++)
//        cout<<ans[i].Process_name<<"\t"<<ans[i].Arrival_time<<"\t\t"<<ans[i].Service_time<<"\t\t"<<ans[i].Start_time<<"\t\t"<<ans[i].End_time<<endl;
}


int main()
{
    Init();
    Solve_FCFS();
    Solve_SJF();
    return 0;
}


/*
3
a 1 4
b 5 2
c 2 5


4
a 0 7
b 2 4
c 4 1
d 5 4
*/

高響應比優先排程

#include <iostream>
#include <queue>
#include <algorithm>
#include <cstdio>
#include <cstring>

using namespace std;
const int MAXN = 1000;
int n;
struct Process
{
    int pos;                          //代表第幾個輸入的程序
    char Process_name[50];            //程序名字,預設最長長度佔用50字元
    double Arrival_time;             //程序到達時間
    double Service_time;             //服務時間       程序所需要的時間
    double Start_time;               //服務開始時間
    double End_time;                 //服務結束的時間
    double Priority;                 //優先順序
    bool operator < (const Process &a)const
    {
        if(Priority == a.Priority)
            return Arrival_time > a.Arrival_time;
        return Priority < a.Priority;
    }
}process[MAXN];
void Init()
{
    printf("請輸入程序的數量:");
    scanf("%d",&n);
    for(int i = 0;i < n;i ++)
    {
        cout<<"請輸入第"<<i+1<<"個程序的名字  到達時間  服務時間"<<endl;
        scanf("%s",process[i].Process_name);
        scanf("%lf",&process[i].Arrival_time);
        scanf("%lf",&process[i].Service_time);
        process[i].pos = i;process[i].Priority = 0;
    }
}
bool cmp1(Process &a,Process &b)
{
    return a.Arrival_time < b.Arrival_time;
}

void Solve_HRRN()
{
    /*
    高響應比優先排程:每次都計算作業的優先順序,隨著作業等待時間的變長,優先順序不斷增加
    優先順序 = (作業已等待的時間+作業服務時間) / 作業服務時間
    那麼每完成一個任務,我們就要更新一次優先順序
    */
    printf("高響應比優先排程:\n");
    priority_queue<Process> que;
    sort(process,process+n,cmp1);
    bool vis[MAXN];      //表示這個程序有沒有在完成,完成使用true表示
    Process ans[MAXN];
    double time = max(0.0,process[0].Arrival_time);int index = 0;
    memset(vis,false,sizeof(vis));
    //首先將第一個放到優先佇列中!
    que.push(process[0]);vis[process[0].pos] = 1;
    for(int i = 0;i < n;i ++)
    {
        while(!que.empty())
        {
            Process temp = que.top();   que.pop();
            temp.Start_time = time;temp.End_time = time + temp.Service_time;
            for(int j = 0;j < n;j ++)
                if(!vis[process[j].pos] && process[j].Arrival_time <= temp.End_time)
                {
                    vis[process[j].pos] = 1;
                    que.push(process[j]);
                }
            time += temp.Service_time;       //這裡面的時間都是有聯絡的,所以不用再次更新time
            ans[index++] = temp;             //將順序儲存到最終的答案序列中
            Process need[MAXN];int tot = 0;
            while(!que.empty())  //首先將程序轉移的need陣列中
            {
                temp = que.top();que.pop();need[tot++] = temp;
            }
            for(int j = 0;j < tot;j ++)  //更新後面的Priority
            {
                need[j].Priority = (time - need[j].Arrival_time + need[j].Service_time)/ need[j].Service_time;
                que.push(need[j]);
            }
        }
        bool flag = false; //判斷是否所有的程序都已經完成
        for(int j = 0;j < n;j ++)
            if(!vis[process[j].pos])
            {
                que.push(process[j]);//將一個時間最靠前的新增到佇列中
                time = process[j].Arrival_time;   //這裡就要更新time了,因為這裡的時間和上面的有些脫節!
                flag = true;break;
            }
        if(!flag) break;
    }
    printf("程序的執行順序為:\n");
    printf("%s",ans[0].Process_name);
    for(int i = 1;i < n;i ++)
        printf("-->%s",ans[i].Process_name);
    printf("\n");
    printf("name\tarrive_time\tservice_time\tstart_time\tend_time\n");
    for(int i= 0;i < index;i ++)
        printf("%s\t%.2lf\t\t%.2lf\t\t%.2lf\t\t%.2lf\n",ans[i].Process_name,ans[i].Arrival_time,ans[i].Service_time,ans[i].Start_time,ans[i].End_time);
//    for(int i= 0;i < index;i ++)
//        cout<<ans[i].Process_name<<"\t"<<ans[i].Arrival_time<<"\t\t"<<ans[i].Service_time<<"\t\t"<<ans[i].Start_time<<"\t\t"<<ans[i].End_time<<endl;
}
int main()
{
    Init();
    Solve_HRRN();
    return 0;
}

搶佔式優先比排程演算法

#include <iostream>
#include <queue>
#include <algorithm>
#include <cstdio>
#include <cstring>

using namespace std;
const int MAXN = 1000;
int n;
struct Process
{
    int pos;                          //代表第幾個輸入的程序
    char Process_name[50];            //程序名字,預設最長長度佔用50字元
    double Arrival_time;             //程序到達時間
    double Service_time;             //服務時間       程序所需要的時間
    double Start_time;               //服務開始時間
    double End_time;                 //服務結束的時間
    double Priority;                 //優先權,這裡面的優先順序權是不能修改的!!!
    bool operator < (const Process &a)const
    {
        if(Priority == a.Priority)
            return Arrival_time > a.Arrival_time;
        return Priority < a.Priority;
    }
}process[MAXN];
void Init()
{
    printf("請輸入程序的數量:");
    scanf("%d",&n);
    for(int i = 0;i < n;i ++)
    {
        cout<<"請輸入第"<<i+1<<"個程序的名字  到達時間  服務時間  優先權"<<endl;
        scanf("%s",process[i].Process_name);
        scanf("%lf",&process[i].Arrival_time);
        scanf("%lf",&process[i].Service_time);
        scanf("%lf",&process[i].Priority);
        process[i].pos = i;
    }
}
bool cmp1(Process &a,Process &b)
{
    return a.Arrival_time < b.Arrival_time;
}

void Solve_PPS()
{
    /*
    搶佔式優先權排程:如果當前程序在執行時,如果後面出現了一個優先順序更高的程序,我們就要暫時停止這個程序,先執行優先權高的程式!!
    */
    printf("搶佔式優先權排程:\n");
    priority_queue<Process> que;
    sort(process,process+n,cmp1);
    bool vis[MAXN];      //表示這個程序有沒有在完成,完成使用true表示
    Process ans[MAXN];
    double time = max(0.0,process[0].Arrival_time);int index = 0;
    memset(vis,false,sizeof(vis));
    //首先將第一個放到優先佇列中!
    que.push(process[0]);vis[process[0].pos] = 1;
    for(int i = 0;i < n;i ++)
    {
        while(!que.empty())
        {
            bool ok = false;
            Process temp = que.top();que.pop();
            //在temp的服務時間中,如果有新的優先權高的程序出現,那麼就先執行優先權更高的程序,暫停這一段程序,並且更新這個程序所需要的時間等等
            temp.Start_time = time;temp.End_time = time + temp.Service_time;
            for(int j = 0;j < n;j ++)
            {//在當前優先佇列中的優先權永遠是要小於當前執行的優先權的,那麼我們只需要判斷vis為false的就可以了!
                if(!vis[process[j].pos] && process[j].Priority > temp.Priority && process[j].Arrival_time < temp.End_time)
                {
                    ok = true;
                    vis[process[j].pos] = 1;
                    que.push(process[j]);
                    temp.End_time = process[j].Arrival_time;
                    ans[index++] = temp;
                    temp.Service_time = time + temp.Service_time - temp.End_time;//更新當前的服務時間
                    que.push(temp);
                    time = process[j].Arrival_time;
                    break;
                }
            }
            for(int j = 0;j < n;j ++)//將這段時間內時間已經滿足要求,但是優先權不是很高的新增到佇列中!
            {
                if(!vis[process[j].pos] && process[j].Arrival_time <= temp.End_time)
                {
                    vis[process[j].pos] = 1;
                    que.push(process[j]);
                }
            }
            if(!ok)  //表示這個執行過程中沒有打斷的其它程序到來
            {
                time += temp.Service_time;
                ans[index++] = temp;
            }

        }
        bool flag = false; //判斷是否所有的程序都已經完成
        for(int j = 0;j < n;j ++)
            if(!vis[process[j].pos])
            {
                vis[process[j].pos] = 1;
                que.push(process[j]);//將一個時間最靠前的新增到佇列中
                time = process[j].Arrival_time;   //這裡就要更新time了,因為這裡的時間和上面的有些脫節!
                flag = true;break;
            }
        if(!flag) break;
    }
    printf("程序的執行順序為:\n");
    printf("%s",ans[0].Process_name);
    for(int i = 1;i < index;i ++)
        printf("-->%s",ans[i].Process_name);
    printf("\n");
    printf("name\tarrive_time\tservice_time\tstart_time\tend_time\n");
    for(int i= 0;i < index;i ++)
        printf("%s\t%.2lf\t\t%.2lf\t\t%.2lf\t\t%.2lf\n",ans[i].Process_name,ans[i].Arrival_time,ans[i].Service_time,ans[i].Start_time,ans[i].End_time);
    //for(int i= 0;i < index;i ++)
       // cout<<ans[i].Process_name<<"\t"<<ans[i].Arrival_time<<"\t\t"<<ans[i].Service_time<<"\t\t"<<ans[i].Start_time<<"\t\t"<<ans[i].End_time<<endl;
}
int main()
{
    Init();
    Solve_PPS();
    return 0;
}

/*
5
1 1 10 80
2 11 15 20
3 21 10 50
4 31 10 120
5 41 10 100

3
A 0 5 1
B 2 2 2
C 3 4 3
*/

時間片輪轉排程演算法

#include <iostream>
#include <queue>
#include <algorithm>
#include <cstdio>
#include <cstring>
using namespace std;
const int MAXN = 1000;//假設能夠容納的程序最多的個數

struct Process
{
    int pos;                          //代表第幾個輸入的程序
    char Process_name[50];            //程序名字,預設最長長度佔用50字元
    double Arrival_time;             //程序到達時間
    double Service_time;             //服務時間       程序所需要的時間
    double Start_time;               //服務開始時間
    double End_time;                 //服務結束的時間
    double Turnaround_time;          //週轉時間    程序結束的時間-程序到達時間
    double Weight_Turnaround_time;   //帶權週轉時間       週轉時間 / 服務時間
}process[MAXN];
double every_time;
int n;

void Init()
{
    printf("請輸入時間片的時間:");
    scanf("%lf",&every_time);
    printf("請輸入程序的數量:");
    scanf("%d",&n);
    for(int i = 0;i < n;i ++)
    {
        cout<<"請輸入第"<<i+1<<"個程序的名字  到達時間  服務時間"<<endl;
        scanf("%s",process[i].Process_name);
        scanf("%lf",&process[i].Arrival_time);
        scanf("%lf",&process[i].Service_time);
        process[i].pos = i;
    }
}
bool cmp1(const Process &a,const Process &b)
{
    return a.Arrival_time < b.Arrival_time;
}

void Solve_TSRA()
{
    /*
    時間片輪轉演算法:
    */
    printf("時間片輪轉演算法:\n");
    queue<Process> que;
    sort(process,process+n,cmp1);
    bool vis[MAXN];      //表示這個程序有沒有在完成,完成使用true表示
    Process ans[MAXN];
    double time = max(0.0,process[0].Arrival_time);int index = 0;
    memset(vis,false,sizeof(vis));
    que.push(process[0]);vis[process[0].pos] = 1;
    for(int i = 0;i < n;i ++)
    {
        while(!que.empty())
        {
            Process temp = que.front();   que.pop();
            temp.Start_time = time;
            temp.End_time = temp.Service_time >= every_time ? time + every_time : time + temp.Service_time;
            for(int j = 0;j < n;j ++)
                if(!vis[process[j].pos] && process[j].Arrival_time <= temp.End_time)
                {
                    vis[process[j].pos] = 1;
                    que.push(process[j]);
                }
            if(temp.Service_time > every_time)
            {
                temp.Service_time -= every_time;
                que.push(temp);
                time += every_time;
            }
            else
                time += temp.Service_time;       //這裡面的時間都是有聯絡的,所以不用再次更新time
            ans[index++] = temp;             //將順序儲存到最終的答案序列中
        }
        bool flag = false; //判斷是否所有的程序都已經完成
        for(int j = 0;j < n;j ++)
            if(!vis[process[j].pos])
            {
                que.push(process[j]);//將一個時間最靠前的新增到佇列中
                time = process[j].Arrival_time;   //這裡就要更新time了,因為這裡的時間和上面的有些脫節!
                flag = true;break;
            }
        if(!flag) break;
    }
    printf("程序的執行順序為:\n");
    printf("%s",ans[0].Process_name);
    for(int i = 1;i < index;i ++)
        printf("-->%s",ans[i].Process_name);
    printf("\n");
    printf("name\tarrive_time\tservice_time\tstart_time\tend_time\n");
    for(int i= 0;i < index;i ++)
        printf("%s\t%.2lf\t\t%.2lf\t\t%.2lf\t\t%.2lf\n",ans[i].Process_name,ans[i].Arrival_time,ans[i].Service_time,ans[i].Start_time,ans[i].End_time);
//    for(int i= 0;i < index;i ++)
//        cout<<ans[i].Process_name<<"\t"<<ans[i].Arrival_time<<"\t\t"<<ans[i].Service_time<<"\t\t"<<ans[i].Start_time<<"\t\t"<<ans[i].End_time<<endl;
}
int main()
{
    Init();
    Solve_TSRA();
    return 0;
}

寫在後面

只是單純的模擬實現,如果有錯誤,感謝大家的指正

一學期的作業系統實驗,上機時間只有週六周天兩天,寫給我那三流院校計算機學院的樊院長,那剩下的只能在課下找時間完成,這個作為第一個題用了大約半天多的時間,主要是最短作業優先的寫完了之後後面的都是和最短作業優先的方法很是類似了,只需要更改一下迴圈裡面的函式就可以了