先来先服务算法
短进程优先级算法
非抢占式优先级调度算法
抢占式优先级调度算法
#include <iostream>
#include <queue> //优先级队列
#include <algorithm>
#include <cstdio>
#include <cstring>
using namespace std;
const int MAXN = 1000;
int n;
//先来先服务和短进程优先结构体
struct ProcessFS
{
int pos; //代表第几个输入的进程
char Process_name[50]; //进程名字,默认最长长度占用50字符
double Arrival_time; //进程到达时间
double Service_time; //服务时间 进程所需要的时间
double Start_time; //服务开始时间
double End_time; //服务结束的时间
double turnroundTime; //周转时间
double weightedTurnaroundTime;//带权周转时间
double Priority; //优先权,这里面的优先级权是不能修改的!!!
bool operator < (const ProcessFS & a)const
{
if (Service_time == a.Service_time)
return Arrival_time > a.Arrival_time;
return Service_time > a.Service_time;
}
}processFS[MAXN]; //结构体数组
//非抢占式优先级结构体
struct ProcessNP
{
int pos; //代表第几个输入的进程
char Process_name[50]; //进程名字,默认最长长度占用50字符
double Arrival_time; //进程到达时间
double Service_time; //服务时间 进程所需要的时间
double Start_time; //服务开始时间
double End_time; //服务结束的时间
double turnroundTime; //周转时间
double weightedTurnaroundTime;//带权周转时间
double Priority; //优先权,这里面的优先级权是不能修改的!!!
bool operator < (const ProcessNP& a)const
{
if (Priority == a.Priority)
return Arrival_time > a.Arrival_time; //在Priority相同的前提下,到达时间小(即到达最早的)优先出队
return Priority < a.Priority; //Priority大的优先出队 优先级大的在堆顶
}
}processNP[MAXN]; //结构体数组
struct Process
{
int pos; //代表第几个输入的进程
char Process_name[50]; //进程名字,默认最长长度占用50字符
double Arrival_time; //进程到达时间
double Service_time; //服务时间 进程所需要的时间
double Start_time; //服务开始时间
double End_time; //服务结束的时间
double turnroundTime; //周转时间
double weightedTurnaroundTime;//带权周转时间
double Priority; //优先权,这里面的优先级权是不能修改的!!!
bool operator < (const Process& a)const
{
if (Priority == a.Priority)
return Arrival_time > a.Arrival_time; //在Priority相同的前提下,到达时间小(即到达最早的)优先出队
return Priority < a.Priority; //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;
}
}
//先来先服务和短进程的数据输入函数
void InitFS()
{
printf("请输入进程的数量:");
scanf("%d", &n);
for (int i = 0; i < n; i++)
{
cout << "请输入第" << i + 1 << "个进程的名字 到达时间 服务时间 优先权" << endl;
scanf("%s", processFS[i].Process_name);
scanf("%lf", &processFS[i].Arrival_time);
scanf("%lf", &processFS[i].Service_time);
scanf("%lf", &processFS[i].Priority);
processFS[i].pos = i;
}
};
//非抢占式优先级的数据输入函数
void InitNP()
{
printf("请输入进程的数量:");
scanf("%d", &n);
for (int i = 0; i < n; i++)
{
cout << "请输入第" << i + 1 << "个进程的名字 到达时间 服务时间 优先权" << endl;
scanf("%s", processNP[i].Process_name);
scanf("%lf", &processNP[i].Arrival_time);
scanf("%lf", &processNP[i].Service_time);
scanf("%lf", &processNP[i].Priority);
processNP[i].pos = i;
}
};
//抢占式优先级算法的优先级队列排序函数
bool cmp1(Process& a, Process& b)//优先级队列排序方式始终是先来的在队首
{
return a.Arrival_time < b.Arrival_time;
};
//先来先服务和短进程优先排序函数
bool arrange(ProcessFS& a, ProcessFS& b)//优先级队列排序方式始终是先来的在队首
{
return a.Arrival_time < b.Arrival_time;
};
//非抢占式优先级排序函数
bool arrangeNP(ProcessNP& a, ProcessNP& 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; //取第一个进程的到达时间与0.0取最大值
memset(vis, false, sizeof(vis));//对vis数组元素挨个拷贝为false,即让vis的元素初始值为false
//首先将第一个放到优先队列中!
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,然后在que中删除该进程
//在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;//计数index+1并且将阻塞进程()放入数组ans
temp.Service_time = time + temp.Service_time - temp.End_time;//更新当前的服务时间
que.push(temp);//继续放入后背队列que参与下一轮竞争
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; //ans[]结构体数组用来存放真实运行序列的进程
}
}
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了,因为这里的时间和上面的有些脱节!temp完整的运行时间已经过去
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);
Process shows[MAXN]; //用来输出好看的
for (int i = 0; i < index; i++) {
shows[ans[i].pos] = ans[i];
shows[ans[i].pos].turnroundTime = shows[ans[i].pos].End_time - shows[ans[i].pos].Arrival_time;
shows[ans[i].pos].weightedTurnaroundTime = shows[ans[i].pos].turnroundTime / shows[ans[i].pos].Service_time;
}
printf("\n");
printf("name\tarrive_time\tservice_time\tstart_time\tend_time\n");
for (int i = 0; i < n; i++)
printf("%s\t%.2lf\t\t%.2lf\t\t%.2lf\t\t%.2lf\n", shows[i].Process_name, shows[i].Arrival_time, shows[i].Service_time, shows[i].Start_time, shows[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 k;
float atTime = 0; // 平均周转时间
float AQTTime = 0; //平均带权周转时间
for (k = 0; k < n; k++)
{
atTime += shows[k].turnroundTime;
AQTTime += shows[k].weightedTurnaroundTime;
}
atTime = atTime / n;
AQTTime = AQTTime / n;
printf("\n调用短进程优先算法的平均周转时间为:");
printf("%.3f\n", atTime);
printf("调用短进程优先算法的平均带权周转时间为:");
printf("%.3f\n", AQTTime);
}
//先来先服务和短进程优先
void Solve_FCFS()
{
/*
先到先服务算法:是第一个排队,谁就先被执行,在执行过程中,不会中断他,当别人想要进入内存被执行,那么只能在后面排队
*/
printf("先到先服务算法\n");
sort(processFS, processFS + n, arrange);
printf("进程的运行顺序为:\n");
printf("%s", processFS[0].Process_name);
for (int i = 1; i < n; i++)
printf("-->%s", processFS[i].Process_name);
printf("\n");
double time = max(0.0, processFS[0].Arrival_time);//记录总的时间!
for (int i = 0; i < n; i++)
{
processFS[i].Start_time = time; //更新开始时间
processFS[i].End_time = time + processFS[i].Service_time; //更新结束时间
processFS[i].turnroundTime = processFS[i].End_time - processFS[i].Arrival_time; //更新周转时间
processFS[i].weightedTurnaroundTime = processFS[i].turnroundTime / processFS[i].Service_time; //更新带权周转时间
time += processFS[i].Service_time;
if (i != n - 1) //当这时的结束时间小于下一个进程的到达时间的话,就要重新更新time
time = max(time, processFS[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", processFS[i].Process_name, processFS[i].Arrival_time, processFS[i].Service_time, processFS[i].Start_time, processFS[i].End_time, processFS[i].turnroundTime, processFS[i].weightedTurnaroundTime);
// 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<ProcessFS> que;
sort(processFS, processFS + n, arrange);
bool vis[MAXN]; //表示这个进程有没有在完成,完成使用true表示
ProcessFS ans[MAXN];
double time = max(0.0, processFS[0].Arrival_time); int index = 0;
memset(vis, false, sizeof(vis));
//首先将第一个放到优先队列中!
que.push(processFS[0]); vis[processFS[0].pos] = 1;
for (int i = 0; i < n; i++)
{
while (!que.empty())
{
ProcessFS temp = que.top(); que.pop();
temp.Start_time = time; temp.End_time = time + temp.Service_time; temp.turnroundTime = temp.End_time - temp.Arrival_time;//temp为当前(这个模型里)占用cpu进程
temp.weightedTurnaroundTime = temp.turnroundTime / temp.Service_time;//整个循环是temp的整个周转时间为周期
for (int j = 0; j < n; j++)
if (!vis[processFS[j].pos] && processFS[j].Arrival_time <= temp.End_time)
{
vis[processFS[j].pos] = 1;
que.push(processFS[j]);
}
time += temp.Service_time; //这里面的时间都是有联系的,所以不用再次更新time ,因为占用cpu的进程不会被抢占
ans[index++] = temp; //将顺序存储到最终的答案序列中
}
bool flag = false; //判断是否所有的进程都已经完成
for (int j = 0; j < n; j++)
if (!vis[processFS[j].pos])
{
que.push(processFS[j]);//将一个时间最靠前的添加到队列中
time = processFS[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].turnroundTime, ans[i].weightedTurnaroundTime);
// 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_FCFS1()
{
/*
先到先服务算法:是第一个排队,谁就先被执行,在执行过程中,不会中断他,当别人想要进入内存被执行,那么只能在后面排队
*/
printf("先到先服务算法\n");
sort(processNP, processNP + n, arrangeNP);
printf("进程的运行顺序为:\n");
printf("%s", processNP[0].Process_name);
for (int i = 1; i < n; i++)
printf("-->%s", processNP[i].Process_name);
printf("\n");
double time = max(0.0, processNP[0].Arrival_time);//记录总的时间!
for (int i = 0; i < n; i++)
{
processNP[i].Start_time = time; //更新开始时间
processNP[i].End_time = time + processNP[i].Service_time; //更新结束时间
processNP[i].turnroundTime = processNP[i].End_time - processNP[i].Arrival_time; //更新周转时间
processNP[i].weightedTurnaroundTime = processNP[i].turnroundTime / processNP[i].Service_time; //更新带权周转时间
time += processNP[i].Service_time;
if (i != n - 1) //当这时的结束时间小于下一个进程的到达时间的话,就要重新更新time
time = max(time, processNP[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", processNP[i].Process_name, processNP[i].Arrival_time, processNP[i].Service_time, processNP[i].Start_time, processNP[i].End_time, processNP[i].turnroundTime, processNP[i].weightedTurnaroundTime);
// 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_SJF1()
{
/*
最短作业优先调度算法:进程的时间长短作为优先级,进程时间越短,优先级越高
寻找就绪队列中,进程时间最短的先执行,当存在多个长度相同的短作业时,按照提交时间的先后顺序进行调度
*/
printf("非抢占式优先级调度算法:\n");
priority_queue<ProcessNP> que;
sort(processNP, processNP + n, arrangeNP);
bool vis[MAXN]; //表示这个进程有没有在完成,完成使用true表示
ProcessNP ans[MAXN];
double time = max(0.0, processNP[0].Arrival_time); int index = 0;
memset(vis, false, sizeof(vis));
//首先将第一个放到优先队列中!
que.push(processNP[0]); vis[processNP[0].pos] = 1;
for (int i = 0; i < n; i++)
{
while (!que.empty())
{
ProcessNP temp = que.top(); que.pop();
temp.Start_time = time; temp.End_time = time + temp.Service_time; temp.turnroundTime = temp.End_time - temp.Arrival_time;//temp为当前(这个模型里)占用cpu进程
temp.weightedTurnaroundTime = temp.turnroundTime / temp.Service_time;//整个循环是temp的整个周转时间为周期
for (int j = 0; j < n; j++)
if (!vis[processNP[j].pos] && processNP[j].Arrival_time <= temp.End_time)
{
vis[processNP[j].pos] = 1;
que.push(processNP[j]);
}
time += temp.Service_time; //这里面的时间都是有联系的,所以不用再次更新time ,因为占用cpu的进程不会被抢占
ans[index++] = temp; //将顺序存储到最终的答案序列中
}
bool flag = false; //判断是否所有的进程都已经完成
for (int j = 0; j < n; j++)
if (!vis[processNP[j].pos])
{
que.push(processNP[j]);//将一个时间最靠前的添加到队列中
time = processNP[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].turnroundTime, ans[i].weightedTurnaroundTime);
// 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()
{
int select = 1;
while (select)
{
cout << "******************************************\n";
cout << "*****1.******* 先来先服务算法及短作业优先 ************\n";
cout << "*****2.******** 静态非抢占优先级 ************\n";
cout << "*****3.**** 静态抢占优先级*********\n";
cout << "*****0.**********退出*********************\n";
cout << "请选择:> ";
cin >> select;
switch (select)
{
case 1:
InitFS();
Solve_FCFS();
Solve_SJF();
break;
case 2:
InitNP();
Solve_FCFS1();
Solve_SJF1();
break;
case 3:
Init();
Solve_PPS();
break;
default:
break;
}
}
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
*/
本文来自https://blog.csdn.net/li1615882553/article/details/80553945
我只是进行了部分整合和一点点添加和亿点点注释
还是要膜拜这位大佬