作業系統電梯演算法和SSTF演算法
阿新 • • 發佈:2022-04-04
OS實驗四
一、要求
假定一磁碟有200個柱面,編號為0~199,當前移動臂的位置在143號柱面上,並剛剛完成125號柱面的服務請求,如果請求佇列的先後順序是86,147,91,177,94,150,102,175,130。請按下列演算法分別計算為完成上述各次訪問總共需要的磁頭移動量,並寫出磁頭的移動順序。要求通過編寫模擬程式實現,開發工具任選。
(1)電梯演算法;
(2)最短尋找時間優先演算法(SSTF)。
二、演算法
#include <bits/stdc++.h> using namespace std; #define ll long long const int maxn = 100; const int INF = 0x3f3f3f3f; /* 題目要求: 假定一磁碟有200個柱面,編號為0~199,當前移動臂的位置在143號柱面上,並剛剛完成125號柱面的服務請求,如果請求佇列的先後順序是86,147,91,177,94,150,102,175,130。請按下列演算法分別計算為完成上述各次訪問總共需要的磁頭移動量,並寫出磁頭的移動順序。要求通過編寫模擬程式實現,開發工具任選。 (1)電梯演算法; (2)最短尋找時間優先演算法(SSTF)。 */ int M[maxn] = {143,86,147,91,177,94,150,102,175,130};//// 當前的記憶體訪問序列 和之前一樣 但是最前面放的是143 因為當前我們是從143開始,方便後續操作 bool flag[maxn];/// S S T F演算法 標記是否訪問 bool flag_1[maxn];/// 電梯演算法 標記是否訪問 int N[maxn];/// S S T F演算法的最終訪問序列 int N_1[maxn];/// 電梯演算法L O O K的最終的訪問序列 /* */ int cnt;/// 當前N或者N_1 已經訪問的序列之中放了多少個數值 int all;/// 移動總量 void init()/// 初始化 { memset(flag,false,sizeof(flag));//// flag的初始值都變成false memset(flag_1,false,sizeof(flag_1)); memset(N,0,sizeof(N));//// N存放訪問序列 所有的初始值都變成0 memset(N_1,0,sizeof(N_1)); } void out_sstf() { cout<<"磁頭移動順序:"; for (int i=1;i<=cnt;++i) { cout<<N[i]<<' '; } cout<<endl; cout<<"總量"<<all<<endl; } void out_melactor() { cout<<"磁頭移動順序:"; for (int i=1;i<=cnt;++i) { cout<<N_1[i]<<' '; } cout<<endl; cout<<"總量"<<all<<endl; } void SSTF() { int idx = 0;/// 這個是用來記錄當前離所在地方距離最小的那個點的下標 int mine = INF;//// 最小距離 for (int i=1;i<=9;++i)/// 這個代表我當前要找九次,因為有九個數要走 { mine = INF;/// 這個沒找到當前最小的都要變回一個很大的數值 int local = M[idx];/// 當前的所在的位置 因為後面會使得idx變化所以我們需要存起來 for (int j=1;j<=9;++j) { if (!flag[j])/// 只有當沒有訪問過才作為下一步移動的預選目標 { int x = abs(local-M[j]); /// 距離等於當前所在的位置減去我想去的位置 if (x<mine) { mine = x;//// 找到當前距離更加小的那個 就把最小的距離進行改變 idx = j;/// 所在的下標也進行改變 } } } all += mine;///總量加上這個距離 flag[idx] = true;/// 標記表示這個已經訪問過了 N[++cnt] = M[idx];/// 放入訪問陣列之中 } out_sstf();/// 輸出 } void right(int &idx)/// 傳入idx主要是現在的位置去找到哪個位置離他最近 往增大的地方查詢 { int mine = INF;/// 記住 這裡是從裡面找到最近的,不是雙層迴圈 不用放在for裡面 可以對比下SSFT,因為這裡有兩個方向所以 /// 要寫成兩個函式 int local = M[idx];/// 當前位置 for (int i=1;i<=9;++i) { if (!flag_1[i]&&local<M[i])/// 找到沒有訪問過 而且數值比當前大的 { int x = abs(local-M[i]); if (x<mine) { mine = x; idx = i; } } } flag_1[idx] = true;/// 標記已經訪問 } void left(int &idx)/// 傳入idx主要是現在的位置去找到哪個位置離他最近 往增大的地方查詢 { int mine = INF; int local = M[idx];/// 當前位置 for (int i=1;i<=9;++i) { if (!flag_1[i]&&local>M[i]) { int x = abs(local-M[i]);/// 找到當前沒有訪問過的切數值小的 if (x<mine) { mine = x; idx = i; } } } flag_1[idx] = true;/// 標記已經訪問 } void Elevator()/// 電梯演算法 { bool f = true;/// 確定方向 false代表往左邊(去往比他小的) true代表往右邊 (去往比他大的) //// 由於題目中說了剛剛從125轉移到143 所以是遞增 int sum_1 = 0;/// 統計有多少個數比143要小 int sum_2 = 0;/// 統計有多少個數字比143要大 int idx = 0;/// 和之前一樣 作為你當前位置的下標 for (int i=1;i<=9;++i) { if (M[i]<M[idx]) ++sum_1;//// 統計有多少小的 } sum_2 = 9 - sum_1; /// cout<<sum_1<<endl; for (int i=1;i<=9;++i)/// 找九次 { int local = M[idx];/// 存放當前位置 if (f) { right(idx);/// 右邊 找到比他大的裡面最近的那個 --sum_2; } else { left(idx);/// 左邊 找到比他小的裡面最近的那個 --sum_1; } /// cout<<idx<<endl; if (!sum_1 || !sum_2) { f = !f;/// 調轉方向 sum_1 = 100;/// 這裡為什麼要這樣 是因為如果你不把sum_1和sum_2 變大,就一直執行這個語句,那樣方向一直調轉 sum_2 = 100; //// 因為這個演算法最多一種方向完成後就是另外一種方向,也就是方向只需要調轉一次 };/// 一個方向完成 那麼反方向查詢 all += abs(local-M[idx]);//// 當前的減去下一個我要移動的目標之間的距離 N_1[++cnt] = M[idx];/// 存入我當前的訪問順序的陣列 } out_melactor(); } int main() { puts("-------------------------------請選擇你需要的演算法--------------------------------------"); puts("---------------1.SSTF演算法\t\t 2.電梯演算法LOOK----------------------"); int n; cin>>n; init();/// 程式開始先執行初始化操作 if (n==1) SSTF();//// 執行sstf演算法 else if (n==2)Elevator(); return 0; }