package com.test2;
import java.util.ArrayList;
import java.util.Scanner;
/**
* @author : YWJ
* @date : 2022/10/7 : 17:23
*/
public class Test {
static int totalTime;//总周转时间
static double totalTurnTime ;//总带权周转时间
static final int TOTAL_MEMORY = 100;//总内存
static final int TOTAL_TAPE_DRIVE = 4; //总磁盘
static int sumMemory = 0; //以使用内存
static int sumTapeDrive = 0; //已使用磁盘
static ArrayList<Problem> allProblem = new ArrayList<>(); //进程列表
static ArrayList<Problem> inProgress = new ArrayList<>();//正在运行的进程列表
public static void main(String[] args) {
init();//初始化进程列表
fcfs(allProblem);
}
//初始化进程列表
public static void init() {
Scanner sc = new Scanner(System.in);
System.out.print("请输入进程数:");
int num = sc.nextInt();
sc.nextLine();
for (int i = 0; i < num; i++) {
System.out.println("请输入第"+(i+1)+"个作业的名称,开始时间(小时 分钟),所需时间,所需内存,所需磁盘(用空格隔开):");
String[] str = sc.nextLine().split(" ");
allProblem.add(new Problem(str[0], new DateTime(Integer.parseInt(str[1]), Integer.parseInt(str[2])),
Integer.parseInt(str[3]),
Integer.parseInt(str[4]),
Integer.parseInt(str[5])));
}
sc.close();
//按进程开始时间排序
timeSort(allProblem);
}
public static void timeSort(ArrayList<Problem> allProblem){
for (int i = 0; i < allProblem.size() - 1; i++) {
for (int j = 0; j < allProblem.size() - 1 - i; j++) {
if (allProblem.get(j).getStartTime().compareTo(allProblem.get(j + 1).getStartTime()) > 0) {
Problem temp = allProblem.get(j);
allProblem.set(j, allProblem.get(j + 1));
allProblem.set(j + 1, temp);
}
}
}
}
//FCFS(First Come First Severd,先来先服务)
public static void fcfs(ArrayList<Problem> allProblems) {
for (int i = 0; i < allProblems.size(); i++) {
Problem obj = allProblems.get(i);
//判断可执行性
if (obj.getMemory() > TOTAL_MEMORY || obj.getTapeDrive() > TOTAL_TAPE_DRIVE) {
//证明该进程所需空间或磁盘,超出硬件可承受范围
System.out.println(obj.getName() + " 硬件要求过高,无法执行! 已自行跳过...");
continue;
}
//打印信息
System.out.println("正在等待进程 : " + obj.getName());
for (int j = 0; j < inProgress.size(); ) {
if (inProgress.get(j).getEndTime().compareTo(obj.getStartTime()) <= 0) {
remove(j);
}
j++ ;
}
//此时已经剔除早于该进程的进程,
//添加进运行队列
inProgress.add(obj);
//更新系统内存,以及磁盘占用情况
sumTapeDrive += obj.getTapeDrive();
sumMemory += obj.getMemory();
if (i == 0 || inProgress.size() == 0) {
//设置等待时间 为 0;
obj.setWaitTime(0);
//设置结束时间
obj.setEndTime();
System.out.println("进程开始执行 : " + obj.print());
continue;
}
if(sumMemory <= TOTAL_MEMORY && sumTapeDrive <= TOTAL_TAPE_DRIVE){
//设置等待时间 为 0;
obj.setWaitTime(0);
}
while(sumMemory>TOTAL_MEMORY||sumTapeDrive>TOTAL_TAPE_DRIVE) {
//否则不可执行,此时依次移除进程,并设置等待时间
obj.setWaitTime(inProgress.get(0).getEndTime().diff(obj.getStartTime()));
remove(0);
}//设置结束时间
obj.setEndTime();
System.out.println("进程开始执行 : " + obj.print());
}
//最后输出进程信息
for (int i = 0; i < inProgress.size();) {
remove(i);
}
printRe();
System.out.println("平均周转时间: "+totalTime/allProblems.size());
System.out.println("平均带权周转时间 : "+totalTurnTime/allProblems.size());
}
public static void remove(int i){
//同时 释放磁盘空间 内存空间
sumMemory -= inProgress.get(i).getMemory();
sumTapeDrive -= inProgress.get(i).getTapeDrive();
//计算周转时间,带权周转时间
inProgress.get(i).setTurnaroundTime(inProgress.get(i).getEndTime().diff(inProgress.get(i).getStartTime()));
inProgress.get(i).setTurnaroundTimeWithRight((double) inProgress.get(i).getTurnaroundTime() / inProgress.get(i).getDuration());
totalTime += inProgress.get(i).getTurnaroundTime() ;
totalTurnTime += inProgress.get(i).getTurnaroundTimeWithRight();
System.out.println("进程执行结束: " + inProgress.get(i).getName());
inProgress.remove(i);
}
public static void printRe(){
System.out.println("所有进程执行完毕");
for (Problem problem : allProblem) {
System.out.println(problem);
}
}
}
class Problem{//进程类
private final String name ;
private final DateTime startTime ;
private final int duration ; //耗时
private final int memory ;// 内存
private final int tapeDrive ;//磁盘
private DateTime endTime ;
private int waitTime ;//等待时间
private int turnaroundTime ; //周转时间
private double turnaroundTimeWithRight ; //带权周转时间
public int getTurnaroundTime() {
return turnaroundTime;
}
public double getTurnaroundTimeWithRight() {
return turnaroundTimeWithRight;
}
public Problem(String name , DateTime startTime, int duration, int memory, int tapeDrive) {
this.name = name ;
this.startTime = startTime;
this.duration = duration;
this.memory = memory;
this.tapeDrive = tapeDrive;
}
public String getName() {
return name;
}
public DateTime getStartTime() {
return startTime;
}
public int getDuration() {
return duration;
}
public DateTime getEndTime() {
return endTime;
}
public void setEndTime() {
this.endTime = new DateTime(0,0).addTime(startTime,waitTime,duration);
}
public int getMemory() {
return memory;
}
public void setWaitTime(int waitTime) {
this.waitTime = waitTime;
}
public int getTapeDrive() {
return tapeDrive;
}
public void setTurnaroundTime(int turnaroundTime) {
this.turnaroundTime = turnaroundTime;
}
public void setTurnaroundTimeWithRight(double turnaroundTimeWithRight) {
this.turnaroundTimeWithRight = turnaroundTimeWithRight;
}
public String print() {
return name+" {" +
" startTime=" + startTime +
", duration=" + duration +
", memory=" + memory +
", tapeDrive=" + tapeDrive +
'}';
}
@Override
public String toString() {
return name +"{" +
" startTime=" + startTime +
", duration=" + duration +
", memory=" + memory +
", tapeDrive=" + tapeDrive +
", endTime=" + endTime +
", waitTime=" + waitTime +
", turnaroundTime=" + turnaroundTime +
", turnaroundTimeWithRight=" + turnaroundTimeWithRight +
'}';
}
public int getWaitTime() {
return this.waitTime;
}
}
class DateTime implements Comparable<DateTime>{
private int h ;
private int m ;
public DateTime(int h, int m) {
if (h<0||h>23||m<0||m>59) {
this.h = 0;
this.m = 0;
return ;
}
this.h = h;
this.m = m;
}
public int getH() {
return h;
}
public int getM() {
return m;
}
public DateTime addTime(DateTime startTime,int m1 , int m2){
m = m1 + m2 ;
this .h = startTime.getH()+m/60 ;
this.m = startTime.getM()+m%60 ;
if(this.m > 60){
this.h += 1 ;
this.m -= 60 ;
}
return this ;
}
public int diff(DateTime startTime){
return (h*60+ m) - (startTime.h*60+startTime.m);
}
@Override
public String toString() {
return h + " : "+String.format("%02d",m) ;
}
@Override
public int compareTo(DateTime o) {
if(this.h == o.h && this.m == o.m) return 0 ;
if(this.h>o.h) return 1 ;
if(this.h<o.h) return -1 ;
if(this.m>o.m) return 1 ;
return -1 ;
}
}
运行结果