移臂调度及调度算法 C#实现

在磁盘盘面上,0磁道在盘面的外部;号数越大,磁道越靠近盘片的中心。

常用的移臂调度算法有先来先服务算法、最短寻找时间优先算法、电梯调度算法和单向扫描调度算法。

先来先服务算法:

不考虑访问者要求访问的物理位置,而只是考虑访问者提出访问请求的先后次序。

最短寻找时间优先算法

总是从等待访问者中挑选寻找时间最短的那个请求先执行,先不管访问者到来的先后顺序。

电梯调度算法

从移臂当前位置开始沿着臂的方向去选择离当前移动臂最近的那个柱访问者,如果沿臂的方向无请求者,就改变臂的方向再选择。

算法上实现需分移动臂从里到外移动、移动臂从外向里移动。

移动臂从外向里移动(正向),柱面号从小到大,可理解为电梯移动从下到上。

移动臂从里到外移动(逆向),柱面号从大到小,可理解为电梯移动从上到下。

 

单向扫描调度算法

不考虑访问者的等待先后顺序,总是从0号柱面开始向里道扫描,然后再返回0号柱面,再次进行扫描。

(在这里代码实现我就从第一个访问柱面的开始向里道扫描)

 C#代码实现:

根据输入的柱面号访问序列,不同算法的服务顺序和移动总量。

环境:

 C#实现移臂调度及调度算法OSAlgorithm-C#文档类资源-CSDN下载



do
{
    Console.WriteLine("请选择其中一个移臂调度算法的编号:");
    Console.WriteLine("1:先来先服务算法(FCFS)");
    Console.WriteLine("2:短作业优先算法(SJF)");
    Console.WriteLine("3:磁盘扫描/电梯算法(大,正向,从下到上)");
    Console.WriteLine("4:磁盘扫描/电梯算法(小,逆向,从上到下)");
    Console.WriteLine("5:单向扫描调度算法");

    string inStr = Console.ReadLine();
    Console.WriteLine("请输入需要访问的柱面号,逗号隔开");//空格 \u0020
    string strList = Console.ReadLine();
    if (string.IsNullOrWhiteSpace(strList))
    {
        Console.WriteLine("你输入的柱面号为空。");
    }
    string[] strArr = strList.Split('\u002C');
    if (strArr == null || strArr.Count() <= 0)
    {
        Console.WriteLine("你输入的柱面号为空或者输入异常。");
    }
    List<int> list = new List<int>();
    try
    {
        foreach (string str in strArr)
        {
            list.Add(int.Parse(str));
        }
        list.Distinct();
    }
    catch (Exception ex)
    {
        Console.WriteLine("请输入正确的数字。");
    }
    if (list == null || list.Count <= 0)
    {
        Console.WriteLine("你输入的柱面号为空。");
        return;
    }
    if (list.Count == 1)
    {
        Console.WriteLine("你输入至少两个柱面号。");
        return;
    }

    switch (inStr)
    {
        case "1":
            Console.WriteLine(@"你选择了算法{0}", inStr);
            FCFS(list);
            break;
        case "2":
            Console.WriteLine(@"你选择了算法{0}", inStr);
            SJF(list);
            break;
        case "3":
            Console.WriteLine(@"你选择了算法{0}", inStr);
            ScanUp(list);
            break;
        case "4":
            Console.WriteLine(@"你选择了算法{0}", inStr);
            ScanDown(list);
            break;
        case "5":
            Console.WriteLine(@"你选择了算法{0}", inStr);
            OneWayScan(list);
            break;
        default:
            Console.WriteLine("请输入正确的算法编号。");
            break;

    }
    Console.WriteLine("按q退出,其他键继续。");
    if(Console.ReadLine().ToString().ToLower().Equals("q"))
    {
        break;
    }

} while (true);


//先来先服务
void FCFS(List<int> list)
{
    int mNum = 0;//移动总量
    for (int i = 1; i < list.Count; i++)
    {
        mNum+=Math.Abs(list[i]-list[i-1]);//当前磁头与上一个访问过的磁头的差值
    }
    Console.WriteLine(@"服务顺序为:{0}", string.Join(",", list));
    Console.WriteLine(@"移动总量为:{0}", mNum);

}

//短作业优先
void SJF(List<int> list)
{
    int mNum = 0;//移动总量
    int firstNum = list[0];//当前磁头位置
    List<int> newList = new List<int>();
    newList.Add(firstNum);//先记录当前磁头位置
    list.Sort();//排序
    int firthIndex = list.FindIndex(a=>a.Equals(firstNum));
    int len=list.Count;
    int left = firthIndex - 1;
    int right = firthIndex + 1;
    while (left>=-1 &&  right<=len)
    {
        int toLeft = 0;
        int toRight =0;
        if (left >= 0)
        {
            toLeft = Math.Abs(list[left] - firstNum);  //当前磁头跟小的磁头(取最近的)的差值
        }
        if (right < len)
        {
            toRight = Math.Abs(list[right] - firstNum);//当前磁头跟大的磁头(取最近的)的差值
        }
       
        if(toLeft>0 && (toLeft < toRight|| toRight==0))
        {
            //先访问小的
            newList.Add(list[left]);
            firstNum = list[left];
            mNum += toLeft;
            left--;
        }else if(toRight>0 && (toRight< toLeft || toLeft==0))
        {
            //先访问大的
            newList.Add(list[right]);
            firstNum = list[right];
            mNum += toRight;
            right++;
        }
        else
        {
            left--;
            right++;
        }
    }
    Console.WriteLine(@"服务顺序为:{0}", string.Join(",", newList));
    Console.WriteLine(@"移动总量为:{0}", mNum);

}

//磁盘扫描/电梯算法(大,正向)
void ScanUp(List<int> list)
{
    int mNum = 0;//移动总量
    int firstNum = list[0];//当前磁头位置
    List<int> newList = new List<int>();
    newList.Add(firstNum);//先记录当前磁头位置
    list.Sort();
    int firthIndex = list.FindIndex(a => a.Equals(firstNum));
    int len = list.Count;
    for (int i = firthIndex+1; i < len; i++)//正向
    {
        mNum +=(list[i] - firstNum);  //当前磁头跟最近的的磁头的差值
        firstNum =list[i];
        newList.Add(firstNum);
    }

    for (int i = firthIndex - 1; i >=0; i--)//逆向
    {
        mNum += Math.Abs(list[i] - firstNum);  //当前磁头跟最近的的磁头的差值
        firstNum = list[i];
        newList.Add(firstNum);
    }
    Console.WriteLine(@"服务顺序为:{0}", string.Join(",", newList));
    Console.WriteLine(@"移动总量为:{0}", mNum);
}

//磁盘扫描/电梯算法(小,逆向)
void ScanDown(List<int> list)
{
    int mNum = 0;//移动总量
    int firstNum = list[0];//当前磁头位置
    List<int> newList = new List<int>();
    newList.Add(firstNum);//先记录当前磁头位置
    list.Sort();
    int firthIndex = list.FindIndex(a => a.Equals(firstNum));
    int len = list.Count;
    for (int i = firthIndex - 1; i >= 0; i--)//逆向
    {
        mNum += Math.Abs(list[i] - firstNum);  //当前磁头跟最近的的磁头的差值
        firstNum = list[i];
        newList.Add(firstNum);
    }
    for (int i = firthIndex + 1; i < len; i++)//正向
    {
        mNum += (list[i] - firstNum);  //当前磁头跟最近的的磁头的差值
        firstNum = list[i];
        newList.Add(firstNum);
    }


    Console.WriteLine(@"服务顺序为:{0}", string.Join(",", newList));
    Console.WriteLine(@"移动总量为:{0}", mNum);
}

//单向扫描
void OneWayScan(List<int> list)
{
    int mNum = 0;//移动总量
    int firstNum = list[0];//当前磁头位置
    List<int> newList = new List<int>();
    newList.Add(firstNum);//先记录当前磁头位置
    list.Sort();
    int firthIndex = list.FindIndex(a => a.Equals(firstNum));
    int len = list.Count;
    for (int i = firthIndex + 1; i < len; i++)//正向
    {
        mNum += (list[i] - firstNum);  //当前磁头跟最近的的磁头的差值
        firstNum = list[i];
        newList.Add(firstNum);
    }
    //从0开始,
    if (firthIndex>0)
    {
        //从里转到外面的0磁道位置
        mNum += firstNum;
        firstNum = 0;
        newList.Add(0);
       
        for (int i = 0; i < firthIndex; i++)//再次从外到里
        {
            mNum += Math.Abs(list[i] - firstNum);  //当前磁头跟最近的的磁头的差值
            firstNum = list[i];
            newList.Add(firstNum);
        }
    }

    Console.WriteLine(@"服务顺序为:{0}", string.Join(",", newList));
    Console.WriteLine(@"移动总量为:{0}", mNum);
}

测试数据:100,55,58,39,18,90,160,115,38,184

结果:

 

  • 1
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
多机调度问题是一个经典的优化问题,它可以通过贪心算法来解决。 在多机调度问题中,我们有一组任务需要在多个机器上完成,每个任务有一个执行时间和一个处理机器。任务不能同时在同一台机器上执行,目标是最小化完成所有任务的时间。 下面是使用C#实现多机调度问题的贪心算法的基本步骤: 1. 定义一个任务类,该类包含任务编号、执行时间和分配机器的属性。 2. 将所有任务按照执行时间从大到小排序。 3. 创建一个机器列表,并将第一个任务分配给第一台机器。 4. 遍历剩余的任务列表,对于每个任务,将其分配给当前最短时间的机器。 5. 重复步骤4,直到所有任务都被分配。 6. 计算每台机器完成任务的时间,取最大值作为总完成时间。 下面是一个简单的C#代码实现: ``` class Task { public int Id { get; set; } public int Time { get; set; } public int Machine { get; set; } } static void Main(string[] args) { List<Task> tasks = new List<Task> { new Task { Id = 1, Time = 5 }, new Task { Id = 2, Time = 2 }, new Task { Id = 3, Time = 1 }, new Task { Id = 4, Time = 6 }, new Task { Id = 5, Time = 4 } }; // Sort tasks by time in descending order tasks.Sort((a, b) => b.Time.CompareTo(a.Time)); List<int> machines = new List<int>(); machines.Add(0); // Assign tasks to machines foreach (Task task in tasks) { int machineIndex = machines.IndexOf(machines.Min()); task.Machine = machineIndex; machines[machineIndex] += task.Time; } // Calculate total time int totalTime = machines.Max(); } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值