对相互依赖的作业列表进行排序

时间:2018-10-25 12:16:47

标签: c# list sorting

我想对相互依赖的作业进行排序。

  • 一个作业(可能)需要多个输入文件。
  • 作业创建一个输出文件。

在(ObservableCollection个作业列表中,某些作业要求其他作业在开始之前已完成(它们需要其他一些作业的输出)。

现在,我想订购一个随机的作业列表,以便以正确的顺序执行作业。在下面的代码中,我会尽力给出简短的代码版本和一些组合工作。

输入SearchNewPos 7次(在5个作业的列表中),导致动作比最佳5动作多。对于这么小的列表,这没问题,但是当列表变大时,迭代次数也增加了很多。

有人对这种排序有更聪明的方法吗?

namespace TestConsApp
{
  internal static class Program
  {
    private static void Main(string[] args)
    {          
      var work = new MyWork();
      work.ReorderJobs();

      Console.ReadLine();
    }
  }

  internal class MyWork
  {
    private ObservableCollection<Job> myJobs;

    private static int reorderSearces = 0;

    public void DoMyWork()
    {
      foreach (var j in myJobs)
      {
        j.DoWork();
      }
    }

    public MyWork()
    {
      myJobs = new ObservableCollection<Job>()
      {
        new Job()
          { OututFilename="output5", InputFilenames = new List<string>() {"output3","output4"} },
        new Job()
          { OututFilename="output4", InputFilenames = new List<string>() {"output2"} },
        new Job()
          { OututFilename="output3", InputFilenames = new List<string>() {"output1","input6"} },
        new Job()
          { OututFilename="output2", InputFilenames = new List<string>() {"input3","input4","input5"}},
        new Job()
          { OututFilename="output1", InputFilenames = new List<string>() {"input1","input2"}}
      };
    }

    public void ReorderJobs()
    {
      var newPos = 0;
      var oldPos = 0;
      while (SearchNewPos(ref newPos, ref oldPos))
      { myJobs.Move(oldPos, newPos);
        Console.WriteLine(string.Join(", ",myJobs.Select(j=>j.OututFilename).ToArray()));
      }
    }

    private bool SearchNewPos(ref int newPos, ref int oldPos)
    {
      Console.WriteLine("Reorder no. " + reorderSearces++);
      for (int iOldPos = myJobs.Count - 1; iOldPos >= 0; iOldPos--)
      {
        oldPos = iOldPos;
        for (int iNewPos = 0; iNewPos < iOldPos; iNewPos++)
        {
          if (myJobs[iNewPos].DoesJobUseFile(myJobs[iOldPos].OututFilename))
          {
            newPos = iNewPos;
            return true;
          }
        }
      }
      return false;
    }

  }

  internal class Job
  {

    public string OututFilename { get; set; }

    public List<string> InputFilenames { get; set; }

    public void DoWork()
    {
      ReadInput();
      Workout();
      WriteOutput();
    }

    private void Workout()
    {
      return;
    }

    private void ReadInput()
    {
      return;
    }

    private void WriteOutput()
    {
      return;
    }

    public bool DoesJobUseFile(string fileName)
    {
      return InputFilenames.Exists(s=>s.Equals(fileName));
    }

    public override string ToString()
    {
      return OututFilename;
    }
  }
}

0 个答案:

没有答案