从根本上说,排序需要linear order。
你需要你的关系是一个线性顺序,这意味着:
- a ≤ a(自反性)
- 如果 a ≤ b 且 b ≤ a 则 a = b(反对称)
- 如果 a ≤ b 且 b ≤ c 则 a ≤ c(传递性)
- 对于所有 a 和 b,a ≤ b 或 b ≤ a(总数)
那么,这是什么意思?最常见的关系是线性的。例如,如果您正在谈论实际上是实数的成绩,那么是的,成绩可以线性排序。排名也是如此,因为它们再次只是实数。
但是,例如,如果您对棋手进行排名,则不能使用他们的比赛历史。如果玩家 A 在他们的大部分比赛中击败了玩家 B,并且 B 在他们的大部分比赛中再次击败了 C,这并不意味着 A > B > C,仅仅因为 C 可能在他们的大部分比赛中击败了 A匹配。
这也是Elo ratings 存在的原因之一,他们需要一个线性顺序来排序谁是最好的玩家,并注意 Elo 基本上只是一个实数,因此具有线性顺序。
因此,对于考试评分,您根本没有那种线性顺序。为什么?是实数!嗯,没错,你有这个线性顺序,但你不能问这个线性顺序一切,你被限制在预定义的比较列表中,这里是:
- 约翰比简做得更好
- 简比卢克做得更糟
- 卢克比杰森做得更好
- Jason 做得比 Tim 还差
所以,答案是:不,一般来说,如果没有任何一对元素之间的比较,就无法对列表进行排序。
现在,我正在研究一个“最不坏”的答案,但这对我来说并不是微不足道的......
编辑:好的,我想出了一些东西。这个想法是您将在预定义的比较列表中提取最可能的信息。然后将不在扩展比较列表中的任何比较视为相等。
那么,你是怎么做到的呢?
首先,对于任何 a a。然后,您将查看预定义的比较列表以查找任何比较 a a。如果你知道没有平等(没有学生的成绩相同),那就完了。否则,您必须添加所有自反性和反对称关系。你不能对整体性做任何事情。现在,您有了扩展比较列表。
现在,采用您最喜欢的排序算法。如果您没有,quicksort 写起来很好、高效且简短。然后,每当算法要求比较 a 和 b 时,请查看您的扩展比较列表。如果比较在这里,很好,否则,将比较视为 a=b。 (注意,知道不存在等式也没关系,算法不关心)
结果将是一个“最差”的排序列表。通常有几个可能的“最差”排序列表,但这个算法只会给你一个。
那么,让我们举个例子。它与 OP 中给出的几乎相同,略有不同(“约翰比卢克做得更糟”而不是“简比卢克做得更糟”)。所以,我们从:
- 约翰比简做得更好
- 约翰比卢克做得更糟
- 卢克比杰森做得更好
- Jason 做得比 Tim 还差
现在,对于每个“X 比 Y 差”,我添加“Y 比 X 好”,反之亦然。新句子以粗体显示:
- 约翰比简做得更好
-
卢克比约翰做得更好
- 卢克比杰森做得更好
-
蒂姆比杰森做得更好
- 简的表现比约翰差
- 约翰比卢克做得更糟
- 杰森比卢克做得更糟
- Jason 做得比 Tim 还差
最后,我扫描了所有可能的句子“X has done better than Y”和“Y has done better than Z”,并加上“X has done better than Z”
- 约翰比简做得更好
- 卢克比约翰做得更好
- 卢克比杰森做得更好
- 蒂姆比杰森做得更好
- 卢克比简做得更好
- 简的表现比约翰差
- 约翰比卢克做得更糟
- 杰森比卢克做得更糟
- Jason 做得比 Tim 还差
- 简比卢克做得更糟
扩展表已完成。
现在让我们看一下快速排序的伪代码:
function quicksort('array')
if length('array') ≤ 1
return 'array' // an array of zero or one elements is already sorted
select and remove a pivot value 'pivot' from 'array'
create empty lists 'less' and 'greater'
for each 'x' in 'array'
if 'x' ≤ 'pivot' then append 'x' to 'less'
else append 'x' to 'greater'
return concatenate(quicksort('less'), 'pivot', quicksort('greater'))
与标准快速排序的唯一区别在于您通常无法知道问题if('x' ≤ 'pivot') ... 的答案。因此,相反,如果x=Luke 和pivot = Tim,您在表中查找“Luke has done than Tim”这句话。如果你找到它,那么你认为答案是true 并做append 'x' to 'less'。如果您在表中找到“Luke 比 Tim 做得更好”,那么您认为答案是错误的,您会选择 append 'x' to 'greater'。最后,如果你找不到上面提到的两个句子中的任何一个,你就像'x' == 'pivot',你做append 'x' to 'less'