对数字进行排序的算法


14

我已经在stackoverflow上问过这个问题,但也许它更适合此站点。

问题是:

我有N对无符号整数。我需要对它们进行排序。成对的结束向量应按每对中的第一个数字递增地排序,而按对中的第二个按递增顺序排序。每对可以随时交换第一和第二元素。有时没有解决方案,因此我需要抛出一个异常。

例:

in pairs:
1 5
7 1
3 8
5 6

out pairs:
1 7     <-- swapped
1 5     
6 5     <-- swapped
8 3     <-- swapped

^^如果不交换对,就不可能构建解决方案。因此,我们交换对(7,1),(3,8)和(5,6)并构建结果。要么

in pairs:
1 5
6 9

out:
not possible

谢谢

编辑:

Tom Sirgedas在SO上提出了最佳解决方案。它真的很容易实现,并且可以在O(log(n)* n)中工作。谢谢大家的回答和关注。我真的很喜欢mjqxxxx分析。


6
有趣的问题。没有交换就很简单,但是有了交换就不清楚是否存在唯一的解决方案。
戴夫·克拉克

2
独特的解决方案并不总是存在的。即(1,10),(5,6)。(1,10),(5,6)和(1,10),(6,5)都是正确的。
克拉克

4
下次请提供链接。 stackoverflow.com/questions/5323941/...
刚伊藤

2
我的一个朋友把它当作纸笔试面试问题。所以我想这只是出于好奇:)
克拉克

3
(1)克拉克,谢谢您的答复。(2)我不认为这个问题是研究水平的问题,但是我想这是应该改变的范围。我开始讨论meta
伊藤刚(Tsuyoshi Ito)

Answers:


8

假设两对p 2 = a 2b 2是非交换兼容的,如果它们可以在排序列表中以任何顺序放置而不交换任何一个。这是真实的,如果任一一个1一个2b 1b 2一个2一个1b 2bp1=(a1,b1)p2=(a2,b2)(a1a2b1b2)。注意, p 1 p 2是无插拔如果兼容且仅当它们是双交换兼容(由于偏序定义满足 p 1p 2p * 2p * 1,其中 *表示交换操作) 。最后,如果 p 1 p 2可以按交换顺序放在排序列表中的任何一个位置,并且恰好交换其中一个,则它们是单交换兼容的。如果 p 1(a2a1b2b1)p1p2p1p2p2p1p1p2p1根本不兼容:无论交换状态如何,它们都不能满足订购条件。p2是无交换兼容的。在其余情况下,p 2p1p2

现在可以如下解决该问题。测试每一对。如果任何一对都不兼容,则没有解决方案,我们可以抛出异常。否则,考虑与这些对那些节点之间对应于原始对节点和边的曲线不是一个交换兼容。在任何适当排序的列表中,每对这样的节点对必须具有相同的交换状态,因此,图的每个连接组件中的所有节点都必须具有相同的交换状态。我们需要确定是否可以一致地分配这些组件范围的交换状态。测试每个连接的组件内的所有节点对。如果任何一对都不兼容,则没有解决方案,我们可以抛出异常。现在测试所有成对的已连接组件(即,对于组件C1,测试所有节点对p 1Ç 1p 2Ç 2)。我们知道每对组件至少是一次交换兼容的,但是有些组件对也可能是非交换兼容的(因为未通过边缘连接的每对节点至少是一次交换兼容的,而且也可能是不交换的)交换兼容)。考虑具有对应于所连接组件的节点的简化图,如果对应组件兼容,则考虑两个节点之间的边。当且仅当此图为2色时,才可以解决原始问题。如果没有2C2p1C1p2C222-着色,没有解决方案,我们可以抛出异常。如果有一个,则交换单一颜色所有组件中的所有节点。现在,我们保证了任何两个节点都是无交换兼容的,因此我们可以使用定义的部分顺序对对列表进行正确排序。

算法中的每个步骤以及整个算法都可以在时间内执行。O(N2)


更新:以下是一个更为优雅的构造。如果一对线对不兼容,则将相应的节点与边缘连接(在任何2色中强制它们为不同的颜色)。如果一对对不兼容,则用长度为2的链连接相应的节点(强制它们在任何2色中为相同颜色)。当且仅当结果图为2色时,才有解决方案。要从图的蓝红色构造一个解决方案,请仅交换其对应节点为蓝色的那些对,然后对结果列表进行排序。


1
非常感谢您的回答。我真的很喜欢阅读它。检查关于SO的建议答案。尽管它不依赖于图论,这意味着它不如优雅的解决方案那么有趣:),但速度更快。感谢您的时间。
克拉克

3

令X(a,b)表示二进制变量,该变量指示对(a,b)是否应该交换。考虑任意一对不同的对(a,b)和(c,d),并且对变量X(a,b)和X(c,d)写一个二元约束条件,当且仅当这两对在分别执行X(a,b)和X(c,d)指示的互换后的正确顺序。所有这些二元约束的结合是n个变量和O(n ^ 2)子句中的2-SAT公式,当且仅当原始问题具有解时才可满足。可以在时间O(n ^ 2)中检查。


对于原始解决方案,只需注意所有约束的形式为X(a,b)= X(c,d)或X(a,b)!= X(c,d)(否则X(a, b)=常数),因此可以使用简单的“合并并检查二分性”算法:

从每个X代表仅包含自身的集合开始;然后对于每对(X,Y),使X = Y为约束,合并X和Y所属的分量;最后检查如果关系X!= Y必须成立,则每个分量为一个顶点,且某些边将包含X和Y的分量连接起来的收缩图是否为二分图。


1
X(a,b)=X(c,d)

所以?此处的等价关系是(a,b)R(c,d)如果a <c和b> d的关系的传递闭合,反之亦然。也许我不是很明确,但是从我的回答中应该可以明显看出。
大卫

1
a<cb>dX(a,b)X(c,d)(1,10)(2,5)(3,7)

1
XYX¬Y

1
你在开玩笑吗?首先,仅两个变量之间的任何关系都可以表示为2-SAT公式。例如,X = Y与(X表示Y)和(不是X表示不是Y)相同。另一方面,如果所有约束确实都是X = Y或X =不是Y的形式,则根本不需要运行2SAT算法:我先前描述的更简单的“合并并检查二分性”算法是可行的。
大卫
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.