我有一个对象
public class Task
{
public TimeSpan Length { get; set; }
public IList<Task> Dependencies { get; set; }
public DateTime? StartDate { get; set; }
}
与其他实例有依赖关系。例如:
(读作“&lt; - ”为“取决于”)
和
给定一个Tasks *和EndDate列表,我需要在每个任务上设置StartDate,以便它们全部由EndDate完成。任务可以在可能的情况下并行运行,所以......
A必须在B和C之前完成(可以同时完成),D只能在B和C都完成后才能运行。
R必须在Q之后运行,在P之后,但这些可以在parelell中运行到A B C和D.
*列表将完整,所有依赖项将出现在列表中
感谢您的任何建议 安德鲁
答案 0 :(得分:1)
答案 1 :(得分:1)
您需要计算关键路径。如果有帮助,请参阅this question。
否则,这是一个简单的动态编程问题。
答案 2 :(得分:0)
这听起来更像是同步活动。即在线程中你会使用WaitHandles。
A启动并传递B等待句柄和C等待句柄
一旦A完成B和C启动,由于等待句柄被发信号
D有一个等待句柄,在B和C上等待ANY,所以谁先完成将发出信号D
答案 3 :(得分:0)
对于小图,只需递归计算开始日期 - D的开始日期为min(B.StartDate,C.StartDate) - D.Length
。
对于大型图形,执行拓扑排序,然后可以迭代执行计算。
答案 4 :(得分:0)
public class Task
{
public long Length;
public List<Task> Dependencies = new List<Task>();
public DateTime StartDate;
public DateTime EndDate;
public void CompleteBaseSchedule()
{
DateTime startDate = DateTime.MinValue;
foreach (Task task in Dependencies)
{
startDate = (startDate < task.EndDate) ? task.EndDate : startDate;
task.CompleteBaseSchedule();
}
this.StartDate = startDate;
this.Length = this.EndDate.Ticks - this.StartDate.Ticks;
}
主要的某个地方:
Task task1 = new Task();
task1.EndDate = new DateTime(2009, 3, 3);
Task task2 = new Task();
task1.EndDate = new DateTime(2009, 3, 5);
Task task3 = new Task();
task1.EndDate = new DateTime(2009, 3, 2);
Task task4 = new Task();
task1.EndDate = new DateTime(2009, 3, 6);
task4.Dependencies.AddRange(new Task[]{ task1, task2, task3 });
task4.CompleteBaseSchedule();
Console.WriteLine(task4.StartDate);
Console.ReadLine();
答案 5 :(得分:0)
感谢大家的建议,Topological排序的东西很有用,但我想我已经解决了它更简单的方法......
public class Scheduler
{
private readonly IEnumerable<Task> tasks;
private readonly DateTime endDate;
public Scheduler(IEnumerable<Task> tasks, DateTime endDate)
{
this.tasks = tasks;
this.endDate = endDate;
}
public void Schedule()
{
var terminators = FindTerminators();
SetStartDatesRecursively(terminators, endDate);
}
public ICollection<Task> FindTerminators()
{
IList<Task> terminators = new List<Task>();
foreach(var task in tasks)
{
var dependencies = this.tasks.Where(x => x.Dependencies.Contains(task));
if (dependencies.Count() == 0)
terminators.Add(task);
}
return terminators;
}
public void SetStartDatesRecursively(IEnumerable<Task> tasks, DateTime endDate)
{
foreach(var task in tasks)
{
var startDate = endDate - task.Length;
if (task.StartDate.HasValue)
task.StartDate = startDate < task.StartDate ? startDate : task.StartDate;
else
task.StartDate = startDate;
SetStartDatesRecursively(task.Dependencies, task.StartDate.Value);
}
}
}