如何从给定图中的项目子集进行拓扑排序?
How to do a topological sort from a subset of items from a given graph?
我有以下问题:给你一个待办事项列表,其中一些项目依赖于其他项目。编写一个函数,该函数接受这些待办事项的子集和 returns 所有要完成的待办事项的有序列表。给定的子集包含这些待办事项中的一个或多个。
我使用 Kahn 算法编写了拓扑排序,将给我的列表转换为邻接列表。当我有待办事项的有序列表时,我开始将它们添加到另一个数组中,并在它包含给定子集中的所有项目时停止。
这行得通,但我觉得它有点笨拙且效率低下,因为我对整个列表进行排序,然后返回截断的版本。
关于如何让这个解决方案更优雅一点有什么想法吗?
您应该能够检查每个任务是否添加到输出 filteredTasks
,而不是进行单独的过滤过程,因为它被处理以添加到 orderedTasks
。
由于 orderedTasks
的唯一其他用途是检查其长度,因此您应该可以用计数器替换它。
这可能不会使您的函数更快,但会简化您的代码。
不要认为这是拓扑排序。将此视为“首先执行依赖项,不要执行两次”。这是一个简单的递归函数,只要我们跟踪我们将要做什么以及已经做了什么。
以下 Python 解决方案可能会使这一点更清楚。
def arrange_tasks(dependencies, todo, in_order=None, done=None):
if in_order is None:
in_order = []
if done is None:
done = set()
for item in todo:
# Do we need to?
if item not in done:
# Marking it done first avoids deep recursion on dependency loops!
done.add(item)
# Make sure that dependencies happened.
arrange_tasks(dependencies, dependencies[item], in_order, done)
# And now this can happen.
in_order.append(item)
return in_order
print(arrange_tasks(
{
'make a sandwich': ['buy groceries'],
'buy groceries': ['go to store'],
'go to store': []
},
['buy groceries']
))
我有以下问题:给你一个待办事项列表,其中一些项目依赖于其他项目。编写一个函数,该函数接受这些待办事项的子集和 returns 所有要完成的待办事项的有序列表。给定的子集包含这些待办事项中的一个或多个。
我使用 Kahn 算法编写了拓扑排序,将给我的列表转换为邻接列表。当我有待办事项的有序列表时,我开始将它们添加到另一个数组中,并在它包含给定子集中的所有项目时停止。
这行得通,但我觉得它有点笨拙且效率低下,因为我对整个列表进行排序,然后返回截断的版本。
关于如何让这个解决方案更优雅一点有什么想法吗?
您应该能够检查每个任务是否添加到输出 filteredTasks
,而不是进行单独的过滤过程,因为它被处理以添加到 orderedTasks
。
由于 orderedTasks
的唯一其他用途是检查其长度,因此您应该可以用计数器替换它。
这可能不会使您的函数更快,但会简化您的代码。
不要认为这是拓扑排序。将此视为“首先执行依赖项,不要执行两次”。这是一个简单的递归函数,只要我们跟踪我们将要做什么以及已经做了什么。
以下 Python 解决方案可能会使这一点更清楚。
def arrange_tasks(dependencies, todo, in_order=None, done=None):
if in_order is None:
in_order = []
if done is None:
done = set()
for item in todo:
# Do we need to?
if item not in done:
# Marking it done first avoids deep recursion on dependency loops!
done.add(item)
# Make sure that dependencies happened.
arrange_tasks(dependencies, dependencies[item], in_order, done)
# And now this can happen.
in_order.append(item)
return in_order
print(arrange_tasks(
{
'make a sandwich': ['buy groceries'],
'buy groceries': ['go to store'],
'go to store': []
},
['buy groceries']
))