输出未出现在多级队列算法中

Output not appearing in Multi-level Queue algorithm

提问人:SYED ALI MEHDI RIZVI 提问时间:10/11/2023 最后编辑:genpfaultSYED ALI MEHDI RIZVI 更新时间:10/12/2023 访问量:18

问:

这是一个多级队列调度问题。我已经实现了 4 个级别,其中系统进程队列具有最高优先级,批处理队列具有最低优先级。我使用堆对流程进行排序,以便对系统进程进行优先级调度,对交互式和交互式编辑进程进行循环调度,对批处理进程进行先到先得调度:

#include <iostream>
#include <vector>
#include <queue>

using namespace std;

// Define a struct for representing a process.
class Process {
public:
    int pid;            // Process ID
    int arrivalTime;    // Arrival time
    string type;        // Type of process (System, Interactive, etc.)
    int burstTime;      // Burst time
    int priority;       // Priority
    int curRunTime;     // Current run time

    // Default constructor
    Process() : pid(0), arrivalTime(0), type(""), burstTime(0), priority(0), curRunTime(0) {
    }

    // Parameterized constructor
    Process(int pid, int arrivalTime, string type, int burstTime, int priority)
    : pid(pid), arrivalTime(arrivalTime), type(type), burstTime(burstTime), priority(priority), curRunTime(0) {
    }

    // Getters and setters for process attributes
    int getPid() { return pid; }
    int getArrivalTime() { return arrivalTime; }
    string getType() { return type; }
    int getPriority() { return priority; }
    int getBurstTime() { return burstTime; }
    void setBurstTime(int burstTime) { this->burstTime = burstTime; }
    int getCurRunTime() { return curRunTime; }
    void setCurRunTime(int curRunTime) { this->curRunTime = curRunTime; }
};

// Define a class for a priority queue using priority.
class Priority_queue_using_priority {
private:
    vector<Process> heap; // The heap data structure
    int size;             // Current size of the queue
    int capacity;         // Maximum capacity of the queue

    // Helper functions for heap operations
    int parent(int i) { return (i - 1) / 2; }
    int leftChild(int i) { return 2 * i + 1; }
    int rightChild(int i) { return 2 * i + 2; }
    void swap(int i, int j) {
        Process temp = heap[i];
        heap[i] = heap[j];
        heap[j] = temp;
    }

public:
    // Constructor to initialize the priority queue.
    Priority_queue_using_priority(int capacity) {
        this->capacity = capacity;
        this->size = 0;
        this->heap = vector<Process>(capacity);
    }

    // Insert a process into the priority queue based on its priority and arrival time.
    void insert(Process process) {
        if (size >= capacity) {
            cout << "Heap is full, cannot insert." << endl;
            return;
        }

        size++;
        int i = size - 1;
        heap[i] = process;

        while (i != 0) {
            if (heap[parent(i)].getPriority() > heap[i].getPriority() ||
                (heap[parent(i)].getPriority() == heap[i].getPriority() &&
                 heap[parent(i)].getArrivalTime() > heap[i].getArrivalTime())) {
                swap(i, parent(i));
                i = parent(i);
            } else {
                break;
            }
        }
    }

    // Extract the process with the highest priority.
    Process extractMin() {
        if (size <= 0) {
            cout << "Heap is empty." << endl;
            return Process(0, 0, "", 0, 0);
        }

        if (size == 1) {
            size--;
            return heap[0];
        }

        Process root = heap[0];
        heap[0] = heap[size - 1];
        size--;
        minHeapify(0);

        return root;
    }

    // Maintain the min-heap property.
    void minHeapify(int i) {
        int left = leftChild(i);
        int right = rightChild(i);
        int smallest = i;

        if (left < size &&
            (heap[left].getPriority() < heap[i].getPriority() ||
             (heap[left].getPriority() == heap[i].getPriority() &&
              heap[left].getArrivalTime() < heap[i].getArrivalTime()))) {
            smallest = left;
        }
        if (right < size &&
            (heap[right].getPriority() < heap[smallest].getPriority() ||
             (heap[right].getPriority() == heap[smallest].getPriority() &&
              heap[right].getArrivalTime() < heap[smallest].getArrivalTime()))) {
            smallest = right;
        }

        if (smallest != i) {
            swap(i, smallest);
            minHeapify(smallest);
        }
    }

    // Get the process with the highest priority (root of the heap).
    Process top() { return heap[0]; }

    // Check if the priority queue is empty.
    bool isEmpty() { return size == 0; }
};

// Define a class for a regular priority queue.
class Priority_queue {
private:
    vector<Process> heap; // The heap data structure
    int size;             // Current size of the queue
    int capacity;         // Maximum capacity of the queue

    // Helper functions for heap operations
    int parent(int i) { return (i - 1) / 2; }
    int leftChild(int i) { return 2 * i + 1; }
    int rightChild(int i) { return 2 * i + 2; }
    void swap(int i, int j) {
        Process temp = heap[i];
        heap[i] = heap[j];
        heap[j] = temp;
    }

public:
    // Constructor to initialize the priority queue.
    Priority_queue(int capacity) {
        this->capacity = capacity;
        this->size = 0;
        this->heap = vector<Process>(capacity);
    }

    // Insert a process into the priority queue based on its arrival time.
    void insert(Process process) {
        if (size >= capacity) {
            cout << "Heap is full, cannot insert." << endl;
            return;
        }

        size++;
        int i = size - 1;
        heap[i] = process;

        while (i != 0 && heap[parent(i)].getArrivalTime() > heap[i].getArrivalTime()) {
            swap(i, parent(i));
            i = parent(i);
        }
    }

    // Extract the process with the smallest arrival time.
    Process extractMin() {
        if (size <= 0) {
            cout << "Heap is empty." << endl;
            return Process(0, 0, "", 0, 0);
        }

        if (size == 1) {
            size--;
            return heap[0];
        }

        Process root = heap[0];
        heap[0] = heap[size - 1];
        size--;
        minHeapify(0);

        return root;
    }

    // Maintain the min-heap property.
    void minHeapify(int i) {
        int left = leftChild(i);
        int right = rightChild(i);
        int smallest = i;

        if (left < size && heap[left].getArrivalTime() < heap[i].getArrivalTime())
            smallest = left;
        if (right < size && heap[right].getArrivalTime() < heap[smallest].getArrivalTime())
            smallest = right;

        if (smallest != i) {
            swap(i, smallest);
            minHeapify(smallest);
        }
    }

    // Get the process with the smallest arrival time (root of the heap).
    Process top() { return heap[0]; }

    // Check if the priority queue is empty.
    bool isEmpty() { return size == 0; }
};

// Define a class for a simple queue.
class Queue {
private:
    int front, rear, size;
    int capacity;
    vector<Process> queue;

public:
    // Constructor to initialize the queue.
    Queue(int capacity) {
        this->capacity = capacity;
        this->front = this->size = 0;
        this->rear = capacity - 1;
        this->queue = vector<Process>(capacity);
    }

    // Check if the queue is full.
    bool isFull() { return (size == capacity); }

    // Check if the queue is empty.
    bool isEmpty() { return (size == 0); }

    // Enqueue a process into the queue.
    void enqueue(Process process) {
        if (isFull()) {
            cout << "Queue is full. Cannot enqueue." << endl;
            return;
        }

        rear = (rear + 1) % capacity;
        queue[rear] = process;
        size++;
    }

    // Dequeue a process from the queue.
    Process dequeue() {
        if (isEmpty()) {
            cout << "Queue is empty. Cannot dequeue." << endl;
            return Process(0, 0, "", 0, 0);
        }

        Process process = queue[front];
        front = (front + 1) % capacity;
        size--;
        return process;
    }

    // Get the front process in the queue.
    Process Front() {
        if (isEmpty()) {
            cout << "Queue is empty." << endl;
            return Process(0, 0, "", 0, 0);
        }
        return queue[front];
    }

    // Simulate the execution of a process for one second.
    void runForOneSec() {
        if (isEmpty()) {
            cout << "Queue is empty. Cannot Run." << endl;
            return;
        }
        queue[front].setBurstTime(queue[front].getBurstTime() - 1);
        queue[front].setCurRunTime(queue[front].getCurRunTime() + 1);
    }
};

// Define a class for representing a Gantt Chart entry.
class GrantChart {
public:
    int pid;         // Process ID
    int startTime;   // Start time
    int endTime;     // End time
    GrantChart* next; // Pointer to the next entry

    // Constructor to initialize a Gantt Chart entry.
    GrantChart(int pid, int startTime, int endTime) {
        this->pid = pid;
        this->startTime = startTime;
        this->endTime = endTime;
        this->next = nullptr;
    }
};

int currentTime;
GrantChart* chart;
vector<int> turnAroundTime;
vector<int> waitingTime;
vector<int> queueEnteringTime;

// Function to execute a process and update the Gantt Chart.
void executeProcess(Process process, int startTime, int endTime) {
    chart->next = new GrantChart(process.getPid(), startTime, endTime);
    chart = chart->next;
}

// Function to schedule processes using the Round Robin algorithm.
void RoundRobinScheduler(Queue& readyQueue) {
    int timeQuantum = 2;
    readyQueue.runForOneSec();
    Process executingProcess = readyQueue.Front();
    int idx = executingProcess.getPid() - 1;
    int remainingBurstTime = executingProcess.getBurstTime();
    waitingTime[idx] += currentTime - queueEnteringTime[idx];

    if (remainingBurstTime == 0) {
        currentTime += 1;
        executeProcess(executingProcess, currentTime - 1, currentTime);
        readyQueue.dequeue();
        turnAroundTime[idx] = currentTime - executingProcess.getArrivalTime();
    }
    else if (executingProcess.getCurRunTime() == timeQuantum) {
        currentTime += 1;
        readyQueue.dequeue();
        readyQueue.enqueue(executingProcess);
        executeProcess(executingProcess, currentTime - 1, currentTime);
        queueEnteringTime[idx] = currentTime;
        executingProcess.setCurRunTime(0);
    }
    else {
        currentTime += 1;
        executeProcess(executingProcess, currentTime - 1, currentTime);
        queueEnteringTime[idx] = currentTime;
    }
}

// Function to schedule processes based on priority.
void priorityScheduler(Priority_queue_using_priority& readyQueue) {
    Process process = readyQueue.extractMin();
    int remainingBurstTime = process.getBurstTime();
    int idx = process.getPid() - 1;
    waitingTime[idx] += currentTime - queueEnteringTime[idx];

    if (remainingBurstTime <= 1) {
        currentTime += 1;
        executeProcess(process, currentTime - 1, currentTime);
        turnAroundTime[idx] = currentTime - process.getArrivalTime();
    } else {
        currentTime += 1;
        process.setBurstTime(remainingBurstTime - 1);
        readyQueue.insert(process);
        executeProcess(process, currentTime - 1, currentTime);
        queueEnteringTime[idx] = currentTime;
    }
}

// Function to schedule processes based on First-Come-First-Serve (FCFS).
void firstComeFirstServeScheduler(Priority_queue& readyQueue) {
    Process process = readyQueue.extractMin();
    int remainingBurstTime = process.getBurstTime();
    int idx = process.getPid() - 1;
    waitingTime[idx] += currentTime - queueEnteringTime[idx];

    if (remainingBurstTime <= 1) {
        currentTime += 1;
        executeProcess(process, currentTime - 1, currentTime);
        turnAroundTime[idx] = currentTime - process.getArrivalTime();
    } else {
        currentTime += 1;
        process.setBurstTime(remainingBurstTime - 1);
        readyQueue.insert(process);
        executeProcess(process, currentTime - 1, currentTime);
        queueEnteringTime[idx] = currentTime;
    }
}

// Function to convert process type (integer) to a string.
string getTypeString(int type) {
    switch (type) {
        case 1:
            return "System";
        case 2:
            return "Interactive";
        case 3:
            return "Interactive Editing";
        case 4:
            return "Batch";
        default:
            return "Unknown";
    }
}

int main() {
    int numProcesses;
    cin >> numProcesses;

    Priority_queue arrivedProcesses(numProcesses);

    currentTime = 0;
    chart = new GrantChart(-1, 0, 0);
    turnAroundTime = vector<int>(numProcesses, 0);
    waitingTime = vector<int>(numProcesses, 0);
    queueEnteringTime = vector<int>(numProcesses, 0);
    GrantChart* headOfChart = chart;

    Priority_queue_using_priority systemProcesses(numProcesses);
    Queue interactiveProcesses(numProcesses);
    Queue interactiveEditingProcesses(numProcesses);
    Priority_queue batchProcess(numProcesses);

    // Read process information and add them to the arrived processes queue.
    for (int i = 0; i < numProcesses; i++) {
        int arrivalTime, burstTime, priority, type;
        cin >> arrivalTime >> burstTime >> priority >> type;
        Process process(i + 1, arrivalTime, getTypeString(type), burstTime, priority);
        arrivedProcesses.insert(process);
        queueEnteringTime[i] = arrivalTime;
        waitingTime[i] = 0;
    }

    // Main scheduling loop.
    while (!arrivedProcesses.isEmpty() || !systemProcesses.isEmpty() || !interactiveProcesses.isEmpty() || !interactiveEditingProcesses.isEmpty() || !batchProcess.isEmpty()) {
        while (!arrivedProcesses.isEmpty() && arrivedProcesses.top().getArrivalTime() <= currentTime) {
            Process topushed = arrivedProcesses.extractMin();
            if (topushed.getType() == "System") systemProcesses.insert(topushed);
            else if (topushed.getType() == "Interactive") interactiveProcesses.enqueue(topushed);
            else if (topushed.getType() == "Interactive Editing") interactiveEditingProcesses.enqueue(topushed);
            else if (topushed.getType() == "Batch") batchProcess.insert(topushed);
        }
        if (!systemProcesses.isEmpty()) {
            priorityScheduler(systemProcesses);
        } else if (!interactiveProcesses.isEmpty()) {
            RoundRobinScheduler(interactiveProcesses);
        } else if (!interactiveEditingProcesses.isEmpty()) {
            RoundRobinScheduler(interactiveEditingProcesses);
        } else if (!batchProcess.isEmpty()) {
            firstComeFirstServeScheduler(batchProcess);
        }
        else currentTime++;
    }

    // Print the Gantt Chart.
    chart = headOfChart->next;
    cout << "GRANT CHART" << endl;
    cout << "0";
    int prev = 0;
    while (chart != nullptr) {
        if (prev != chart->startTime) {
            cout << " | IDLE | " << chart->startTime;
        }
        while (chart->next != nullptr && chart->pid == chart->next->pid) {
            chart = chart->next;
        }
        cout << " | P" << chart->pid << " | " << chart->endTime;
        prev = chart->endTime;
        chart = chart->next;
    }
    cout << endl;

    // Print waiting times for each process and calculate average waiting time.
    cout << "Waiting Time For Each Process" << endl;
    double sum = 0;
    for (int i = 0; i < numProcesses; i++) {
        cout << "P" << i + 1 << ": " << waitingTime[i] << endl;
        sum += waitingTime[i];
    }
    cout << "Average Waiting Time: " << sum / numProcesses << endl;

    // Print turn around times for each process and calculate average turn around time.
    cout << "Turn Around Time Of Each Process" << endl;
    sum = 0;
    for (int i = 0; i < numProcesses; i++) {
        cout << "P" << i + 1 << ": " << turnAroundTime[i] << endl;
        sum += turnAroundTime[i];
    }
    cout << "Average Turn Around Time: " << sum / numProcesses << endl;

    return 0;
}

但是,在执行程序时,屏幕上没有输出。谁能帮我解决这个问题并指出我哪里出了问题?

C++ C++17 优先级队列 作业调度

评论

0赞 Igor Tandetnik 10/13/2023
无法重现。该程序为我打印了一些东西
0赞 SYED ALI MEHDI RIZVI 10/14/2023
它是否提供了所需的输出?
0赞 Igor Tandetnik 10/14/2023
我不知道输出应该是什么。或者输入,就此而言。但它打印了一些东西。您可以自己查看:单击链接,查看右下角的输出面板。

答: 暂无答案