首先:这不是家庭作业,这是我朋友的作业,她已经完成并提交了,我很好奇它是如何工作的,因为我以前从未写过队列模拟,并决定给它一个机会。
基本上,我们得到了一个Job ADT,并且应该编写一个具有常规队列操作(如delete()和insert())的功能Queue ADT。使用这两个ADTS,我试图编写一个作业队列模拟,其中有一个输入文件,在第1行上列出:要处理的作业数量,文件中的所有其他行都有一对数字,表示每行上每个作业的到达时间和持续时间。作业比处理器多,作业由(到达时间、持续时间、完成时间)组成。
模拟的目标是确定
- 总等待时间
- 最大等待时间
- 平均等待时间。
我已经写了一个基于LinkedList
的功能队列ADT,但我非常失落,我应该如何在Simulation
文件中使用Job
ADT和Queue
ADT。我知道我的队列ADT工作,所以我只是包括接口文件,以节省空间。我也有一些代码和一些伪代码的模拟文件,我一直在工作。如果我能得到一点推动/一些示例代码,我可能会找到我的方式从那里。请帮助!:)谢谢你
示例输入文件:
3,
2 2,
3 4,
5 6,
input.rpt
文件(由simulation.java创建的报告文件):报告文件:
3 Jobs:
(2, 2, *) (3, 4, *) (5, 6, *)
***********************************************************
1 processor: totalWait=4, maxWait=3, averageWait=1.33
2 processors: totalWait=0, maxWait=0, averageWait=0.00
input.trc
文件(由simulation.java创建的跟踪文件):跟踪文件:
3 Jobs:
(2, 2, *) (3, 4, *) (5, 6, *)
*****************************
1 processor:
*****************************
time=0
0: (2, 2, *) (3, 4, *) (5, 6, *)
1:
time=2
0: (3, 4, *) (5, 6, *)
1: (2, 2, 4)
time=3
0: (5, 6, *)
1: (2, 2, 4) (3, 4, *)
time=4
0: (5, 6, *) (2, 2, 4)
1: (3, 4, 8)
time=5
0: (2, 2, 4)
1: (3, 4, 8) (5, 6, *)
time=8
0: (2, 2, 4) (3, 4, 8)
1: (5, 6, 14)
time=14
0: (2, 2, 4) (3, 4, 8) (5, 6, 14)
1:
*****************************
2 processors:
*****************************
time=0
0: (2, 2, *) (3, 4, *) (5, 6, *)
1:
2:
time=2
0: (3, 4, *) (5, 6, *)
1: (2, 2, 4)
2:
time=3
0: (5, 6, *)
1: (2, 2, 4)
2: (3, 4, 7)
time=4
0: (5, 6, *) (2, 2, 4)
1:
2: (3, 4, 7)
time=5
0: (2, 2, 4)
1: (5, 6, 11)
2: (3, 4, 7)
time=7
0: (2, 2, 4) (3, 4, 7)
1: (5, 6, 11)
2:
time=11
0: (2, 2, 4) (3, 4, 7) (5, 6, 11)
1:
2:
Job ADT:
import java.io.*;
public class Job{
public static final int UNDEF = -1;
private int arrival;
private int duration;
private int finish;
// default constructor
public Job(int arrival, int duration){
this.arrival = arrival;
this.duration = duration;
this.finish = UNDEF;
}
// access functions
public int getArrival(){return arrival;}
public int getDuration(){return duration;}
public int getFinish(){return finish;}
public int getWaitTime(){
if( finish==UNDEF ){
System.err.println("Job: getWaitTime(): undefined finish time");
System.exit(1);
}
return finish-duration-arrival;
}
// manipulation procedures
public void computeFinishTime(int timeNow){finish = timeNow + duration;}
public void resetFinishTime(){finish = UNDEF;}
// toString
// overrides Object's toString() method
public String toString(){
return "("+arrival+", "
+duration+", "
+(finish==UNDEF?"*":String.valueOf(finish))+")";
}
}
Queue Interface:列出Queue ADT执行的操作
public interface QueueInterface{
// isEmpty()
// pre: none
// post: returns true if this Queue is empty, false otherwise
public boolean isEmpty();
// length()
// pre: none
// post: returns the length of this Queue.
public int length();
// enqueue()
// adds newItem to back of this Queue
// pre: none
// post: !isEmpty()
public void enqueue(Object newItem);
// dequeue()
// deletes and returns item from front of this Queue
// pre: !isEmpty()
// post: this Queue will have one fewer element
public Object dequeue() throws QueueEmptyException;
// peek()
// pre: !isEmpty()
// post: returns item at front of Queue
public Object peek() throws QueueEmptyException;
// dequeueAll()
// sets this Queue to the empty state
// pre: !isEmpty()
// post: isEmpty()
public void dequeueAll() throws QueueEmptyException;
// toString()
// overrides Object's toString() method
public String toString();
}
目前为止我在Simulation.java中有什么
import java.io.*;
import java.util.Scanner;
import java.util.Queue;
import java.util.Job;
public class Simulation{
public static Job getJob(Scanner in) {
String[] s = in.nextLine().split(" ");
int a = Integer.parseInt(s[0]);
int d = Integer.parseInt(s[1]);
return new Job(a, d);
}
public static void main(String[] args) throws IOException{
Scanner in = null;
PrintWriter in.rpt = null;
PrintWriter in.trc = null;
in = new Scanner(new File(args[0]);
in.rpt = new PrintWriter(new FileWriter);
in.trc = new PrintWriter(new FileWriter);
in.useDelimiter("n");
int m = in.next();
for(int i = 1; i<m; i++){
System.out.println(getJob(Scanner in));
}
int n = 1;
while(n<m){
Queue[] Processors = new Queue[n];
Processor[0] = new Queue();
Queue[] Backup = new Queue[n];
// Pseudo code for Simulation
// 1. check command line arguments
//
// 2. open files for reading and writing
//
// 3. read in m jobs from input file
//
// 4. run simulation with n processors for n=1 to n=m-1 {
//
// 5. declare and initialize an array of n processor Queues and any
// necessary storage Queues
//
// 6. while unprocessed jobs remain {
//
// 7. determine the time of the next arrival or finish event and
// update time
//
// 8. complete all processes finishing now
//
// 9. if there are any jobs arriving now, assign them to a processor
// Queue of minimum length and with lowest index in the queue array.
//
// 10. } end loop
//
// 11. compute the total wait, maximum wait, and average wait for
// all Jobs, then reset finish times
//
// 12. } end loop
//
// 13. close input and output files
作为Java(我的第一门编程语言)的学习者,我在为作业和爱好设计程序时遇到了类似的心理障碍。因此,我觉得我最近克服类似的类交互困惑的经验可能会对OP有所帮助,而且社区提供的任何关注设计过程而不是代码片段的答案都会对OP、其他学习者和我都有帮助。
分解需求:
- 总等待时间不需要在处理每个作业时存储有关单个作业的数据。在Simulation中维护一个int实例变量,该变量由等待的每个Job和等待的数量增加,最终包含总等待时间。
- 平均等待时间仅用total除以m,不需要实例变量。
- 最大等待时间是我发现自己在寻求灵感的问题,所以我会详细说明我的过程,希望它能成为你需要的"推动力"。
示例报告文件提供了关于必要结构的线索,以及触发报告的状态更改。"Time:x"行表明您需要人为地保持时间,并且该代码片段中的所有内容都将循环,包括报告。伪代码第6步中的循环是看起来合理的最早的循环。
行仅在作业启动或完成时打印到报告中,而不是每次"时钟"增加时打印可能相同的报告。作业在脱离队列时启动,那么空队列真的意味着没有作业在处理吗?这个问题的答案决定了某些片段在逻辑结构中的位置。
job . getwaittime()只会在作业启动后返回一个值。完成时间由Job. computefinishtime()通过传递作业到达处理器的时间来计算,并且不需要通过时间来设置完成时间。只在适当的时候调用这个方法。
我的一个新手错误是将所有的等待时间存储在一个数组中,而不是只存储到目前为止看到的最大值。我想没有必要存储更多,Simulation应该有一个实例变量来存储它。
如果您取得了进展,我会发现在您的下一个断点处查看代码是有指导意义的。
注:我(初学者)对ADT的理解是,Queue ADT在泛型中更好,或者专门为作业而不是对象编写。