短作业优先与时间片轮转法

#include <iostream>
#include <iomanip>
#include <vector>
using namespace std;
#define MaxNum 100
int  ArrivalTime[MaxNum];  //到达时间
int  ServiceTime[MaxNum];  //服务时间
int  FinishTime[MaxNum];   //完成时间
int  WholeTime[MaxNum];    //周转时间
double  WeightWholeTime[MaxNum];      //带权周转时间
double AverageWT_SJF;  //SJF算法的平均周转时间
double AverageWWT_SJF; //SJF算法的平均带权周转时间
bool isFinished_SJF[MaxNum];
static int n;
struct RR{
    // 进程名称
    char name[10];
    // 到达时间
    int daodatime;
    // 服务时间
    int fuwutime;
    // 剩余时间
    int shengyutime;
    // 所处状态
    char *state;


    struct RR *next;
};


// 根据到达时间从小到大排序
struct RR *input()
{
    int N, i;
    // 定义队首、队尾
    struct RR *head, *rear;
    // p是队尾指针,q是队首指针,t是执行时间
    struct RR *p, *q, *t;
    // 初始化队首和队尾为空
    head = rear = NULL;


    printf("请输入进程数目:");
    scanf("%d", &N);


    for(i = 0; i < N; i++)
    {
        // 初始化一个空间给进程
        p = (struct RR *)malloc(sizeof(struct RR));


        printf("请输入第%d个进程的名字、到达时间、服务时间(例如:1 2 1):\n", i+1);
        scanf("%s%d%d", p->name, &p->daodatime, &p->fuwutime);
        p->shengyutime = p->fuwutime;
        p->state = "就绪";
        p->next = NULL;


        // 当输入结束时,把p的数据放到队首,以便下一步执行
        if(rear == NULL)
        {
            head = p;
            p->next = NULL;
            rear = p;
        }
        // 否则执行时间为空,队首变成q
        else
        {
            t = NULL;
            q = head;
            // 当q和q的到达时间小于p的到达时间时,把执行时间给q
            while(q && q->daodatime < p->daodatime)
            {
                t = q;
                q = q->next;
            }
            // 当q是队首时,则下一个队首变成p,以便每个进程都能够得到时间片
            if(q == head)
            {
                p->next = head;
                head = p;
            }
            // 当执行时间片到达队尾时(执行完成),返回给队首p
            else if(t == rear)
            {
                rear->next = p;
                p->next = NULL;
                rear = p;
            }
            // 否则给队首p占用执行时间,p执行完后到q
            else
            {
                t->next = p;
                p->next = q;
            }
        }
    }
    // 返回队首
    return head;
}
// 输出
void run(struct RR *head)
{
    struct RR *p, *t, *r;
    int num;
    // 运行过程
    vector<string> vec_out;


    printf("请输入时间片:");
    scanf("%d", &num);


    // 当队首不为空时,把p给队首
    while(head != NULL)
    {
        r = p = head;
        // 把执行时间给队首
        while(p != NULL)
        {
            t = head;
            // p的剩余时间 = 剩余时间 - 时间片
            p->shengyutime = p->shengyutime - num;
            p->state = "运行";
            string s = p->name;
            vec_out.push_back(s);
            // 当p运行完,即剩余时间小于0时,仍然把它当做0处理
            if(p->shengyutime < 0)
                p->shengyutime = 0;


            printf("\n************程序开始运行*****************\n");
            printf("进程  到达时间 服务时间  剩余时间  当前状态\n");
            //时间不为空时,输出当前进程的信息,并把时间片交给下一个进程
            while(t != NULL)
            {
                printf("%2s%8d%8d%14d%10s\n", t->name, t->daodatime, t->fuwutime, t->shengyutime, t->state);
                t = t->next;
            }
            //按住回车键观看
            //getchar();
            //当队首的剩余时间为0时,先把队首改成p的下一个,然后释放内存,删除队首节点
            if(p->shengyutime == 0)
            {
                if(p == head)
                {
                    head = p->next;
                    free(p);
                    p = head;
                }
                //否则返回执行,把队尾的下一个指针变成p的下一个指针,队尾的位置移动到队首
                else
                {
                    r->next = p->next;
                    p = r->next;
                    r = p;
                }
            }
            //否则把队首的位置给队尾,把队首的状态显示为“就绪”状态
            else
            {
                r = p;
                p->state = "就绪";
                p = p->next;
            }
        }
    }
    printf("执行顺序:\n");
    printf("%s", vec_out[0].c_str());
    for(int i = 1; i < vec_out.size(); i++)
    {
        printf("-->%s", vec_out[i].c_str());
    }
}


void RR_MAIN()
{
    //定义时间片的队首结构体
    struct RR *head;
    // 队首执行的时间
    head = input();
    run(head);
}
void Initial() { //确定进程个数后再初始化
cout<<"请输入作业(进程)个数n=";
cin>>n;
for (int i=0;i<n;i++){
ArrivalTime[i] = 0;
ServiceTime[i] = 0;
FinishTime[i] = 0;
WholeTime[i] = 0;
WeightWholeTime[i] = 0;
AverageWT_SJF = 0;
AverageWWT_SJF = 0;
isFinished_SJF[i] = false;
}
}
void INput(){
int i;
cout<<"请分别输入每个进程的到达时间:"<<endl;
for (i=0;i<n;i++){
cin>>ArrivalTime[i];
}
cout<<"请分别输入每个进程的服务时间:"<<endl;
for (i=0;i<n;i++){
cin>>ServiceTime[i];
}
}
int get_firstProcess(){
int first = MaxNum;
for (int i=0;i<n;i++){
if (ArrivalTime[i]<=ArrivalTime[first]){
first = i;
}
}
return first;
}
void display(){
cout<<"******************************************************"<<endl;
cout<<"进程相关信息如下:"<<endl;
cout<<setw(10)<<"进程名(ID)"<<" ";
cout<<setw(10)<<"到达时间"<<" ";
cout<<setw(10)<<"服务时间"<<" ";
cout<<setw(10)<<"完成时间"<<" ";
cout<<setw(10)<<"周转时间"<<" ";
cout<<setw(10)<<"带权周转时间"<<endl;
for (int i = 0;i<n;i++){
cout<<setw(10)<<i+1<<" ";
cout<<setw(10)<<ArrivalTime[i]<<" ";
cout<<setw(10)<<ServiceTime[i]<<" ";
cout<<setw(10)<<FinishTime[i]<<" ";
cout<<setw(10)<<WholeTime[i]<<" ";
cout<<setw(10)<<WeightWholeTime[i]<<" "<<endl;
}
}
void SJF() {
//与SCSF类似,相同的方法获得第一个进程
int startWorkTime_SJF = 0;  //表示开始执行时间 = 当前进程之前的所有服务时间之和
//第一个进程的处理
int first = get_firstProcess();  //获得第一个进程
isFinished_SJF[first] = true;
FinishTime[first] = ArrivalTime[first] + ServiceTime[first];
startWorkTime_SJF += ServiceTime[first];   //下一个进程的开始执行时间
WholeTime[first] = FinishTime[first] - ArrivalTime[first];   //周转时间 = 完成时间 - 到达时间
WeightWholeTime[first] = (double)WholeTime[first]/ServiceTime[first]; //带权周转时间 = 周转时间/服务时间
//获得下一个进程的下标
int nextProcess_SJF = n;
for (int i=1;i<n;i++){
nextProcess_SJF = n;
for (int j=0;j<n;j++){
if (!isFinished_SJF[j]){
if (ArrivalTime[j]<=startWorkTime_SJF){
if (nextProcess_SJF==n){+
nextProcess_SJF = j;
}
else {
if (ServiceTime[nextProcess_SJF]>ServiceTime[j]){
nextProcess_SJF = j;   //获得运行时间最短的作业的下标
}
}
}
}
}//for(j)
//对获得的进程进行处理
isFinished_SJF[nextProcess_SJF] = true;
FinishTime[nextProcess_SJF] = ServiceTime[nextProcess_SJF] + startWorkTime_SJF;
startWorkTime_SJF += ServiceTime[nextProcess_SJF]; 
WholeTime[nextProcess_SJF] = FinishTime[nextProcess_SJF] - ArrivalTime[nextProcess_SJF];
WeightWholeTime[nextProcess_SJF] = (double)WholeTime[nextProcess_SJF]/ServiceTime[nextProcess_SJF];
}//for(i)
double totalWT = 0;
double totalWWT = 0;
for (i=0;i<n;i++){
totalWT+=WholeTime[i];
totalWWT+=WeightWholeTime[i];
}
AverageWT_SJF = totalWT/n;
AverageWWT_SJF = totalWWT/n;
//输出检测
display();
cout<<"平均周转时间="<<AverageWT_SJF<<endl;
cout<<"平均带权周转时间="<<AverageWWT_SJF<<endl;
cout<<"******************************************************"<<endl;
}



int main(){
while(1){
         cout<<"******************************************************"<<endl;
         cout<<"         1.SJF        "<<endl;
cout<<"         2.优先数     "<<endl;
cout<<"         3.退出       "<<endl;
cout<<"******************************************************"<<endl;
  int c;
cin>>c;
if (c==3)break;
switch(c){
case 1:
        Initial();
   INput();
   SJF();
   break;
    case 2:
RR_MAIN();
break;
}
}
return 0;
}

猜你喜欢

转载自blog.csdn.net/wanwu_fusu/article/details/80270629