RR算法(时间片轮转)
package experiment;
import java.util.Queue;
import java.util.Scanner;
import java.text.DecimalFormat;
import java.util.LinkedList;
class Process
{
private String Name; //进程名称
private int ArrivalTime; //到达时间
private int ServiceTime;//服务时间
private int HasServiceTime;//已经服务时间
private int FinishTime; //完成时间
private int WholeTime;//周转时间
private double WeightWholeTime; //带权周转时间
Process()
{}
Process(String Name,int ArrivalTime,int ServiceTime)
{
this.Name=Name;
this.ArrivalTime=ArrivalTime;
this.ServiceTime=ServiceTime;
}
public String getName() {
return Name;
}
public void setName(String name) {
Name = name;
}
public int getArrivalTime() {
return ArrivalTime;
}
public void setArrivalTime(int arrivalTime) {
ArrivalTime = arrivalTime;
}
public int getServiceTime() {
return ServiceTime;
}
public void setHasServiceTime(int hasServiceTime) {
HasServiceTime = hasServiceTime;
}
public int getHasServiceTime() {
return HasServiceTime;
}
public void setServiceTime(int serviceTime) {
ServiceTime = serviceTime;
}
public int getFinishTime() {
return FinishTime;
}
public void setFinishTime(int finishTime) {
FinishTime = finishTime;
}
public int getWholeTime() {
return WholeTime;
}
public void setWholeTime(int wholeTime) {
WholeTime = wholeTime;
}
public double getWeightWholeTime() {
return WeightWholeTime;
}
public void setWeightWholeTime(double weightWholeTime) {
WeightWholeTime = weightWholeTime;
}
public void WholeTime(Process[]process)
{
//求进程的周转时间
for(int i=0;i<process.length;i++)
process[i].setWholeTime(process[i].getFinishTime()-process[i].getArrivalTime());
}
public void WeightWholeTime(Process[]process)
{
//求进程的带权周转时间
DecimalFormat a = new DecimalFormat(".##");
for(int i=0;i<process.length;i++)
process[i].setWeightWholeTime(Double.parseDouble( a.format((double)process[i].getWholeTime()/(double)process[i].getServiceTime())));
}
public double AVG_WholeTime(Process[]process)
{
//求进程的平均周转时间
double AVG_WholeTime=0;
for(int i=0;i<process.length;i++)
AVG_WholeTime=AVG_WholeTime+process[i].getWholeTime();
DecimalFormat a = new DecimalFormat(".##");
return (Double.parseDouble(a.format(AVG_WholeTime/process.length)));
}
public double AVG_WeightWholeTime(Process[]process)
{
//求进程的平均带权周转时间
double AVG_WeightWholeTime=0;
for(int i=0;i<process.length;i++)
AVG_WeightWholeTime=AVG_WeightWholeTime+process[i].getWeightWholeTime();
DecimalFormat a = new DecimalFormat(".##");
return (Double.parseDouble(a.format(AVG_WeightWholeTime/process.length)) );
}
public void Print(Process[]process)
{
for (int i = 0; i < process.length; i++)
{
System.out.println("第" + (i + 1) + "个进程的名称是" + process[i].getName() + " " + "到达时间是" + process[i].getArrivalTime() + " " + "服务时间是" + process[i].getServiceTime() + " " + "完成时间是" + process[i].getFinishTime() + " " + "周转时间是" + process[i].getWholeTime() + " " + "带权周转时间是" + process[i].getWeightWholeTime());
}
}
public void RR(Process[] process,int q,int skip)
{
int count=0;//标记进程完成个数
int time=0; //记录q_时间
int nowtime=0; //记录当前时间
Queue<Integer> queue = new LinkedList<Integer>(); //创建一个队列,用于队列的排队
for (int i = 0; i < process.length; i++)
{
//找到到达时间为0的进程,加入队列
if (process[i].getArrivalTime() == nowtime)
queue.add(i);
}
while(!queue.isEmpty())
{
int k = queue.peek();//返回队列首个元素,但不移除
time=time+q;
while(nowtime!=time )
{
nowtime++;
//增加判断条件减少判断到达次数
if(process.length-queue.size()!=count)
{
//如果进程个数减去队列中排队的进程数量!=进程完成个数,就说明还有进程未到达(未加入队列),则需要遍历队列
for (int i = 0; i < process.length; i++)
{
if (process[i].getArrivalTime() == nowtime)
{
if(process[i].getArrivalTime()!=0)//到达时间为0的进程在前面已经加入,所以不需要再加入队列
queue.add(i);
System.out.println("时刻" + nowtime + "进程" + process[i].getName() + "到达");
}
}
}
process[k].setHasServiceTime(process[k].getHasServiceTime() + 1);//+1是因为执行一个时间单位
if(!queue.isEmpty())
System.out.println("时刻"+nowtime+"进程"+process[k].getName()+"正在执行");
if (process[k].getHasServiceTime() == process[k].getServiceTime())
{
System.out.println("时刻" + nowtime + "进程" + process[k].getName() + "完成");
process[k].setFinishTime(nowtime);
queue.poll();
count++;//若当前进程完成则++
if(nowtime!=time)
{
//处理进程完成后还剩余的时间
//skip==1则不跳过剩余时间
if(skip==1)
{
//根据当前时间判断下一个进程是否到达到达
//到达则直接执行,未到达则时间+1,直到有进程到达
if(!queue.isEmpty())
{
int peek=queue.peek();
while(process[peek].getArrivalTime()<=nowtime)
{
k=peek;
break;
}
if(process[peek].getArrivalTime()>nowtime)
{
System.out.println("时刻"+nowtime+"空闲");
nowtime++;
}
}
}
else
{
//skip为其他则跳过当前的空闲时间
for(int t=nowtime;t<time;t++)
System.out.println("时刻"+(t+1)+"空闲");
nowtime=time;
}
}
}
}
if (process[k].getHasServiceTime() != process[k].getServiceTime()&&process[k].getHasServiceTime()==q)
{
//如果执行完一个时间片之后还未完成
if(!queue.isEmpty())
{
int peek=queue.peek();//将队列的第一个进程保存
queue.add(peek);
queue.remove();
}
}
}
}
}
public class Experiment {
// 进程个数为5
// q=1时预期输出结果如下
// 名称 到达时间 服务时间 完成时间 周转时间 带权周转时间 平均周转时间为 11.2 平均带权周转时间为3.35
// A 0 4 12 12 3.0
// B 1 3 10 9 3.0
// C 2 4 16 14 3.5
// D 3 2 11 8 4.0
// E 4 4 17 13 3.25
// q=4时预期输出结果如下
// 名称 到达时间 服务时间 完成时间 周转时间 带权周转时间 平均周转时间为9.4 平均带权周转时间为 3.0
// A 0 4 4 4 1.0
// B 1 3 7 6 2.0
// C 2 4 12 10 2.25
// D 3 2 14 11 5.5
// E 4 4 20 16 4.0
public static void main(String[] args) {
// System.out.println("请输入进程个数:");
// Scanner Input=new Scanner(System.in);
// int num=Input.nextInt();
// Process [] process=new Process[num];
// for(int i=0;i<num;i++)
// {
// System.out.println("请输入第"+(i+1)+"个进程的名称,到达时间,服务时间");
// String name=Input.next();
// int arrivalTime=Input.nextInt();
// int ServiceTime=Input.nextInt();
// process[i]=new Process(name,arrivalTime,ServiceTime);
// }
// System.out.println("请输入时间片大小q:");
// int q=Input.nextInt();
// Input.close();
// new Process().RR(process, q);
// new Process().WholeTime(process);
// new Process().WeightWholeTime(process);
// new Process().Print(process);
// System.out.println("平均周转时间为"+new Process().AVG_WholeTime(process));
// System.out.println("平均带权周转时间为"+new Process().AVG_WeightWholeTime(process));
int q=1;
// int q=4;
Process [] process=new Process[5];
process[0]=new Process("A",0,4);
process[1]=new Process("B",1,3);
process[2]=new Process("C",2,4);
process[3]=new Process("D",3,2);
process[4]=new Process("E",4,4);
// System.out.println("当有进程已完成而时间片未结束时,是否将剩余的时间分配给下一个已到达的进程,是则输入1,输入其他则视为不分配");
// int skip=Input.nextInt();
int skip=1;
new Process().RR(process, q,skip);
new Process().WholeTime(process);
new Process().WeightWholeTime(process);
new Process().Print(process);
System.out.println("平均周转时间为"+new Process().AVG_WholeTime(process));
System.out.println("平均带权周转时间为"+new Process().AVG_WeightWholeTime(process));
}
}