我的算法
1)我有一个空的completeTask列表,并与任务进行比较,我试图找到没有依赖性的任务(它是task_e) 什么时候做的,我将添加到完整列表中的第一任务(我只需要一个任务名称,因为我将依赖项的名称和任务名称进行了比较)并将其放在第一位。
2)我们完成了第一个任务-task_e是我们的第一个依赖项。 现在,我必须找到所有具有依赖关系的任务,然后执行。 何时将其添加到completeTask列表中,并执行其他任务
这是我的算法
public static void Sort(Task[] tasks)
{
List<String> completedTaskName = new List<String>();
Task temp;
for (int i = 0; i < tasks.Length; i++)
{
for (int j = i; j < tasks.Length; j++)
{
if (!tasks[j].Dependencies.Except(completedTaskName).Any())
{
temp = tasks[i];
tasks[i] = tasks[j];
tasks[j] = temp;
completedTaskName.Add(tasks[i].Name);
}
}
}
}
但是我排序时并不能正确显示
new Task("a", "b", "c"),
new Task("b"),
new Task("c", "b"),
答案 0 :(得分:3)
您是否一定需要在同一数组上应用排序,因为如果可以按顺序完成任务进行复制并追加到列表中,将容易得多。 使用与示例中相同的LINQ方法,您可以简单地根据任务的依赖性将任务从一个列表移至另一个列表,如下所示。
private static List<Task> Sort(Task[] tasks)
{
var completedTasks = new List<Task>();
var uncompletedTasks = tasks.ToList();
while (uncompletedTasks.Any())
{
var taskToComplete = uncompletedTasks
.FirstOrDefault(task => !task.Dependencies.Except(completedTasks.Select(x => x.Name)).Any());
if (taskToComplete == null)
{
// Cross dependency between tasks
Console.WriteLine($"Cross dependency between the tasks: {string.Join(", ", uncompletedTasks.Select(task => task.Name))}");
break;
}
completedTasks.Add(taskToComplete);
uncompletedTasks.Remove(taskToComplete);
}
return completedTasks;
}
然后只需Sort(tasks)
即可代替var sortedTasks = Sort(tasks)
答案 1 :(得分:2)
对OP的评论已经强调了您的代码中的一些问题:
无论如何,您不应该尝试实现排序算法,.Net框架已经为您实现了(一些)好的算法。不要重新发明轮子
您只需指定如何比较两个对象(在您的情况下为两个Task)。
您可以创建自己的TaskComparer,实现:IComparer<Task>
,并在(例如)Linq OrderBy
或List<Task>.Sort
中使用比较器
类似的事情应该起作用:
public class TaskComparer: IComparer<Task>
{
public virtual int Compare(Task t1, Task t2)
{
// second task is included in first task dependencies, it should be considered "bigger" than first
if (t1.Dependencies.Contains(t2.Name))
return 1;
// first task is included in second task dependencies, it should be considered "bigger" than second
if (t2.Dependencies.Contains(t1.Name))
return -1;
return 0;
}
}
public static void Main()
{
// The following array is an example of specific tasks and dependencies between them.
// For example the following constructor:
// new Task("task_a", "task_c")
// means that task_a may be started only after task_c is complete
var tasks = new[]
{
new Task("task_a", "task_c"),
new Task("task_b", "task_c"),
new Task("task_c", "task_e"),
new Task("task_d", "task_a", "task_e"),
new Task("task_e"),
};
var sortedList = tasks.OrderBy(t => t, new TaskComparer()).ToList();
foreach (Task t in sortedList)
Console.WriteLine(t.Name);
Console.WriteLine();
// another set of data
tasks = new Task[]
{
new Task("task_a", "task_b", "task_c"),
new Task("task_b"),
new Task("task_c", "task_b"),
};
sortedList = tasks.OrderBy(t => t, new TaskComparer()).ToList();
foreach (Task t in sortedList)
Console.WriteLine(t.Name);
}
输出:
task_e
task_c
task_a
task_b
task_d
task_b
task_c
task_a
在工作中here
查看