1. 程式人生 > >磁碟排程演算法 C++實現

磁碟排程演算法 C++實現

常見的磁碟排程演算法大致分為以下5類:

FCFS、SSTF、SCAN、CSCAN、FSCAN

程式實現了上述5類排程演算法。

其中,當前磁軌和要求服務的磁軌均由系統隨機產生。

程式入口是main主函式,在程式一開始由request()函式產生隨機的要求服務的磁碟序列。然後由使用者選擇演算法FCFS、SSTF、SCAN、CSCAN、FSCAN其中之一。

分別執行相應的演算法。

1)FCFS演算法實現思路:將vector內隨機產生的數依次讀出,相當於對於佇列資料結構中的出隊操作。

2)SSTF演算法實現思路:在時間複雜度和空間複雜度上的綜合考慮,我首先將vector內的資料進行排序,然後確定當前磁軌號在有序資料中的位置,然後在該位置的左右找到離它最近的數,並將當前位置進行重新整理。

3)SCAN演算法實現思路:首先將vector內的資料進行排序,然後同樣地確定當前磁軌號在有序資料中的位置,然後在向內的方向上依次訪問,訪問完了之後,再輸出初始位置向外的服務序列。

4)CSCAN演算法實現思路:開始和前面的演算法一樣,也是先進行排序,定位,然後在向內的方向上依次訪問,訪問完了之後,再從最外層向內掃。

5)FSCAN演算法實現思路:將初始的序列放在一個佇列中,將在掃描過程中新出現的服務序列放在另一個序列中,然後對兩個佇列中的資料依次進行SCAN演算法的實現。

程式流程圖:


實驗結果:


源程式:

#include <iostream>
#include <time.h>
#include <vector>
#include <math.h>
#include <stdlib.h>
#include <algorithm>
#include <cstring>
#include <windows.h>
#include <fstream>
using namespace std;

int position = 0;      //當前磁軌位置
int dis = 0;
double average_distance = 0;

void request(vector<int>&m_vec,ofstream &outfile){
    cout<<"隨機生成磁碟序列:"<<endl;
    int n = 0;
    srand(time(NULL));     //新增隨機數種子
    n = rand() % 20 + 1;
    int temp = 0;
    for(int i=0;i<n;i++){
        temp = rand() % 100;
        m_vec.push_back(temp);
        cout<<temp<<" ";
        outfile<<temp<<endl;
    }
    cout<<endl;
    position = rand() % 100;
    cout<<"當前磁軌:"<<position<<endl;
}

void compute_dis(vector<int>m_vec,int &dis,double &average_distance){
    average_distance = (double)dis / (double)m_vec.size();
}

void FIFO(vector<int>m_vec,int position){     //先來先服務演算法
    dis = 0;
    average_distance = 0;
    for(vector<int>::iterator it=m_vec.begin();it!=m_vec.end();it++){
        dis += abs(position-*it);
        Sleep(500);
        cout<<"->"<<*it;
        position = *it;
    }
    compute_dis(m_vec,dis,average_distance);
}

void SSTF(vector<int>m_vec,int position){   //最短尋道時間演算法
    dis = 0;
    average_distance = 0;
    sort(m_vec.begin(),m_vec.end());    //從小到大排序
    int i = 0;
    for(vector<int>::iterator it=m_vec.begin();it!=m_vec.end();it++){
        if(position >= *it)
            i++;
    }
    int count = 0;
    int left = i-1;
    int right = i;
    while(count<m_vec.size()){
        if((left >=0 && abs(m_vec[right]-position) > abs(m_vec[left]-position)) || right>=m_vec.size()){
            dis += abs(m_vec[left]-position);
            Sleep(500);
            cout<<"->"<<m_vec[left];
            position = m_vec[left];
            left--;
        }
        else{
            dis += abs(m_vec[right]-position);
            Sleep(500);
            cout<<"->"<<m_vec[right];
            position = m_vec[right];
            right++;
        }
        count++;
    }
    compute_dis(m_vec,dis,average_distance);
}

void SCAN(vector<int>m_vec,int position){   //電梯排程演算法
    dis = 0;
    average_distance = 0;
    sort(m_vec.begin(),m_vec.end());    //從小到大排序
    int i = 0;
    for(vector<int>::iterator it=m_vec.begin();it!=m_vec.end();it++){
        if(position >= *it)
            i++;      //找到position所在的磁軌
    }
    int left = i - 1;   //先從外到內掃描
    int right = i;
    while(left >= 0){
        dis += abs(position - m_vec[left]);
        Sleep(500);
        cout<<"->"<<m_vec[left];
        position = m_vec[left];
        left --;
    }
    while(right < m_vec.size()){
        dis += abs(position - m_vec[right]);
        Sleep(500);
        cout<<"->"<<m_vec[right];
        position = m_vec[right];
        right ++;
    }
    compute_dis(m_vec,dis,average_distance);
}

void CSCAN(vector<int>m_vec,int position){   //迴圈掃描演算法
    dis = 0;
    average_distance = 0;
    sort(m_vec.begin(),m_vec.end());    //從小到大排序
    int i = 0;
    for(vector<int>::iterator it=m_vec.begin();it!=m_vec.end();it++){
        if(position >= *it)
            i++;      //找到position所在的磁軌
    }
    int left = i - 1;   //先從外到內掃描
    int right = i;
    while(left >= 0){
        dis += abs(position - m_vec[left]);
        Sleep(500);
        cout<<"->"<<m_vec[left];
        position = m_vec[left];
        left --;
    }
    position = 100;     //立即到最外側的磁軌
    int len = m_vec.size()-1;
    while(len >= right){
        dis += abs(position - m_vec[len]);
        Sleep(500);
        cout<<"->"<<m_vec[len];
        position = m_vec[len];
        len --;
    }
    compute_dis(m_vec,dis,average_distance);
}

void FSCAN(vector<int>m_vec,int position){   //分步電梯排程演算法,。分兩個佇列
    dis = 0;
    average_distance = 0;
    //SCAN(m_vec,position);
    sort(m_vec.begin(),m_vec.end());    //從小到大排序
    int i = 0;
    for(vector<int>::iterator it=m_vec.begin();it!=m_vec.end();it++){
        if(position >= *it)
            i++;      //找到position所在的磁軌
    }
    int left = i - 1;   //先從外到內掃描
    int right = i;
    while(left >= 0){
        dis += abs(position - m_vec[left]);
        Sleep(500);
        cout<<"->"<<m_vec[left];
        position = m_vec[left];
        left --;
    }
    while(right < m_vec.size()){
        dis += abs(position - m_vec[right]);
        Sleep(500);
        cout<<"->"<<m_vec[right];
        position = m_vec[right];
        right ++;
    }
    cout<<endl;
    cout<<"在掃描的過程中新產生的服務序列:"<<endl;
    vector<int>ve;
    while(!ve.empty())
        ve.pop_back();
    int n = 0;
    n = rand() % 20 + 1;
    int temp = 0;
    for(i=0;i<n;i++){
        temp = rand() % 100;
        cout<<temp<<" ";
        ve.push_back(temp);
    }
    cout<<endl;
    cout<<position;
    SCAN(ve,position);
    average_distance = (double)dis / (double)(m_vec.size()+ve.size());
}

void print(){
    cout<<endl<<endl;
    cout<<"經計算,磁頭移動的總距離為:"<<dis<<endl;
    cout<<"磁頭平均移動距離:"<<average_distance<<endl;
    cout<<endl<<endl;
}

int choose_algorithm(vector<int>m_vec){
    cout<<endl<<endl;
    cout<<"本實驗可用的排程演算法有以下5種:"<<endl;
    cout<<"1.FIFO  2.SSTF  3.SCAN  4.CSCAN  5.FSCAN  6.結束本序列的排程  7.結束程式"<<endl;
    int choice = 0;
    cout<<"選擇:"<<endl;
    cin>>choice;
    cout<<endl;
    while(choice!=6 && choice!=7){
        cout<<"磁碟請求的服務狀況:"<<endl;
        cout<<position;
        switch(choice){
            case 1:
                FIFO(m_vec,position);break;
            case 2:
                SSTF(m_vec,position);break;
            case 3:
                SCAN(m_vec,position);break;
            case 4:
                CSCAN(m_vec,position);break;
            case 5:
                FSCAN(m_vec,position);break;
            default:
                cout<<"******非法輸入!******"<<endl<<endl;break; 
        } 
        if(choice<=7 && choice>=1) 
            print();
        cout<<"選擇:"<<endl;
        cin>>choice;
    }
    if(choice == 7)
        return 0;
    else
        cout<<endl<<endl;
    return 1;
}

int main(){
    cout<<"---------------磁碟排程演算法模擬實驗-----------------"<<endl;
    ofstream outfile;
    outfile.open("data.txt");
    while(1){
        vector<int> vec;
        while(!vec.empty())
            vec.pop_back();
        request(vec,outfile);         //請求服務序列 
        int flag = choose_algorithm(vec);
        if(flag == 0)
            break;
    } 
    outfile.close();
    return 0;
}