实验六 磁盘调度算法

一、  需求分析

说明程序设计的任务和目的,明确规定下述内容:

加深对磁盘调度算法的理解,进一步掌握先来先服务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
    }
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值