【实验】模拟FIFO网络打印机

放肆的年华 提交于 2020-02-22 13:51:27

Experiment 2 Printer Simulation: FIFO(4 hours)

Prerequisites: Students should have mastered the following prerequisite skills.

  • Inheritance - Declaring and defining derived classes
  • Queues - Programming queue structure

Goals: This assignment is designed to reinforce the student’s understanding of queues.

Outcomes: Students successfully completing this assignment would master the following outcomes.

  • Program a queue data structure and use it in creating a simulation
  • Use inheritance appropriately to create a specialized version of an existing class

Background
    From store-and-forward queues in network routers to the facilitation of breadth-first searches in graph algorithms, queues have many important applications in Computer Science and Information Technology. One such application can be found in a policy used by networked printers to manage print jobs. A complicated policy involves the prioritization of jobs that come from certain users. A simpler approach is a first-in-first-out policy. This policy dictates that print jobs are processed in the order they are received. A queue is used to implement this first-in-first-out policy.

Description
    This assignment tests your understanding of queues and your ability to program a queue structure. The program you are asked to finish the implementation of simulates a shared printer. This printer uses a first-in-first-out queue.
    The simulation works by reading and processing a list of events from a data file. Each line in a valid data file contains information about a print job and a time when this job was submitted. Specifically, the information contained in each line is the time (in seconds) the job was submitted, the length in pages of the job, and the name of the computer from which the job was submitted. At the beginning of the simulation, each of these events should be read in by the program and stored in the inherited workload queue.
    The program should simulate the passage of time by incrementing a counter inside a for-loop or while-loop. The program should initialize this counter to zero and increment it by one second. A print job “arrives” when the current time of the simulation equals the submitted time of the print job at the front of the workload queue. When this happens, pop this event from the workload queue and place it in another Queue object. This other Queue object stores the “arrived” print jobs. These jobs wait in this queue while the program simulates the printing of other jobs. Hence, you may want to name this object waiting or something similar.

Files
Following is a list of files needed to complete this assessment.

  • arbitrary.run - Data file containing arbitrary print jobs
  • arbitrary.out - Output from a sample solution when run using arbitrary.run
  • bigfirst.run - Data file containing larger jobs first
  • bigfirst.out - Output from a sample solution when run using bigfirst.run

Tasks

  • To complete this assessment, you need to declare and implement the following classes.
  • To begin, verify the files needed for this assessment.
  • Extract the archive to retrieve the files needed to complete this assessment.
  • Following is an ordered list of steps that serves as a guide to completing this assessment. Work and test incrementally. Save often.
    • Write your Queue structure class.
    • Write the class Job, which represents a printing job and should have the following 2 data members: “string user” and “int number_of_pages”.
    • Write the class Event, which represents a submitted printing event and should have the following 2 data members: “job j” and “int arrival_time”.
    • Write the class Simulator to simulate a networked printer. It should have the following 2 data members: “int seconds_per_page” and “Queue<Event> workload”. seconds_per_page data member determines how long a print job takes to print. This class should provide a member function “loadWorkLoad” to load the printing event data from corresponding files.
    • Write a class Fifo which is a subclass of Simulator appropriately to model the following relationship: a fifo is a type of simulator. Next, define a method “simulate” to implement the simulation as described above. Your solution’s output should match the output from the sample solutions.

For clarity, the word “latency” in the output file is the number of seconds that elapse between when a print job arrives and when it begins printing. Aggregate latency is the total latency of all print jobs, and mean latency is the average latency across all print jobs.

Submission
Submit all the codes you need to complete.

数据文件

arbitrary.run

2 2 platypus
3 6 herring
4 1 falcon
5 1 giraffe
5 10 aardvark
5 7 dolphin
11 2 eagle

arbitrary.out

FIFO Simulation 

      Arriving: 2 pages from platypus at 2 seconds
      Servicing: 2 pages from platypus at 2 seconds
      Arriving: 6 pages from herring at 3 seconds
      Arriving: 1 page from falcon at 4 seconds
      Arriving: 1 page from giraffe at 5 seconds
      Arriving: 10 pages from aardvark at 5 seconds
      Arriving: 7 pages from dolphin at 5 seconds
      Servicing: 6 pages from herring at 6 seconds
      Arriving: 2 pages from eagle at 11 seconds
      Servicing: 1 page from falcon at 18 seconds
      Servicing: 1 page from giraffe at 20 seconds
      Servicing: 10 pages from aardvark at 22 seconds
      Servicing: 7 pages from dolphin at 42 seconds
      Servicing: 2 pages from eagle at 56 seconds

      Total jobs: 7
      Aggregate latency: 131 seconds 
      Mean latency: 18.7143 seconds 

bigfirst.run

1 100 giraffe
2 75 aardvark
3 50 dolphin
4 2 platypus
5 1 aardvark
6 1 herring
7 2 falcon

bigfirst.out

FIFO Simulation 

      Arriving: 100 pages from giraffe at 1 seconds
      Servicing: 100 pages from giraffe at 1 seconds
      Arriving: 75 pages from aardvark at 2 seconds
      Arriving: 50 pages from dolphin at 3 seconds
      Arriving: 2 pages from platypus at 4 seconds
      Arriving: 1 page from aardvark at 5 seconds
      Arriving: 1 page from herring at 6 seconds
      Arriving: 2 pages from falcon at 7 seconds
      Servicing: 75 pages from aardvark at 201 seconds
      Servicing: 50 pages from dolphin at 351 seconds
      Servicing: 2 pages from platypus at 451 seconds
      Servicing: 1 page from aardvark at 455 seconds
      Servicing: 1 page from herring at 457 seconds
      Servicing: 2 pages from falcon at 459 seconds

      Total jobs: 7
      Aggregate latency: 2347 seconds 
      Mean latency: 335.286 seconds 

Code

Queue可以选用循环队列或者链式队列,这里就不赘述了。

下面的Constant类注意filename的路径被我改了,并换了…表示部分路径,自行调整一下:

public class Constant {
    
    private Constant() {}
    
    public static final String ARBITRARY_RUN = 
            "src/com/.../structure/resources/arbitrary.run";
    
    public static final String ARBITRARY_OUT = 
            "src/com/.../structure/resources/arbitrary.out";
    
    /**
     * 分隔符
     */
    public static final String SPLIT_CHARACTER = " ";
    
    public static final String BIGFIRST_RUN = 
            "src/com/.../structure/resources/bigfirst.run";
    
    public static final String BIGFIRST_OUT = 
            "src/com/.../structure/resources/bigfirst.out";
    
    /**
     * 结果的文件相对路径
     */
    public static final String RESULT = 
            "src/com/.../structure/resources/PrintResult.out";

}

Job类:

public class Job {
    
    /**
     * 使用者(打印机)
     */
    private String user;
    
    /**
     * 打印页数
     */
    private int numberOfPages;

    public Job(String user, int numberOfPages) {
        super();
        this.user = user;
        this.numberOfPages = numberOfPages;
    }

    public String getUser() {
        return user;
    }

    public void setUser(String user) {
        this.user = user;
    }

    public int getNumberOfPages() {
        return numberOfPages;
    }

    public void setNumberOfPages(int numberOfPages) {
        this.numberOfPages = numberOfPages;
    }

}

Event类:

public class Event {
    
    /**
     * 打印任务对象
     */
    private Job job;
    
    /**
     * 作业提交的时间(秒)
     */
    private int arrivalTime;

    public Event(Job job, int arrivalTime) {
        super();
        this.job = job;
        this.arrivalTime = arrivalTime;
    }

    public Job getJob() {
        return job;
    }

    public void setJob(Job job) {
        this.job = job;
    }

    public int getArrivalTime() {
        return arrivalTime;
    }

    public void setArrivalTime(int arrivalTime) {
        this.arrivalTime = arrivalTime;
    }

    @Override
    public String toString() {
        return "Event [job=" + job + ", arrivalTime=" + arrivalTime + "]";
    }

}

Simulator类:

import java.io.FileReader;
import java.io.IOException;
import java.io.BufferedReader;

import com. ... .structure.queue.Queue;

public abstract class Simulator {

    /**
     * 每张纸打印的时间,计算得到是2,但是为了保持可扩展性,还是没有规定死
     */
    private int seconds_per_page;
    
    /**
     * 工作队列
     */
    private Queue<Event> workload;
    
    /**
     * 等待队列
     */
    private Queue<Event> waiting;

    /**
     * 根据Java语法,该抽象类不能实例化,构造器只用于子类继承使用
     * @param seconds_per_page
     */
    public Simulator(int seconds_per_page) {
        workload = new Queue<>();
        waiting = new Queue<>();
        this.seconds_per_page = seconds_per_page;
    }

    public int getSeconds_per_page() {
        return seconds_per_page;
    }

    public void setSeconds_per_page(int seconds_per_page) {
        this.seconds_per_page = seconds_per_page;
    }

    public Queue<Event> getWorkload() {
        return workload;
    }

    public Queue<Event> getWaiting() {
        return waiting;
    }

    public void loadWorkLoad(String fileName) {
        try (BufferedReader in = new BufferedReader(new FileReader(fileName))) {
            String line = "";
            while ((line = in.readLine()) != null) {
                String[] split = line.split(SPLIT_CHARACTER);
                Job job = new Job(split[2], Integer.parseInt(split[1]));
                Event event = new Event(job, Integer.parseInt(split[0]));
                workload.enQueue(event);
            }
        } catch (IOException ioe) {
            ioe.printStackTrace();
        }
    }

    /**
     * 指定的抽象方法
     * @param fileName
     */
    public abstract void simulate(String fileName);

}

Simulator类:

import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.text.DecimalFormat;

public class Fifo extends Simulator {

    public Fifo(int seconds_per_page) {
        super(seconds_per_page);
    }

    private static double getFloat(int var1, int var2) {
        DecimalFormat format = new DecimalFormat("0.0000");
        return Double.parseDouble(format.format((float) var1 / var2));
    }

    private int getRequireTime(int page_count) {
        return getSeconds_per_page() * page_count;
    }

    private boolean is_time_to_arrive(int currentTime, Event current) {
        return currentTime == current.getArrivalTime();
    }

    private void printOut(PrintWriter writer, Event event, int time, String kind) {
        writer.println("      " + kind + ": " + event.getJob().getNumberOfPages()
                + (event.getJob().getNumberOfPages() == 1 ?
                " page " : " pages ") + "from " + event.getJob().getUser() + 
                " at " + time + " seconds");
    }

    private int processWorkLoadQueue(int time, PrintWriter writer) {
        int temp = 0;
        Event current = getWorkload().getHead();
        while (current != null && is_time_to_arrive(time, current)) {
            printOut(writer, current, time, "Arriving");
            getWaiting().enQueue(getWorkload().deQueue());
            current = getWorkload().getHead();
            temp -= time;
        }
        return temp;
    }

    private int[] processWaitingQueue(PrintWriter writer, int time, int prev) {
        int[] result = new int[2];
        if (!getWaiting().isEmpty()) {
            Event waiting = getWaiting().getHead();
            if (prev == time) {
                printOut(writer, waiting, time, "Servicing");
                result[0] = time;
                result[1] = getRequireTime(waiting.getJob().getNumberOfPages());
                getWaiting().deQueue();
            }
        } else {
            result[1]++;
        }
        return result;
    }

    private void printHeading(PrintWriter writer) {
        writer.println("FIFO Simulation\n");
    }

    private void printEnding(PrintWriter writer, int totalCount, int aggregate) {
        writer.println("\n      Total jobs: " + totalCount);
        writer.println("      Aggregate latency: " + aggregate + " seconds");
        writer.println("      Mean latency: " + getFloat(aggregate, totalCount)
            + " seconds");
    }

    @Override
    public void simulate(String fileName) {
        try (PrintWriter out = new PrintWriter(new FileWriter(fileName))) {
            printHeading(out);
            int time = 0;
            int totalCount = getWorkload().size();
            int prev = 0;
            int aggregate = 0;
            while (!getWorkload().isEmpty() || !getWaiting().isEmpty()) {
                if (!getWorkload().isEmpty()) {
                    aggregate += processWorkLoadQueue(time, out);
                }
                int[] ints = processWaitingQueue(out, time, prev);
                aggregate += ints[0];
                prev += ints[1];
                time++;
            }
            printEnding(out, totalCount, aggregate);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

Main类:

public class Main {

    public static void main(String[] args) {
        Fifo fifo = new Fifo(2);
        fifo.loadWorkLoad(BIGFIRST_RUN);
        fifo.simulate(RESULT);
    }

}
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!