单通短作业优先算法,求其平均周转时间。
场景:
4个任务同时到达(J1(1),J2(4),J3(10),J4(7),括号中的值是需要的执行时间),每次只能执行一个任务,那么短作业优先算法按任务照执行时间的大小,优先执行时间短的任务,也就说执行顺序是J1,J2,J4,J3。执行的过程如下所示
执行顺序 | 执行时间 | 周转时间(等待时间 + 执行时间) |
J1 | 1 | 1 |
J2 | 4 | 5 |
J4 | 7 | 12 |
J3 | 10 | 22 |
10(平均周转时间) |
java实现上述算法:
package com.sirding.testalgo;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import org.junit.Before;
import org.junit.Test;
/**
* @Described : Spf = Shortest Process First.最短优先算法
* @project : com.sirding.testalgo.Spn
* @author :
* @date :
*/
public class Spf {
private List<SpfJob> jobList = new ArrayList<SpfJob>();
private long[] arr = {1, 4, 10, 7};
/**
* @Described : 单通道多任务不同时到达
* @author :
* @date :
*/
// @Before
public void diffTime(){
long start = System.currentTimeMillis();
for(long tmp : arr){
jobList.add(new SpfJob(start + (int)(Math.random()*100), tmp));
}
sortList();
}
/**
* @Described : 单通道多任务同时到达
* @author :
* @date :
*/
@Before
public void sameTime(){
long start = System.currentTimeMillis();
for(long tmp : arr){
jobList.add(new SpfJob(start, tmp));
}
sortList();
}
private void sortList() {
Collections.sort(jobList, new Comparator<SpfJob>() {
@Override
public int compare(SpfJob o1, SpfJob o2) {
return (int)(o1.execTime - o2.execTime);
}
});
}
/**
* @Described : 单通道最短优先算法-计算平均周转时间
* 测试用例:
* 多个任务同时到达,sameTime()初始化数据
* @author : zc.ding
* @date :
*/
@Test
public void test(){
// 方式一:逐步计算每个任务的周转时间
long total = 0;
long costTime = 0;
for(SpfJob job : jobList){
costTime = (costTime + job.getExecTime());
total += costTime;
System.out.println("job_" + job.execTime + "周转时间:" + costTime);
}
// 方法二:通过阶乘的方式计算
// for(int i = 0; i < jobList.size(); i++){
// total += (jobList.size() - i) * jobList.get(i).getExecTime();
// }
System.out.println("总周转时间:" + total);
System.out.println("平均周转时间:" + ((double)total/(double)jobList.size()));
}
/**
* @Described : 任务信息
* @project : com.sirding.testalgo.SpfJob
* @author : zc.ding
* @date :
*/
static class SpfJob implements Serializable{
/**
*
*/
private static final long serialVersionUID = 1L;
//到达时间
private long arrivalTime;
//执行时间
private long execTime;
//任务开始时间
private long startTime;
//任务结束时间
private long endTime;
//周转时间
private long totalTime;
public SpfJob(){}
public SpfJob(long startTime, long execTime){
this.startTime = startTime;
this.execTime = execTime;
}
public long getArrivalTime() {
return arrivalTime;
}
public void setArrivalTime(long arrivalTime) {
this.arrivalTime = arrivalTime;
}
public long getExecTime() {
return execTime;
}
public void setExecTime(long execTime) {
this.execTime = execTime;
}
public long getStartTime() {
return startTime;
}
public void setStartTime(long startTime) {
this.startTime = startTime;
}
public long getEndTime() {
return endTime;
}
public void setEndTime(long endTime) {
this.endTime = endTime;
}
public long getTotalTime() {
return totalTime;
}
public void setTotalTime(long totalTime) {
this.totalTime = totalTime;
}
}
}
上述提供了两种实现方式,一种以常规累加的方式进行计算,一种以类似阶乘的方式进行计算。
场景二:
多任务不同时到达,那么要采用的要是应该是FCFS(先来先服务)算法。其周转时间计算过程同场景一中常规计算方式一致。