我创建了一个优先级队列实现,我用它来模拟打印服务器。我还有一个PrintJob用于打印的项目。在这个打印服务器中,最小的项目(要打印的文件)具有最高优先级。虽然,有时最大的文件可能在优先级队列中等待太多时间,所以我要做的是:如果文件在优先级队列中等待15秒,则更改优先级。最好的方法是什么?
我的优先级队列实现是:
import java.util.Comparator;
public class MaxPQ<T> {
public T[] heap;
private int size;
protected Comparator<T> cmp;
public MaxPQ(int capacity, Comparator<T> cmp) {
if (capacity < 1) throw new IllegalArgumentException();
this.heap = (T []) new Object[capacity+1];
this.size = 0;
this.cmp = cmp;
}
MaxPQ() {}
private void swap(int i, int j) {
T tmp = heap[i];
heap[i] = heap[j];
heap[j] = tmp;
}
public void print() {
for (int i=1; i<=size; i++){
System.out.print(heap[i]+ "");
}
System.out.println();
}
boolean isEmpty(){
return size == 0;
}
public void insert(T object) {
if (object == null) throw new IllegalArgumentException();
if (size == heap.length - 1) throw new IllegalStateException();
if (size >= 0.75*heap.length) {
resize(2*heap.length);
}
heap[++size] = object;
swim(size);
}
public T getMax() {
if (size == 0) throw new IllegalStateException();
T object = heap[1];
if (size > 1) heap[1] = heap[size];
heap[size--] = null;
sink(1);
return object;
}
private void swim(int i) {
while (i > 1) { //if i root (i==1) return
int p = i/2; //find parent
int result = cmp.compare(heap[i], heap[p]); //compare parent with child
if (result <= 0) return; //if child <= parent return
swap(i, p); //else swap and i=p
i = p;
}
}
private void sink(int i){
int left = 2*i, right = left+1, max = left;
while (left <= size) {
if (right <= size) {
max = cmp.compare(heap[left], heap[right]) < 0 ? right : left;
}
if (cmp.compare(heap[i], heap[max]) >= 0) return;
swap(i, max);
i = max; left = 2*i; right = left+1; max = left;
}
}
private void resize(int newSize) {
Object[] newHeap = new Object[newSize];
System.arraycopy(heap, 0, newHeap, 0, size);
heap = (T[]) newHeap;
}
public int size(){
return size;
}
}
printjob项目包含以下字段:id,size(文件大小),waitingtime(队列中的时间),到达时间(打印中的到达时间,优先级)
这就是我所做的:
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
import static java.lang.Double.min;
import java.util.ArrayList;
import java.util.Scanner;
public class AlgorithmC {
public static void runC() throws FileNotFoundException{
readFile("arxeia");
}
private static final int MAXSIZE = 128;
private int T = 0;
static ArrayList<PrintJob> printList = new ArrayList<>();
MaxPQ<PrintJob> printPQ = new MaxPQ<>();
public static void readFile(String filename) throws FileNotFoundException{
Scanner scanner = new Scanner(new File("filename.txt"));
int waitingTime = 0;
int r = 0;
while(scanner.hasNextInt()){
int size = scanner.nextInt();
int arrivalTime = scanner.nextInt();
PrintJob p = new PrintJob(size,waitingTime,arrivalTime,size);
printList.add(p);
}
for(int i = 0;i < printList.size(); i++){
if((printList.get(i).getArrivalTime()) <= (printList.get(i+1).getArrivalTime())){
r += 1;
}
}
if(r != (printList.size()) - 1){
System.out.println("Invalid file format!");
}
for(int i = 0;i < printList.size(); i++){
if((printList.get(i).getSize() < 0 || printList.get(i).getSize() > MAXSIZE )){
System.out.println("Invalid file size!");
}
}
}
public void storeFile(String filename){
BufferedWriter bw = null;
FileWriter fw = null;
try {
int i = 0;
fw = new FileWriter(filename);
bw = new BufferedWriter(fw);
T = printList.get(1).getArrivalTime();
bw.write("t = " + (T + printList.get(1).getSize()) + ",completed file" + printList.get(1).getid());
T = T + printList.get(1).getSize();
printList.remove(1);
for (PrintJob printItem : printList) {
printPQ.insert(printItem);
}
int size = printPQ.size();
int max = 0;
int tempID = 0;
int time = 0;
while(i < size){
PrintJob nextPrint = printPQ.getMax();
T = T + nextPrint.getSize();
bw.write("t = " + T + ",completed file" + printList.get(i).getid());
time =+ (T - nextPrint.getArrivalTime());
for(int j = 0; j < printPQ.size(); j++){
if((T-(printPQ.heap[j].getArrivalTime())) >= 15){
printPQ.heap[j].setPriority((int) min(127,printPQ.heap[j].getPriority() + printPQ.heap[j].getWaitingTime()));
}
}
nextPrint.setWaitingTime(time);
if(time > max){
max = time;
tempID = nextPrint.getid();
}
i =+ 1;
}
int averageWaitingTime = time/(size-1);
bw.write("Average waiting time = " + averageWaitingTime + " " );
bw.write("Maximum waiting time = " + max + "achieved by file " + tempID + " ");
}
catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (bw != null)
bw.close();
if (fw != null)
fw.close();
}
catch (IOException ex) {
ex.printStackTrace();
}
}
}
}
因此,当我更改优先级时,我可能会破坏堆结构。