目标是使用m个比较结果(布尔值)的列表C对n个未知变量{x0,x1,x2,... x(n-1)}的列表X进行排序。每个比较在n个变量中的两个之间,例如, x2< x5,每个比较的对索引是固定的,并提前给出。另外给出:C中的所有对都是唯一的(即使翻转时,例如对x0,x1表示没有对x1,x0),也从不将变量与自身进行比较。这意味着C最多有n *(n-1)/ 2个条目。
所以问题是我可以证明我的m比较列表C足以对列表X进行排序吗?显然,如果C是最大可能长度(进行所有可能的比较)。但是短名单呢?
然后,如果已经证明C包含足够的信息进行排序,那么我该如何实际执行排序。
答案 0 :(得分:4)
让我们假设你有一组要排序的对象,并从中形成一个图形,每个对象有一个节点。然后给出一个对列表,说明比较的方式。您可以将这些视为图中的边:如果您知道对象x的比较小于对象y,那么您可以从x到y绘制边。
假设比较结果是一致的 - 也就是说,你没有任何周期 - 你应该有一个有向无环图。
考虑一下如果在拓扑上对此DAG进行排序会发生什么。你最终得到的是与所有约束一致的值的一种可能排序。这样做的原因是,在拓扑排序中,如果存在从y到x的任何可传递的边缘系列,则不会在元素y之前放置元素x,并且存在从y到x的可传递的一系列边缘有一系列比较可以传递地表明y在x之前。
您实际上可以做出更强烈的主张:DAG的所有拓扑排序的集合正好满足所有约束的所有可能排序的集合。我们已经认为每个拓扑排序都满足所有约束,因此我们现在需要做的就是争论满足所有约束的每个序列都是有效的拓扑排序。这里的论点基本上是,如果你遵守所有的约束,你永远不会在它传递的比较小的东西之前在序列中放置任何元素,所以你永远不要在有一个路径的东西之前在序列中放置任何元素。
这为我们提供了解决问题的好方法:以这种方式形成图形,看看它是否只有一个拓扑排序。如果是这样,那么该排序是唯一的排序顺序。如果没有,那么有两个或更多的排序。
那么如何最好地解决这个问题呢?好吧,进行拓扑排序的标准算法之一是用其indegree注释每个节点,然后重复拉出indegree零点的节点并调整其后继者的indegree。如果在执行该算法的过程中,DAG只有一个拓扑排序,在每个阶段都只有一个零度节点,因为在这种情况下,拓扑排序是强制的。
使用正确的设置和数据结构,您可以实现此操作以及时运行O(n + m),其中n是节点数,m是约束数。我将把这些细节作为一个众所周知的练习留给读者。 : - )
答案 1 :(得分:2)
您的问题可以简化为众所周知的Topological sort。
证明“C包含足够的信息来排序”是为了证明拓扑排序的唯一性:
如果拓扑排序具有排序顺序中的所有连续顶点对通过边连接的属性,则这些边在DAG中形成有向哈密顿路径。如果存在哈密尔顿路径,则拓扑排序顺序是唯一的;没有其他顺序尊重路径的边缘。相反,如果拓扑排序不形成哈密顿路径,则DAG将具有两个或更多有效的拓扑排序,因为在这种情况下,总是可以通过交换两个未通过边连接的连续顶点来形成第二个有效排序对彼此。因此,尽管存在更一般有向图的哈密顿路径问题的NP-硬度,但是可以在线性时间内测试是否存在唯一排序,以及是否存在哈密顿路径(Vernet& Markenzon 1997)。