我想对相互依赖的作业进行排序。
在(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;
}
}
}