说明程序设计的任务和目的,明确规定下述内容:
加深对磁盘调度算法的理解,进一步掌握先来先服务FCFS、最短寻道时间优先 SSTF、SCAN和循环SCAN算法的实现方法。
(1) 输入的形式和输入值的范围;
输入1-4的整数选择算法
已在程序中预置好磁盘访问请求
(2) 输出的形式;
磁盘调度过程
(3) 程序所能达到的功能;
模拟FCFS、 SSTF、SCAN和循环SCAN算法对磁盘调度的过程
(4) 测试数据,包括正确的输入及其输出结果和含有错误的输入及其输出结果。
二、 概要设计
说明本程序中用到的所有抽象数据类型的定义、主程序的流程以及各程序模块之间的层次(调用)关系。
磁道访问请求对象
classTrackOrder
{
publicint ArriveID;//到达顺序编号
publicint TrackOrderID;//访问目标磁道
publicint MoveDistance;//本次访问移动的距离
publicint TempDistance;//缓存距离
}
三、 详细设计
实现程序模块的具体算法。
staticList<TrackOrder> FCFS(List<TrackOrder> list)
staticList<TrackOrder> SSTF(List<TrackOrder> list, int curentPostion)
staticList<TrackOrder> SCAN(List<TrackOrder> list, int curentPostion,MoveDirection direcion)
staticList<TrackOrder> CSCAN(List<TrackOrder> list, int curentPostion, MoveDirection direcion)
四、 调试分析
(1) 调试过程中遇到的问题以及解决方法,设计与实现的回顾讨论和分析;
从几个算法中抽闲出相同点,最后将问题转化为排序问题
五、 用户使用说明
程序的使用说明,列出每一步的操作步骤。
运行程序--选择算法--查看结果
六、 测试结果
列出测试结果,包括输入和输出。
七、 附录
带注释的源程序,注释应清楚具体;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Lab6
{
enum MoveDirection
{
Left,Right
}
class TrackOrder//磁道访问请求对象
{
public int ArriveID;//到达顺序编号
public int TrackOrderID;//访问目标磁道
public int MoveDistance;//本次访问移动的距离
public int TempDistance;//缓存距离
//构造函数
public TrackOrder(int ArriveID, int TrackOrderID, int MoveDistance)
{
this.ArriveID = ArriveID;
this.TrackOrderID = TrackOrderID;
this.MoveDistance = MoveDistance;
TempDistance = -1;
}
}
class Program
{
#region 公共函数
//获取差的绝对值
static int getAbsoluteValue(int a, int b)
{
return a - b > 0 ? a - b : b - a;
}
//根据方向获取差值,若b在a的移动方向,则返回正值,若在移动的反方向则返回负值
static int getDifferenceValue(int a, int b,MoveDirection direcion)
{
if (direcion == MoveDirection.Right)
{
return b - a;
}
else
{
return a-b;
}
}
//打印序列[返回平均移动磁道数]
static double printTrackOrderList(List<TrackOrder> list,string tipStr="序列如下",bool caculateAvg=false)
{
Console.WriteLine(tipStr);
double avgDistance = 0;
double sumDistance = 0;
for (int i = 0; i < list.Count; i++)
{
if (caculateAvg)
{
sumDistance += list[i].MoveDistance;
Console.WriteLine("请求编号:" + list[i].ArriveID + " 访问目标磁道:" + list[i].TrackOrderID + " 本次访问移动的距离:" + list[i].MoveDistance);
}
else
{
Console.WriteLine("请求编号:" + list[i].ArriveID + " 访问目标磁道:" + list[i].TrackOrderID );
}
}
avgDistance=sumDistance/list.Count;
return avgDistance;
}
//处理序列
static void dealTrackOrderList(List<TrackOrder> list, int curentPostion)
{
Console.WriteLine("正在处理...");
for (int i = 0; i < list.Count; i++)
{
list[i].MoveDistance = getAbsoluteValue(curentPostion, list[i].TrackOrderID);
curentPostion = list[i].TrackOrderID;
}
}
#endregion
static void Main(string[] args)
{
Console.WriteLine("----------磁盘调度算法----------- \n");
//磁头当前位置
int curentPostion=100;
//移动方向(1向内 2向外)
MoveDirection moveDirection = MoveDirection.Right;
//请求序列
List<TrackOrder> TrackOrderList = new List<TrackOrder>();
int[] TrackOrderIDs = new int[] {55,58,39,18,90,160,150,38,184 };
for (int i = 0; i < 9; i++) //按顺序添加9条访问请求
{
TrackOrderList.Add(new TrackOrder(i,TrackOrderIDs[i],-1));
}
printTrackOrderList(TrackOrderList, "磁盘访问序列如下");
Console.WriteLine("请选择算法1-FCFS,2-SSTF,3-SCAN,4-CSCAN");
string choose=Console.ReadLine();
switch (choose)
{
case "1": { TrackOrderList = FCFS(TrackOrderList); } break;//先来的优先
case "2": { TrackOrderList = SSTF(TrackOrderList, curentPostion); } break;//最短寻道时间优先
case "3": { TrackOrderList = SCAN(TrackOrderList, curentPostion, moveDirection); } break;//按方向扫描
case "4": { TrackOrderList = CSCAN(TrackOrderList, curentPostion, moveDirection); } break;//单一方向扫描
default: { Console.WriteLine("输入错误,程序即将终止"); } break;
}
dealTrackOrderList(TrackOrderList,curentPostion);
double avgTime= printTrackOrderList(TrackOrderList, "处理结果如下",true);
Console.WriteLine("平均寻道时间:" + avgTime);
Console.ReadLine();
}
#region 4种算法
//先来先访问-按到达先后排序
static List<TrackOrder> FCFS(List<TrackOrder> list)
{
Console.WriteLine("先来的优先[FCFS]");
return list.OrderBy(m => m.ArriveID).ToList();
}
static List<TrackOrder> SSTF(List<TrackOrder> list, int curentPostion)
{
Console.WriteLine("最短寻道时间优先[SSTF]");
List<TrackOrder> result = new List<TrackOrder>();
//复制一份数据
TrackOrder[] temp = new TrackOrder[list.Count];
list.CopyTo(temp, 0);
List<TrackOrder> tempList = temp.ToList();
for (int k = 0; k < list.Count; k++)
{
//计算和当前位置的差值绝对值
for (int i = 0; i < tempList.Count; i++)
{
tempList[i].TempDistance = getAbsoluteValue(curentPostion, tempList[i].TrackOrderID);
}
//按绝对值排序
List<TrackOrder> tt= tempList.OrderBy(m => m.TempDistance).ToList();
//取第一个元素加入结果集
result.Add(tt[0]);
//在缓存中删除加入结果集的节点
tempList.Remove(tt[0]);
//移动磁头
curentPostion = tt[0].TrackOrderID;
}
return result;
}
static List<TrackOrder> SCAN(List<TrackOrder> list, int curentPostion,MoveDirection direcion)
{
Console.WriteLine("按方向扫描[SCAN]");
List<TrackOrder> result = new List<TrackOrder>();
//复制一份数据
TrackOrder[] temp = new TrackOrder[list.Count];
list.CopyTo(temp, 0);
List<TrackOrder> tempList = temp.ToList();
for (int k = 0; k < list.Count; k++)
{
//计算和当前位置的差值
for (int i = 0; i < tempList.Count; i++)
{
tempList[i].TempDistance = getDifferenceValue(curentPostion, tempList[i].TrackOrderID, direcion);
}
//排序,忽略小于0的元素
List<TrackOrder> tt = tempList.Where(q=>q.TempDistance>0).OrderBy(m => m.TempDistance).ToList();
//如果不存在大于0的元素,变换方向并跳过本次循环(回退k)
if (tt.Count==0)
{
Console.WriteLine("正在改变磁头方向...");
direcion = direcion == MoveDirection.Left ? MoveDirection.Right : MoveDirection.Left;
k--;
continue;
}
else
{
//取第一个元素加入结果集
result.Add(tt[0]);
//在缓存中删除加入结果集的节点
tempList.Remove(tt[0]);
//移动磁头
curentPostion = tt[0].TrackOrderID;
}
}
return result;
}
static List<TrackOrder> CSCAN(List<TrackOrder> list, int curentPostion, MoveDirection direcion)
{
Console.WriteLine("按单一方向扫描[SCAN]");
List<TrackOrder> result = new List<TrackOrder>();
//复制一份数据
TrackOrder[] temp = new TrackOrder[list.Count];
list.CopyTo(temp, 0);
List<TrackOrder> tempList = temp.ToList();
for (int k = 0; k < list.Count; k++)
{
//计算和当前位置的差值
for (int i = 0; i < tempList.Count; i++)
{
tempList[i].TempDistance = getDifferenceValue(curentPostion, tempList[i].TrackOrderID, direcion);
}
//排序,忽略小于0的元素
List<TrackOrder> tt = tempList.Where(q => q.TempDistance > 0).OrderBy(m => m.TempDistance).ToList();
//如果不存在大于0的元素,将磁头归至0位并跳过本次循环(回退k)
if (tt.Count == 0)
{
Console.WriteLine("正在将磁头归至0位...");
curentPostion = 0;
k--;
continue;
}
else
{
//取第一个元素加入结果集
result.Add(tt[0]);
//在缓存中删除加入结果集的节点
tempList.Remove(tt[0]);
//移动磁头
curentPostion = tt[0].TrackOrderID;
}
}
return result;
}
#endregion
}
}