码迷,mamicode.com
首页 > 编程语言 > 详细

[Java]打印机服务程序

时间:2016-06-12 02:16:31      阅读:208      评论:0      收藏:0      [点我收藏+]

标签:

一、 问题描述:


打印机服务程序,采取动态优先级方案,有三种调度策略。


动态优先级方法:

  • 任何时刻, 用户都可以向服务器发送打印请求
    • 每个请求包含打印文件的文件名字, 页数.
  • 服务器根据文件页数初始化该请求的优先级, 并将该打印请求放入对应的队列中.
    • 具体的初始化优先级算法见后续描述
  • 如果打印机空闲, 则从优先级最高的非空队列中选择请求进行打印
  • 如果打印机忙, 则让其继续打印
  • 当一个打印任务完成, 服务器将进行以下操作
    • 如果所有队列为空, 则等待新的任务到来.
    • 如果存在队列非空, 则从优先级最高的非空队列中选择一个请求. 同时, 如果一个队列qiqi 已经被访问过 kk 次, 则选择优先级最高非空队列 qj,j>iqj,j>i, 从 qjqj 中选择一个任务将其放入 qiqi 中, 并清空 qiqi的访问次数.
调度策略:

  1. 所有请求赋予相同优先级, 放入 q0q0 中. 等价于只有一个队列的 FIFS.
  2. 使用 n 个队列, 根据文档页数分配优先级
    • 页数在 1 到 10 之间, 则进入队列 q0q0
    • 页数在 11 到 20, 则进入队列 q1q1
    • ...
    • 页数在 10(n-2)+1 到 10(n-1) 之间, 则进入队列 qn?2qn?2
    • 页数超过 10(n-1), 则进入队列 qn?1qn?1
  3. 使用 n 个队列, 若文件页数为 t, 则进入队列 qt%n


二、打印请求PrintRequest类:


a) 数据成员:

i. private String filename:打印文件名
ii. private int pageNumber:文件页数
iii. private int requestTime:请求时间

iv. private int waitingTime:等待时间


b) 构造函数PrintRequest(String fn, int pn, int rt):
需指定打印文件名fn,文件页数pn和请求时间rt。


c) 获取打印页数public int getPageNumber();


d) 计算等待时间public void calcWaitingTime(int t):

当前时间t,waitingTime = t- requestTime


e) 获取等待时间public int getWaitingTime();


f) toString方法。


public class PrintRequest {
	private String fileName;
	private int pageNumber;
	private int requestTime;
	private int waitingTime;
	PrintRequest(String fn, int pn, int rt) {
		this.fileName = fn;
		this.pageNumber = pn;
		this.requestTime = rt;
	}
	// PrintRequest(PrintRequest pr) {
	// 	this.fileName = pr.fileName;
	// 	this.pageNumber = pr.pageNumber;
	// 	this.requestTime = pr.requestTime;
	// }
	public int getPageNumber() {
		return this.pageNumber;
	}
	public void calcWaitingTime(int t) {
		waitingTime = t-requestTime;
	}
	public int getWaitingTime() {
		return waitingTime;
	}
	// public void setPageNumber(int pn) {
	// 	this.pageNumber = pn;
	// }
	public String toString() {
		return fileName+" was requested at "+requestTime+" with "+pageNumber+" pages";
	}
}


三、打印机Printer类:


a) 数据成员:
i. private boolean isIdle = true:当前打印机是否空闲
ii. private PrintRequest origJob:当前打印机正在打印的文件请求
iii. private int pageLeft:当前打印的文件剩余页数


b) 获取打印机状态public boolean printIdle():返回isIdle;


c) 在t时刻产生r打印请求public boolean printFile(PrintRequest r, int t):

i. 如果当前打印机忙,返回false;
ii. 否则将origJob置为r,计算r的等待时间,pageLeft即为r的页数,isIdle状态置为false,返回true。


d) 打印一页public int printOnePage():

i. pageLeft减一;
ii. 如果pageLeft为0,则将状态isIdle置为true;
iii. 返回剩余页数pageLeft。


e) 获取当前打印结束的文件public PrintRequest processForOneUnit():

i. 如果打印机空闲, 或者当前正在打印的文档还剩余超过1页则返回 null;
ii. 如果当前文档已完成, 则返回当前的打印任务对象

public class Printer {
	private boolean isIdle = true;
	// private int currTime = 0;
	// private int startTime;
	private PrintRequest origJob;
	private int pageLeft;
	public boolean printIdle() {
		return isIdle;
	}
	public boolean printFile(PrintRequest r, int t) {
		if (this.printIdle()) {
			origJob = r;
			r.calcWaitingTime(t);
			pageLeft = r.getPageNumber();
			// startTime = currTime;
			isIdle = false;
			return true;
		}
		else return false;
	}
	public int printOnePage() {
		pageLeft--;
		if (pageLeft == 0) {
			isIdle = true;
		}
		return pageLeft;
	}
	public PrintRequest processForOneUnit() {
		if (this.printIdle() || pageLeft > 1) {
			return null;
		}
		else return origJob;
	}
	public String toString() {
		if (isIdle) {
			return "The printer is idle now.";
		}
		return origJob+" is working, "+pageLeft+" pages not finished.";
	}
}


四、打印队列PrintQueue类public class PrintQueue<E> extends AbstractQueue<E> implements Queue<E>:


a) 数据成员:

i. private int hasCalledTime = 0:该队列已被访问次数
ii. private int size = 0:队列大小
iii. private int priority:队列优先级
iv. transient private Entry<E> header = new Entry<E>(null, null, null):队首元素,不含数据


b) 内部静态私有类private static class Entry<E>:

i. 含有一个元素element,一个next指针指向下一个元素,一个befo指针指向前一个元素;
ii. 构造函数Entry(E elem, Entry<E> befo, Entry<E> next)


c) 构造函数PrintQueue(int p):

优先级为p,初始化队首header,header的next和befo分别指向自己,size清零。


d) 获取队列的访问次数public int getCalledTime()和清零队列的访问次数public void resetCalledTime()。


e) 添加元素public boolean add(E e)和public boolean offer(E e):

两者方法相同,只是在e为空的时候add抛出NoSuchElementException的异常,offer返回false。
i. 为e创建一个Entry对象tmp,并将其befo置为原本队列的最后一个元素,next置为队首元素;
ii. 将原队尾元素的next置为tmp;
iii. 将队首元素的befo置为tmp;
iv. 队列大小size加一;
v. 返回true。


f) 获取队首元素public E peek()和public E element():

两者方法相同,只是在队列为空的时候element抛出NoSuchElementException的异常,peek返回null。
队列非空时返回header.next.element。


g) 获取并删除队首元素public E remove()和public E poll():

两者方法相同,只是在队列为空的时候remove抛出NoSuchElementException的异常,poll返回null。
i. 获取队首元素tmp;
ii. header的next指向tmp的next;
iii. tmp的next的befo指向header;
iv. 队列大小size减一,访问计数器加一;
v. 返回tmp.element; 

import java.util.*;
public class PrintQueue<E> extends AbstractQueue<E> implements Queue<E> {
	private int hasCalledTime = 0;
	private int size = 0;
	private int priority;
	transient private Entry<E> header = new Entry<E>(null, null, null);
	private static class Entry<E> {
		E element;
	    Entry<E> next;
	    Entry<E> befo;

	    Entry(E elem, Entry<E> befo, Entry<E> next) {
			this.element = elem;
			this.befo = befo;
			this.next = next;
		}
	}
	PrintQueue(int p) {
		priority = p;
		header = new Entry<E>(null, null, null);
		header.next = header;
		header.befo = header;
		size = 0;
	}
	public int getCalledTime() {
		return this.hasCalledTime;
	}
	public void resetCalledTime() {
		this.hasCalledTime = 0;
	}
	public boolean add(E e) {
		if (e == null) {
			throw new NoSuchElementException();
		}
		Entry<E> tmp = new Entry<E>((E)e, header.befo, header);
		tmp.befo.next = tmp;
		header.befo = tmp;
		size++;
		return true;
	}
	public boolean offer(E e) {
		if (e == null) {
			return false;
		}
		Entry<E> tmp = new Entry<E>((E)e, header.befo, header);
		tmp.befo.next = tmp;
		header.befo = tmp;
		size++;
		return true;
	}
	public E peek() {
		if (size == 0) return null;
		return this.element();
	}
	public E element() {
		if (size == 0) {
			throw new NoSuchElementException();
		}
		final Entry<E> tmp = header.next;
		return tmp.element;
	}
	public E poll() {
		if (size == 0) {
			return null;
		}
		E tmp = (E)(header.next.element);
		header.next = header.next.next;
		header.next.befo = header;
		size--;
		hasCalledTime++;
		return tmp;
	}
	public E remove() {
		if (size == 0) {
			throw new NoSuchElementException();
		}
		return poll();
	}
	public String toString() {
		String ans = "  Priority "+priority+" PrintQueue has been called for "+hasCalledTime+" times, and its size is "+size+"\r\n";
		Entry tmp = header.next;
		for (int i = 0; i < size; i++) {
			ans += "    "+tmp.element.toString()+"\r\n";
			tmp = tmp.next;
		}
		return ans;
	}
	// not use methods:
	public void clear() {
		header = new Entry<E>(null, null, null);
		header.next = header;
		header.befo = header;
		size = 0;
	}
	public boolean retainAll(Collection c) {
		return true;
	}
	public int size() {
		return size;
	}
	public Iterator<E> iterator() {
		return new Iterator<E>() {
			public boolean hasNext() {
				return true;
			}
			public E next() {
				return (E)(header.next.element);
			}
			public void remove() {
				return;
			}
		};
	}
}


五、打印机调度器PrintDispatcher类public class PrintDispatcher extends AbstractCollection implements Queue:


a) 数据成员:

i. private int queueNumber = 0:内部队列数
ii. private int type = 0:调度策略,A~C分别对应0~2
iii. private int threshold = 0xFFFFFFF:访问次数阈值
iv. private Entry header = new Entry(null, null, null):队首元素


b) 内部静态私有类private static class Entry:

该类与PrintQueue基本一致,只是元素element的类型已经确定下来了,为PrintQueue<PrintRequest>。


c) 构造函数PrintDispatcher(int qn, int thre, int t):

i. 指定优先级队列数目qn,调度策略t,访问次数阈值thre;
ii. 队首header的next和befo均指向自己;
iii. 创建qn个优先级队列PrintQueue<PrintRequest> pq,优先级依次为0~qn-1,插入header中。


d) 获取当前优先级最高的任务public PrintRequest peek()和public PrintRequest element():

两者方法基本一致,区别在于如果当前没有等待任务时,peek返回null,而element抛出NoSuchElementException异常。
i. 遍历所有优先级队列,找到第一个非空优先级队列tmp;
ii. 返回tmp.element.peek()/element()。


e) 获取当前优先级最高的任务并从队列中移除public PrintRequest poll ()和public PrintRequest remove /dequeue():

两者方法基本一致,区别在于如果当前没有等待任务时,poll返回null,而remove/dequeue抛出NoSuchElementException异常。
i. 遍历所有优先级队列,找到第一个非空优先级队列tmp;
ii. 返回tmp.element.poll()/remove()。


f) 添加新任务public boolean offer/enqueue(Object pr)和public boolean add(Object pr):

两者方法基本一致,区别在于如果pr为空时,offer/dequeue返回false,而add抛出NoSuchElementException异常。
i. 根据当前调度程序的类型type:
1. 如果type==0:直接加入第一个优先级队列;
2. 如果type==1:计算该任务的优先级pn = (((PrintRequest)pr).getPageNumber()-1)/queueNumber,把任务归到第pn的优先级队列队尾;
3. 如果type==2:计算该任务的优先级pn = (((PrintRequest)pr).getPageNumber()-1)%queueNumber,把任务归到第pn的优先级队列队尾;


g) 饥饿检测public boolean detectHungry():

i. 遍历每个优先级队列,如果找到一个优先级队列其访问次数tmp.element.getCalledTime()大于threshold,则记录该队列为tmp;
ii. 从它之后找出第一个非空的优先级队列hungryQueue,取出其队首元素hungryRequest;
iii. 将hungryRequest出队并放入tmp的队尾,并将该tmp的访问次数请0。
h) 检测是否有任务在等待public boolean hasRequestWaiting():
i. 遍历每个优先级队列,判断其大小是否为0;
ii. 如果存在一个优先级队列大小大于0,返回true;否则返回false。

import java.util.*;
public class PrintDispatcher extends AbstractCollection implements Queue {
	private int queueNumber = 0;
	private int type = 0;
	private int threshold = 0xFFFFFFF;
	private Entry header = new Entry(null, null, null);
	private static class Entry {
		PrintQueue<PrintRequest> element;
	    Entry next;
	    Entry befo;

	    Entry(PrintQueue<PrintRequest> elem, Entry befo, Entry next) {
			this.element = elem;
			this.befo = befo;
			this.next = next;
		}
	}
	PrintDispatcher(int qn, int thre, int t) {
		queueNumber = qn;
		type = t;
		threshold = thre;
		header = new Entry(null, null, null);
		header.next = header;
		header.befo = header;
		for (int i = 0; i < queueNumber; i++) {
			PrintQueue<PrintRequest> pq = new PrintQueue<PrintRequest>(i);
			Entry e = new Entry(pq, header.befo, header);
			e.befo.next = e;
			header.befo = e;
		}
	}
	public PrintRequest peek() {
		Entry tmp = header.next;
		for (int i = 0; i < queueNumber; i++) {
			if (tmp.element.size() > 0) {
				return tmp.element.peek();
			}
			tmp = tmp.next;
		}
		return null;
	}
	public PrintRequest element() {
		Entry tmp = header.next;
		for (int i = 0; i < queueNumber; i++) {
			if (tmp.element.size() > 0) {
				return tmp.element.peek();
			}
			tmp = tmp.next;
		}
		throw new NoSuchElementException();
	}
	public PrintRequest poll() {
		Entry tmp = header.next;
		for (int i = 0; i < queueNumber; i++) {
			if (tmp.element.size() > 0) {
				return tmp.element.poll();
			}
			tmp = tmp.next;
		}
		return null;
	}
	public PrintRequest remove() {
		Entry tmp = header.next;
		for (int i = 0; i < queueNumber; i++) {
			if (tmp.element.size() > 0) {
				return tmp.element.remove();
			}
			tmp = tmp.next;
		}
		throw new NoSuchElementException();
	}
	public PrintRequest dequeue() {
		return this.remove();
	}
	public boolean offer(Object pr) {
		if (pr == null) {
			return false;
		}
		Entry tmp = header.next;
		int pn;
		switch (type) {
			case 0:
				tmp.element.offer((PrintRequest)pr);
				break;
			case 1:
				pn = (((PrintRequest)pr).getPageNumber()-1)/10;
				// System.err.println("pr = "+pr);
				// System.err.println("queueNumber = "+queueNumber);
				// System.err.println("pn = "+pn);
				if (pn >= queueNumber) {
					header.befo.element.offer((PrintRequest)pr);
					break;
				}
				for (int i = 0; i < pn; i++) {
					tmp = tmp.next;
				}
				tmp.element.offer((PrintRequest)pr);
				break;
			case 2:
				pn = (((PrintRequest)pr).getPageNumber())%queueNumber;
				for (int i = 0; i < pn; i++) {
					tmp = tmp.next;
				}
				tmp.element.offer((PrintRequest)pr);
				break;
		}
		return true;
	}
	public boolean add(Object pr) {
		if (pr == null) {
			throw new NoSuchElementException();
		}
		return this.offer(pr);
	}
	public boolean enqueue(PrintRequest pr) {
		return this.offer(pr);
	}
	public boolean detectHungry() {
		Entry tmp = header.next;
		for (int i = 0; i < queueNumber; i++) {
			if (tmp.element.getCalledTime() > threshold) {
				Entry hungryQueue = tmp;
				for (int j = i+1; j < queueNumber; j++) {
					hungryQueue = tmp.next;
					if (hungryQueue.element.size() > 0) {
						PrintRequest hungryRequest = hungryQueue.element.remove(); // hungry Queue hasCalledTime++
						tmp.element.offer(hungryRequest);
						tmp.element.resetCalledTime();
						break;
					}
				}
				return true;
			}
			tmp = tmp.next;
		}
		return false;
	}
	public boolean hasRequestWaiting() {
		Entry tmp = header.next;
		for (int i = 0; i < queueNumber; i++) {
			if (tmp.element.size() > 0) {
				return true;
			}
			tmp = tmp.next;
		}
		return false;
	}
	public String toString() {
		String ans = "";
		Entry tmp = header.next;
		for (int i = 0; i < queueNumber; i++) {
			ans += tmp.element.toString()+"\r\n";
			tmp = tmp.next;
		}
		return ans;
	}
	// not use:
	public Iterator iterator() {
		return new Iterator() {
			public boolean hasNext() {
				return true;
			}
			public PrintQueue<PrintRequest> next() {
				return header.next.element;
			}
			public void remove() {
				return;
			}
		};
	}
	public int size() {
		return queueNumber;
	}
}


六、打印环境模拟PrintSimulation类:


a) 数据成员:

i. private double probability:当前模拟环境中每个时刻产生新打印任务的概率
ii. private int queueNumber:当前模拟环境中的优先级队列数
iii. private int callThreshold:当前模拟环境中的优先级队访问阈值
iv. private char priorityType:当前模拟环境中的采取的优先策略
v. ArrayList<Integer[]> waitingTimeArray = new ArrayList<Integer[]>():获取的任务页数-等待时间数组
vi. int maxWaitingTime = 0:所有任务中的最大等待时间
vii. double averageWaitingTime = 0:所有任务的平均等待时间
viii. int sumWaitingTime = 0:总等待时间:
ix. PrintDispatcher pd:任务调度器
x. Printer printer:打印机


b) 构造方法PrintSimulation(double p, int n, int k, String a):

i. P为概率,n为队列数,k为阈值,a为优先策略;
ii. 创建任务调度器new PrintDispatcher(n, k, a.charAt(0)-‘A‘);
iii. 创建打印机。


c) 生成请求private static PrintRequest generateRequest(double p, int clock, int requestNumber):

i. 产生随机数rnd∈[0,1);
ii. 如果rnd大于p,则返回null;
iii. 否则,随机成生一个打印请求,页数为1~100的随机数,名字为当前请求号requestNumber,时间为当前模拟环境时间clock。


d) 模拟场景public void simulate(int simulateTime):simulateTime为模拟的时间

i. 对每个时刻clock,
    1. 调用generateRequest()生成一个请求newRequest,如果非空说明生成成功,将requestNumber加一,并将newRequest放入任务调度器中;
    2. 判断当前打印机printer是否空闲,如果空闲,则打印一页printer.printOnePage();
    3. 否则,从调度器pd中取出队首请求pr,放入打印机打印printer.printFile(pr, clock),更新最大等待时间和总等待时间,将pr的页数-等待时间加入waitingTimeArray中;

    4. 检测饥饿pd.detectHungry();

    5. Clock加一。
ii. 如果当前调度器中还有任务在等待或者打印机还没有空闲:
    1. 如果打印机不空闲,则打印一页printer.printOnePage();

    2. 否则,从调度器pd中取出队首请求pr,放入打印机打印printer.printFile(pr, clock),更新最大等待时间和总等待时间,将pr的页数-等待时间加入waitingTimeArray中;

import java.io.*;
import java.util.*;
public class PrintSimulation {
	private double probability;
	private int queueNumber;
	private int callThreshold;
	private char priorityType;
	ArrayList<Integer[]> waitingTimeArray = new ArrayList<Integer[]>();
	int maxWaitingTime = 0;
	double averageWaitingTime = 0;
	int sumWaitingTime = 0;
	PrintDispatcher pd;
	Printer printer;
	private static PrintRequest generateRequest(double p, int clock, int requestNumber) {
		double rnd = Math.random();
		if (rnd > p) {
			return null;
		}
		int pagenumber = (int)(1+Math.random()*100);
		String filename = "Request"+String.valueOf(requestNumber);
		return new PrintRequest(filename, pagenumber, clock);
	}
	PrintSimulation(double p, int n, int k, String a) {
		probability = p;
		queueNumber = n;
		callThreshold = k;
		priorityType = a.charAt(0);
		pd = new PrintDispatcher(n, k, a.charAt(0)-'A');
		printer = new Printer();
	}
	public void simulate(int simulateTime) {
		int requestNumber = 0;
		for (int clock = 0; clock < simulateTime; clock++) {
			// generate a new PrintRequest
			PrintRequest newRequest = generateRequest(this.probability, clock, requestNumber);
			if (newRequest != null) {
				requestNumber++;
				System.out.println("New request generated: "+newRequest);
				pd.enqueue(newRequest);
			}
			// printer is idle or not
			if (!printer.printIdle()) {
				printer.printOnePage();
			}
			else {
				if (pd.hasRequestWaiting()) {
					PrintRequest pr = pd.dequeue();
					printer.printFile(pr, clock); //next clock start printing

					Integer[] pageWaiting = new Integer[]{pr.getPageNumber(), pr.getWaitingTime()};
					maxWaitingTime = maxWaitingTime>pr.getWaitingTime() ? maxWaitingTime:pr.getWaitingTime();
					sumWaitingTime += pr.getWaitingTime();
					waitingTimeArray.add(pageWaiting);
				}
				pd.detectHungry();
			}
			System.out.println("Time "+clock+" State:");
			System.out.println(pd);
			System.out.println(printer);
		}
		int t = simulateTime;
		while (pd.hasRequestWaiting() || !printer.printIdle()) {
			if (!printer.printIdle()) {
				printer.printOnePage();
			}
			else {
				PrintRequest pr = pd.dequeue();
				printer.printFile(pr, t);
				Integer[] pageWaiting = new Integer[]{pr.getPageNumber(), pr.getWaitingTime()};
				maxWaitingTime = maxWaitingTime>pr.getWaitingTime() ? maxWaitingTime:pr.getWaitingTime();
				sumWaitingTime += pr.getWaitingTime();
				waitingTimeArray.add(pageWaiting);
			}
			System.out.println("Time "+t+" State:");
			System.out.println(pd);
			System.out.println(printer);
			t++;
			averageWaitingTime = (double)sumWaitingTime/waitingTimeArray.size();
		}
	}

}


七、 结果分析:由DrawResult.java生成

import java.io.*;
import java.awt.*;
import java.util.*;
import java.awt.event.*;
import java.text.*; 
public class DrawResult extends Canvas {
	ArrayList<PrintSimulation> aps = new ArrayList<PrintSimulation>();
	ArrayList<ArrayList<Integer[]>> waitingTimeArray = new ArrayList<ArrayList<Integer[]>>();
	ArrayList<Integer> maxWaitingTime = new ArrayList<Integer>();
	ArrayList<Double> averageWaitingTime = new ArrayList<Double>();
	ArrayList<String[]> storeArgs = new ArrayList<String[]>();
	DrawResult() {
		setSize(800, 600);
	}
	public void paint(Graphics g) {
		int n = Integer.parseInt(storeArgs.get(storeArgs.size()-1)[1]);
		g.drawLine(100, 500, 730, 500);
		g.drawString("Page Number/page", 650, 530);
		g.drawLine(100, 500, 100, 70);
		g.drawString("Average Waiting Time/ln(AWT)", 50, 50);
		g.drawString("0", 90, 515);
		for (int i = 1; i <= n; i++) {
			g.drawString(String.valueOf(i*(100/n)), 90+i*(600/n), 515);
		}
		double ceil = Math.log(maxWaitingTime.get(maxWaitingTime.size()-1));
		System.out.println(ceil);
		int seg = 400/(int)Math.ceil(ceil);
		for (int i = 1; i <= Math.ceil(ceil); i++) {
			g.drawString(String.valueOf(i), 80, 500-i*seg);
		}
		// change probability
		// g.drawString("Queue Number = "+n, 500, 300);
		// g.drawString("Call Threshold = "+storeArgs.get(storeArgs.size()-1)[2], 500, 320);
		// g.drawString("Priority Type = "+storeArgs.get(storeArgs.size()-1)[3], 500, 340);
		
		// change queue number
		// g.drawString("Probability = "+storeArgs.get(storeArgs.size()-1)[0], 500, 300);
		// g.drawString("Call Threshold = "+storeArgs.get(storeArgs.size()-1)[2], 500, 320);
		// g.drawString("Priority Type = "+storeArgs.get(storeArgs.size()-1)[3], 500, 340);

		// // change threshold
		// g.drawString("Probability = "+storeArgs.get(storeArgs.size()-1)[0], 500, 300);
		// g.drawString("Queue Number = "+storeArgs.get(storeArgs.size()-1)[1], 500, 320);
		// g.drawString("Priority Type = "+storeArgs.get(storeArgs.size()-1)[3], 500, 340);

		// change type
		g.drawString("Probability = "+storeArgs.get(storeArgs.size()-1)[0], 500, 300);
		g.drawString("Queue Number = "+storeArgs.get(storeArgs.size()-1)[1], 500, 320);
		g.drawString("Call Threshold = "+storeArgs.get(storeArgs.size()-1)[2], 500, 340);

		g.drawRect(500, 20, 200, 90);

		System.err.println(storeArgs.get(0)[3]);
		System.err.println(storeArgs.get(1)[3]);
		System.err.println(storeArgs.get(2)[3]);
		for (int j = 0; j <aps.size(); j++) {
			// change queue number, others should be commented
			n = Integer.parseInt(storeArgs.get(j)[1]);

			switch (j) {
				case 0:
					g.setColor(Color.RED);
					break;
				case 1:
					g.setColor(Color.BLUE);
					break;
				case 2:
					g.setColor(new Color(0x009966));
					break;
				case 3:
					g.setColor(new Color(0x660000));
					break;
				case 4:
					g.setColor(new Color(0xFF9933));
					break;
				default:
					g.setColor(Color.BLACK);
			}
			
			// // change probability:
			// g.drawString("Prob="+(new DecimalFormat("0.0").format(0.1+0.1*j)), 510, 40+j*15);
			// g.drawLine(570, 35+j*15, 680, 35+j*15);

			// // change queue number:
			// g.drawString("Queue Number="+(j*2+1), 510, 40+j*15);
			// g.drawLine(620, 35+j*15, 680, 35+j*15);

			// change queue number:
			// g.drawString("Threshold="+(j*5+5), 510, 40+j*15);
			// g.drawLine(620, 35+j*15, 680, 35+j*15);

			// change type:
			g.drawString("Priority Type="+((char)(j+'A')), 510, 40+j*25);
			g.drawLine(620, 35+j*25, 680, 35+j*25);
			int[][] averageTime = new int[n][2];
			for (int i = 0; i < waitingTimeArray.get(j).size(); i++) {
				if (storeArgs.get(j)[3].equals("B")) {
					// System.err.println("page="+waitingTimeArray.get(j).get(i)[0]+", time="+waitingTimeArray.get(j).get(i)[1]);
					if ((waitingTimeArray.get(j).get(i)[0]-1)/10 >= n) {
						averageTime[n-1][0] += waitingTimeArray.get(j).get(i)[1];
						averageTime[n-1][1] ++;
					}
					else {
						averageTime[(waitingTimeArray.get(j).get(i)[0]-1)/10][0] += waitingTimeArray.get(j).get(i)[1];
						averageTime[(waitingTimeArray.get(j).get(i)[0]-1)/10][1] ++;
					}
				}
				else if (storeArgs.get(j)[3].equals("C")) {
					// System.err.println("C");
					// System.err.println("storeArgs.get(j)[3] = "+storeArgs.get(j)[3]);
					// System.err.println("waitingTimeArray.get(j).get(i)[0] = "+waitingTimeArray.get(j).get(i)[0]);
					// System.err.println("100/n = "+(100/n));
					averageTime[(waitingTimeArray.get(j).get(i)[0]-1)%n][0] += waitingTimeArray.get(j).get(i)[1];
					averageTime[(waitingTimeArray.get(j).get(i)[0]-1)%n][1] ++;
				}
				else {
					// System.err.println("A");
					averageTime[(waitingTimeArray.get(j).get(i)[0]-1)/(100/n)][0] += waitingTimeArray.get(j).get(i)[1];
					averageTime[(waitingTimeArray.get(j).get(i)[0]-1)/(100/n)][1] ++;
				}
			}
			int befox=0, befoy=0;
			for (int i = 0; i < n; i++) {
				if (averageTime[i][1] != 0) {
					averageTime[i][0] /= averageTime[i][1];
				}
				else {
					averageTime[i][0] = 0;
				}
				System.out.println(averageTime[i][0]);
				g.drawRect(130+i*(600/n), (int)(500-seg*Math.log(averageTime[i][0])), 5, 5);
				g.drawString(String.valueOf(averageTime[i][0]), 120+i*(600/n), (int)(500-seg*Math.log(averageTime[i][0]))-7);
				if (befox!=0 && befoy!=0) {
					g.drawLine(befox, befoy, 130+i*(600/n), (int)(500-seg*Math.log(averageTime[i][0])));
				}
				befox = 130+i*(600/n);
				befoy = (int)(500-seg*Math.log(averageTime[i][0]));
			}
		}


	}
	public static void main(String[] args) throws IOException {
		if (args.length != 4) {
			System.out.println("The args are illegal!");
		}
		PrintStream pstream = new PrintStream(new FileOutputStream(args[3]+"result.txt"));
		System.setOut(pstream);

		Frame frame = new Frame("Result");
		DrawResult dr = new DrawResult();

		// // change probability:
		// for (int i = 1 ; i <= 5; i++) {
		// 	args[0] = String.valueOf(0.1*i);
		// 	PrintSimulation ps = new PrintSimulation(0.1*i, Integer.parseInt(args[1]), Integer.parseInt(args[2]), args[3]);
		// 	ps.simulate(1000);
		// 	for (int j = 0; j < ps.waitingTimeArray.size(); j++) {
		// 		System.out.println("PageNumber = "+ps.waitingTimeArray.get(j)[0]+", WaitingTime = "+ps.waitingTimeArray.get(j)[1]);
		// 	}
		// 	System.out.println("Generated "+ps.waitingTimeArray.size()+" jobs, maxWaitingTime = "+ps.maxWaitingTime+", averageWaitingTime = "+ps.averageWaitingTime);

		// 	dr.storeArgs.add(args);
		// 	dr.waitingTimeArray.add(ps.waitingTimeArray);
		// 	dr.maxWaitingTime.add(ps.maxWaitingTime);
		// 	dr.averageWaitingTime.add(ps.averageWaitingTime);
		// 	dr.aps.add(ps);
		// }

		// // change queue number:
		// for (int i = 1 ; i <= 10; i+=2) {
		// 	args[1] = String.valueOf(i);
		// 	System.err.println("n = "+args[1]);
		// 	PrintSimulation ps = new PrintSimulation(Double.parseDouble(args[0]), Integer.parseInt(args[1]), Integer.parseInt(args[2]), args[3]);
		// 	ps.simulate(1000);
		// 	for (int j = 0; j < ps.waitingTimeArray.size(); j++) {
		// 		System.out.println("PageNumber = "+ps.waitingTimeArray.get(j)[0]+", WaitingTime = "+ps.waitingTimeArray.get(j)[1]);
		// 	}
		// 	System.out.println("Generated "+ps.waitingTimeArray.size()+" jobs, maxWaitingTime = "+ps.maxWaitingTime+", averageWaitingTime = "+ps.averageWaitingTime);

		// 	dr.storeArgs.add(args);
		// 	dr.waitingTimeArray.add(ps.waitingTimeArray);
		// 	dr.maxWaitingTime.add(ps.maxWaitingTime);
		// 	dr.averageWaitingTime.add(ps.averageWaitingTime);
		// 	dr.aps.add(ps);
		// }

		// // change threshold:
		// for (int i = 5 ; i <= 25; i+=5) {
		// 	args[2] = String.valueOf(i);
		// 	System.err.println("n = "+args[2]);
		// 	PrintSimulation ps = new PrintSimulation(Double.parseDouble(args[0]), Integer.parseInt(args[1]), Integer.parseInt(args[2]), args[3]);
		// 	ps.simulate(1000);
		// 	for (int j = 0; j < ps.waitingTimeArray.size(); j++) {
		// 		System.out.println("PageNumber = "+ps.waitingTimeArray.get(j)[0]+", WaitingTime = "+ps.waitingTimeArray.get(j)[1]);
		// 	}
		// 	System.out.println("Generated "+ps.waitingTimeArray.size()+" jobs, maxWaitingTime = "+ps.maxWaitingTime+", averageWaitingTime = "+ps.averageWaitingTime);

		// 	dr.storeArgs.add(args);
		// 	dr.waitingTimeArray.add(ps.waitingTimeArray);
		// 	dr.maxWaitingTime.add(ps.maxWaitingTime);
		// 	dr.averageWaitingTime.add(ps.averageWaitingTime);
		// 	dr.aps.add(ps);
		// }

		// change type:
		for (int i = 0 ; i <= 2; i++) {
			args[3] = new String(String.valueOf((char)(i+'A')));
			System.err.println("type = "+args[3]);
			PrintSimulation ps = new PrintSimulation(Double.parseDouble(args[0]), Integer.parseInt(args[1]), Integer.parseInt(args[2]), args[3]);
			ps.simulate(1000);
			for (int j = 0; j < ps.waitingTimeArray.size(); j++) {
				System.out.println("PageNumber = "+ps.waitingTimeArray.get(j)[0]+", WaitingTime = "+ps.waitingTimeArray.get(j)[1]);
			}
			System.out.println("Generated "+ps.waitingTimeArray.size()+" jobs, maxWaitingTime = "+ps.maxWaitingTime+", averageWaitingTime = "+ps.averageWaitingTime);

			dr.storeArgs.add(new String[]{args[0],args[1],args[2],args[3]});
			for (int j = 0; j <= i; j++) {
				System.err.println("storeArgs: "+dr.storeArgs.get(j)[3]);
			}
			dr.waitingTimeArray.add(ps.waitingTimeArray);
			dr.maxWaitingTime.add(ps.maxWaitingTime);
			dr.averageWaitingTime.add(ps.averageWaitingTime);
			dr.aps.add(ps);
		}


		frame.add(dr);
		frame.setLocation(100, 100);
		frame.addWindowListener(new WindowAdapter() {
	    public void windowClosing(WindowEvent e) {
	    	System.exit(0);
	    }});
	    frame.pack();
	    frame.setVisible(true);
		

	}
}


a) 控制任务生成概率:当队列数量为10,访问阈值为5,优先策略采取B时,不同任务产生概率的对比图:
 技术分享
如图所示,随着任务产生概率的升高,平均等待时间成倍增加。
b) 控制队列数量:当任务产生概率为0.3,访问阈值为3,优先策略采取B时,不同队列数量的对比图:
 技术分享
如图所示,随着队伍数量的升高,平均等待时间逐渐降低。当队伍数为1时,各个队列的平均等待时间基本相同,等价于采取优先策略A。
c) 控制阈值:当任务产生概率为0.3,队列数量为10,优先策略采取B时,不同阈值的对比图:
 技术分享
如图所示,随着访问阈值的上升,平均等待时间逐渐降低。
d) 控制优先策略:当任务产生概率为0.3,队列数量为10,访问阈值为5时,不同优先策略的对比图:
 技术分享
如图所示,采取优先策略A和优先策略C时,两者平均等待时间基本一致,这是由于在10个队列情况下,各个可能页数取模都能得到基本一致的数量,故与策略A结果接近,比较奇怪的是当页数很大时C的折线急剧下降,不知道为什么。

而策略B随着页数的增加,平均等待时间在急剧上升。



本文为博主原创,转载请注明来源:

http://blog.csdn.net/cristianojason/article/details/51627993

[Java]打印机服务程序

标签:

原文地址:http://blog.csdn.net/cristianojason/article/details/51627993

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!