【问题标题】:Hard Algorithm Implementation硬算法实现
【发布时间】:2015-11-06 18:45:45
【问题描述】:

我无法实现 SJF(最短作业优先)算法。

SJF 是这样工作的

如果进程到达时间为 0,它将一直工作到下一个进程到达,算法必须检查到达时间为 1 的到达(进程/进程)是否短于当前剩余时间
示例:P0 执行了 1 并且仍然 2 完成,现在我们在 1 中有 P0,P1,P2,P3,P4 算法将执行最短的一个 P3,然后是 P0,然后是 P4,然后是 P1,依此类推。问题是我必须将它们的开始和结束时间执行以及等待时间保存到所有进程。

这是我最新的算法。 (会出现一些错误的情况)

输入数据:

Process Arrival Burest 
P0      0       3
P1      0       4
P2      0       5
P3      1       1
p4      1       3

for (i = 0; i < proc.Count; i++)
{
    minProcIndex = i;
    for (x = i; x < proc.Count; x++)
    {
        for (int y = 0 ; y < proc.Count; y++)
        {
            if (y == minProcIndex)
                continue;

            if (tempBrust[minProcIndex] - tempArrival[y] > tempBrust[y] 
                && tempBrust[y] != 0)
            {
                tempBrust[minProcIndex] -= tempArrival[y];
               // tempArrival[minProcIndex] += tempArrival[y];
                clock += tempArrival[y];
                //proc[y].start = clock;
                minProcIndex = y;
            }
            else if (y != proc.Count -1)
                continue;
            else
            {
                if (y == 0)
                {
                    proc[minProcIndex].start = 0;
                }
                else if (proc[y].start > 0)
                {
                    proc[y].start = clock;
                }
                else
                proc[minProcIndex].start = clock;

                proc[minProcIndex].end = proc[minProcIndex].brust + clock;
                tempBrust[minProcIndex] = 0;
                clock += proc[minProcIndex].brust;
                if (minProcIndex == proc.Count - 1)
                    minProcIndex = 0;
                else
                minProcIndex++;
                for (int c = 0; c < proc.Count; c++)
                {
                    if (tempArrival[c] < clock)
                        tempArrival[c] = clock - 1;
                }
            }
        }
    }
}

【问题讨论】:

  • 看起来像家庭作业。如果您需要帮助,请更具体。您究竟做了什么来尝试调试问题并修复它?除了无法完成作业之外,您遇到了什么具体问题?请准确解释您发布的代码的作用,以及它与您希望它做什么的不同之处。请提供说明所有这些的a good, minimal, complete code example
  • 啊,这让我回到了我的操作系统课。
  • 我的代码遗漏了很多东西,我无法完成它,所以它无助于解释代码因为你可能有一个更好的(更好的想法)
  • 但是如果你真的想知道没关系,我已经尝试在每个循环中制作循环我会完成一些检查,比如最短的工作,在当前时间,下一个循环来检查是否有在不久的将来更短的,如果不是它会在所有工作中完成它
  • 首先,我相信您正在尝试实现最短剩余时间,而不是最短作业优先。你的代码太复杂了,正确的解决方案可能很简单,所以我怀疑你是在想问题。我建议你制作纸条,每个流程一张。然后假装你是计算机,并确定你将如何完成订购它们的任务。提示:您需要一个橡皮擦,以便在工作时更改“burst”值。

标签: c# algorithm loops for-loop operating-system


【解决方案1】:

我认为如果你创建一个类来保存进程信息,这会更容易

public class ProcessInformation
{
    public string Name { get; private set; }
    public int Duration { get; private set; }
    public int ArrivalTime { get; private set; }

    public int TimeLeft { get; set; }
    public int? StartTime { get; set; }
    public int? EndTime { get; set; }
    public List<int> InterruptTimes { get; private set; }

    public ProcessInformation(string name, int arrivalTime, int duration)
    {
        Name = name;
        ArrivalTime = arrivalTime;
        Duration = duration;
        TimeLeft = duration;
        InterruptTimes = new List<int>();
    }
}

然后你就可以运行下面的代码了

var processes = new List<ProcessInformation>
                {
                    new ProcessInformation("P0", 0, 3),
                    new ProcessInformation("P1", 0, 4),
                    new ProcessInformation("P2", 0, 5),
                    new ProcessInformation("P3", 1, 1),
                    new ProcessInformation("P4", 1, 3)
                };

int currentTime = 0;
ProcessInformation currentProcess = null;
while (processes.Any(p => p.TimeLeft > 0))
{
    var shortest =
        processes.Where(p => p.ArrivalTime <= currentTime && p.TimeLeft > 0)
            .OrderBy(p => p.TimeLeft)
            .FirstOrDefault();

    if (currentProcess != null && currentProcess.TimeLeft > 0 && shortest != currentProcess)
    {
        currentProcess.InterruptTimes.Add(currentTime);
    }

    if (shortest != null)
    {
        if (shortest.StartTime == null) shortest.StartTime = currentTime;
        shortest.TimeLeft--;
        if (shortest.TimeLeft == 0) shortest.EndTime = currentTime + 1;
    }

    currentProcess = shortest;
    currentTime++;
}

foreach (var p in processes)
{
    Console.WriteLine(
        "Process {0} arrived {1} started {2} ended {3} duration {4} wait {5} interrupt times {6}", 
        p.Name, 
        p.ArrivalTime, 
        p.StartTime, 
        p.EndTime, 
        p.Duration, 
        p.EndTime - p.ArrivalTime - p.Duration,
        p.InteruptTimes.Any() ? string.Join(", ", p.InteruptTimes) : "None");
}

输出如下

进程 P0 到达 0 开始 0 结束 4 持续时间 3 等待 1 中断次数 1

进程 P1 到达 0 开始 7 结束 11 持续时间 4 等待 7 中断次数 无

进程 P2 到达 0 开始 11 结束 16 持续时间 5 等待 11 中断次数 无

进程 P3 到达 1 开始 1 结束 2 持续时间 1 等待 0 中断次数 无

进程 P4 到达 1 开始 4 结束 7 持续时间 3 等待 3 中断时间 无

【讨论】:

  • 嘿@Juharr 感谢您有时间回答我,但我想知道我如何才能知道第一次进程何时退出。示例第一个过程:它在 1 个时间单位 0 - 1 后退出,因为还有一些其他最短的过程到达,你的代码很棒而且我理解它很容易,但是我必须添加什么来实现这个?
  • 我不确定我是否遵循。您是否想要首先完成的进程(在本例中为 P3),或者您是否还要求包括进程被中断并且必须将 CPU 让给另一个进程的时间?第一个只是processes.OrderBy(p =&gt; p.EndTime).First();,而第二个则需要跟踪在上一个时钟周期内哪个进程在 CPU 中。
  • 是的,我只想知道进程第一次中断的时间(仅第一次中断)不关心其他解释
  • 如果没有中断时间与结束时间相同
  • 我已更新答案以包含所有中断。如果您愿意,您当然可以忽略第一个之后的任何内容。对于这个例子来说,无论如何,一个进程只有一个中断。
猜你喜欢
  • 1970-01-01
  • 2013-11-29
  • 2016-11-06
  • 2020-05-18
  • 2017-12-10
  • 2022-01-05
  • 2011-07-02
  • 2023-04-11
相关资源
最近更新 更多