短进程优先算法(C,Java实现)
2017-10-26 17:03
155 查看
复制代码的时候:最好点下图 [cpp] 旁边的那个标签进行复制,不然可能代码编译不了。
在短进程优先算法中需要注意:下一个进程是已经到达且运行时间最短的进程。
输入如下:
4
A 8.00 2.00
B 8.50 0.50
C 9.00 0.10
D 9.50 0.20
输出如下:
C代码:
Java代码:
如果你想实现以下效果:
可以将java代码的第 56- 66行代码换成以下代码:
如果你要实现FCFS(先到先服务算法):
将C的第61行代码换成 int p = i; 将Java代码的第59行代码也换成 int p = i;
即可实现。
在短进程优先算法中需要注意:下一个进程是已经到达且运行时间最短的进程。
输入如下:
4
A 8.00 2.00
B 8.50 0.50
C 9.00 0.10
D 9.50 0.20
输出如下:
C代码:
#include <stdio.h> #include <stdlib.h> #define INF 1000000.0 struct PCB { char id[10]; // 进程ID double reachTime; // 进程到达的时间 double needTime; // 进程完成需要的时间 double startTime; // 进程开始的时刻 double finishTime; // 进程完成的时刻 double cTime; // 进程周转时间 double wcTime; // 进程带权周转时间 char state; // 进程的状态( 设每个进程处于就绪R(ready),完成F(finish)两种状态之一 ) }; /* 两种情况: 1.在lastTime时刻,选择已经到达且拥有最短运行时间的进程 2.在lastTime时刻,没有进程到达,此时选择拥有最早到达时间的进程 */ int findNext( struct PCB arr[], int length, double lastTime ) { // p是已经到达且拥有最短运行时间的进程的下标 // q是没有到达的进程中拥有最早到达时间的进程的下标 int i, p, q; double minNeedTime, minReachTime; p = q = -1; minNeedTime = minReachTime = INF; for( i = 0; i < length; i++ ) { if( arr[i].state=='R' ) { // 进程处就绪状态 // 第一情况 if( arr[i].reachTime<=lastTime && arr[i].needTime<minNeedTime ) { p = i; minNeedTime = arr[i].needTime; } // 第二种情况 if( arr[i].reachTime>lastTime && arr[i].reachTime<minReachTime ) { q = i; minReachTime = arr[i].reachTime; } } } // p为-1时,代表在lastTime时刻还没进程到达,此时选择下一个最早到达的进程q if( p != -1 ) return p; return q; } int main() { int num, i; double lastTime; // 为上一个进程的完成时间,用来确定当前进程的开始时间 struct PCB *arr; printf( "请输入进程数:" ); scanf( "%d", &num ); arr = (struct PCB*)malloc(num*sizeof(struct PCB)); lastTime = INF; // 最开始lastTime的为第一个作业的reachTime(到达时间) printf( "请依次输入进程ID,进程到达时间,进程运行时间:\n" ); for( i = 0; i < num; i++ ) { scanf( "%s%lf%lf", arr[i].id, &arr[i].reachTime, &arr[i].needTime ); arr[i].state = 'R'; if( lastTime>arr[i].reachTime ) lastTime = arr[i].reachTime; } // sum1为所有进程周转时间之和,sum2为所有进程带权周转时间之和 double sum1=0.0, sum2=0.0; for( i = 0; i < num; i++ ) { int p = findNext( arr, num, lastTime ); // 找到下一个将要执行的进程 // 两种情况:将要执行的进程可能已经到达,或者还没到达 if( arr[p].reachTime<=lastTime ) arr[p].startTime = lastTime; else arr[p].startTime = arr[p].reachTime; // 确定进程的完成时间,周转时间,带权周转时间 arr[p].finishTime = arr[p].startTime + arr[p].needTime; arr[p].cTime = arr[p].finishTime - arr[p].reachTime; arr[p].wcTime = arr[p].cTime/arr[p].needTime; arr[p].state = 'F'; sum1 += arr[p].cTime; sum2 += arr[p].wcTime; lastTime = arr[p].finishTime; // 更新lastTime } printf( "\n进程 到达时间 运行时间 开始时间 完成时间 周转时间 带权周转时间\n" ); for( i = 0; i < num; i++ ) { printf( "%4s %8.2lf %8.2lf ", arr[i].id, arr[i].reachTime, arr[i].needTime ); printf( "%8.2lf %8.2lf ", arr[i].startTime, arr[i].finishTime ); printf( "%8.2lf %12.2lf\n", arr[i].cTime, arr[i].wcTime ); } printf( "平均周转时间: %.3lf\n", sum1/num ); printf( "平均带权周转时间: %.3lf\n", sum2/num ); return 0; }
Java代码:
import java.util.Scanner; import java.util.Arrays; public class Main { // 接口Comparable和类方法Arrays.sort()的配合使用可以使进程按reachTime(到达时间)排序 private static class PCB implements Comparable<PCB> { String id; float reachTime; float needTime; float startTime; float finishTime; char state; public int compareTo( PCB b ) { if( reachTime==b.reachTime ) return 0; if( reachTime<b.reachTime ) return -1; return 1; } } private static final float INF = 10000000.0f; /* 两种情况: 1.在lastTime时刻,选择已经到达且拥有最短运行时间的进程 2.在lastTime时刻,没有进程到达,此时选择拥有最早到达时间的进程 */ private static int findNext( PCB[] arr, float lastTime ) { int i, p = -1; float minNeedTime = INF; for( i = 0; i < arr.length; i++ ) { if( arr[i].state=='R' ) { /* 数组arr已经按reachTime排序,当出现 arr[i].reachTime>lastTime时,说明在lastTime时刻无进程到达,终止循环.*/ if( arr[i].reachTime > lastTime ) break; if( arr[i].needTime < minNeedTime ) { p = i; minNeedTime = arr[i].needTime; } } } if( p != -1 ) return p; return i; } public static void main( String[] args ) { Scanner sc = new Scanner( System.in ); System.out.print( "请输入进程数:" ); int num = sc.nextInt(); PCB[] arr = new PCB[num]; System.out.println( "请依次输入进程ID,进程到达时间,进程运行时间:" ); for( int i = 0; i < num; i++ ) { arr[i] = new PCB(); arr[i].id = sc.next(); arr[i].reachTime = sc.nextFloat(); arr[i].needTime = sc.nextFloat(); arr[i].state = 'R'; } Arrays.sort(arr); // 使进程按reachTime(到达时间)排序 float lastTime=arr[0].reachTime; for( int i=0; i<num; i++ ) { // 找到下一个将要执行的进程 int p = findNext( arr, lastTime ); if( arr[p].reachTime<lastTime ) arr[p].startTime = lastTime; else arr[p].startTime = arr[p].reachTime; arr[p].finishTime = arr[p].startTime + arr[p].needTime; arr[p].state = 'F'; lastTime = arr[p].finishTime; // 更新lastTime } float sum1=0.0f, sum2=0.0f; System.out.println( "\n进程 到达时间 运行时间 开始时间 完成时间 周转时间 带权周转时间" ); for( PCB jcb : arr ) { System.out.format( "%4s %8.2f %8.2f ", jcb.id, jcb.reachTime, jcb.needTime ); System.out.format( "%8.2f %8.2f ", jcb.startTime, jcb.finishTime ); System.out.format( "%8.2f ", jcb.finishTime-jcb.reachTime ); System.out.format( "%12.2f\n", (jcb.finishTime-jcb.reachTime)/jcb.needTime ); sum1 += jcb.finishTime-jcb.reachTime; sum2 += (jcb.finishTime-jcb.reachTime)/jcb.needTime; } System.out.format( "平均周转时间: %.3f\n", (sum1/num) ); System.out.format( "平均带权周转时间: %.3f", (sum2/num) ); } }
如果你想实现以下效果:
可以将java代码的第 56- 66行代码换成以下代码:
/* 此时设每个进程处于就绪R(ready),运行E(excecuting),完成F(finish)三种状态之一, 并假设起始状态都是就绪状态 ) */ int p = 0, cnt = 0; for( float time=arr[p].reachTime; cnt<num; time+=0.1 ) { if( arr[p].reachTime<=time && arr[p].state=='R' ) { arr[p].startTime = time; // 记录开始时间 arr[p].state = 'E'; System.out.format( "在%.2f时刻: ", time ); System.out.format( "进程%s开始运行\n", arr[p].id ); } else if( time-arr[p].startTime<arr[p].needTime && arr[p].state=='E' ) { System.out.format( "在%.2f时刻: ", time ); System.out.format( "进程%s正在运行\n", arr[p].id ); } else if( time-arr[p].startTime>=arr[p].needTime && arr[p].state=='E' ) { arr[p].finishTime = time; // 记录完成时间 arr[p].state = 'F'; System.out.format( "在%.2f时刻: ", time ); System.out.format( "进程%s完成运行\n\n", arr[p].id ); p = findNext( arr, time ); // 找到下一个要执行的进程 time -= 0.1; // 这个很重要,用于结束时刻是否将有进程运行 cnt++; // 已经完成cnt个进程 } }
如果你要实现FCFS(先到先服务算法):
将C的第61行代码换成 int p = i; 将Java代码的第59行代码也换成 int p = i;
即可实现。
相关文章推荐
- 数据结构和算法之:图的深度优先和广度优先遍历及其Java实现
- 进程的优先调度算法的c语言实现
- java按时间片轮转进程调度算法实现
- Java模拟操作系统进程调度算法—先来先服务、短作业优先、高响比优先
- 从Cheney算法->广度优先搜索->倒酒问题(JAVA实现)
- java实现操作系统中的页面置换算法、进程调度算法、磁盘调度算法
- java_实现先来先服务(FCFS)短作业优先算法(SJF)
- 操作系统进程调度算法(Java 实现)
- 操作系统进程调度算法(Java 实现)
- 算法(第四版)学习笔记之java实现基于堆的优先队列
- 操作系统进程调度算法(Java 实现)
- 图及其算法复习(Java实现) 一:存储结构,深度优先周游,广度优先周游
- 操作系统进程调度算法(Java 实现)
- [置顶] Java模拟最短作业优先、时间片轮转、最高响应比三种进程调度算法
- 操作系统进程调用的5种算法 java实现
- 操作系统进程调度算法(Java 实现)
- java按优先权调度进程算法实现
- Dijkstra 算法用优先队列的java实现
- java按时间片轮转进程调度算法实现
- 进程调度-优先级算法(Java简单实现)