给定成对排序矩阵,如何枚举所有可能的总订单

时间:2018-12-07 12:01:23

标签: c++ algorithm

我有一个二维矩阵Pairwise[i][j],其中[i][j]项是

(a)1,如果第i个元素“小于”第j个元素

(b)0,如果第i个元素“等于”第j个元素,并且

(c)-1,如果第i个元素既不小于也不等于第j个元素。

枚举总排序的所有可能子集的有效方法是什么?

例如,如果[2] [3] = 1,[2] [4] = 1,[4] [3] = 1,那么我想枚举以下内容:

2-> 3

2-> 4

2-> 4-> 3

...等等。

2 个答案:

答案 0 :(得分:1)

基于来自不同答案的评论流,我提出以下算法:

  1. 使用connected components算法基于“平等”关系构造等效类。该算法涉及一个简单的深度优先(或广度优先)搜索,在该搜索中,您仅考虑头小于尾的链接。 (也就是说,如果i -> j,则仅链接i < j。)由于您可能无法保证矩阵是对称的,因此您可能想使用Pairwise[i][j] == 0 || Pairwise[j][j] == 0检查两个方向。每个组件都标有该组件中任何元素的最小索引(通常称为“代表”)。此步骤的输出是从索引到代表的映射,这是一个简单的向量。

  2. 通过将两个组件之间的所有“小于”条目折叠成组件之间的单个关系来构造简化图。

  3. 通过具有循环检测功能的深度优先扫描 在缩小图上执行transitive closure。 (DFS与topogical sort中的DFS类似。

答案 1 :(得分:0)

您的矩阵可以看作是有向图,其中元素i是元素j的直接前身(如果Pairwise[i][j] = 1)。只需运行搜索算法(很可能是深度优先搜索)来枚举所有路径。
忽略-1值,因为它们要么不构成路径,要么表示在其他地方已经具有对应的1值的“大于”关系。
如果您在总顺序中包含相等项(通过将0值视为1来计算),则路径的数量将是无限的,因此也请忽略0