用于人类比较的列表排序算法

时间:2015-12-07 22:04:33

标签: algorithm sorting

此问题曾被问过一次,但没有回答,所以我想我会再次询问我的具体情况。

我正在尝试开发一个应用程序,允许您放入一个离散项目列表(对于此示例,水果),它提供了两者之间的比较。你选择你最喜欢的两个,然后重复这个过程,直到你最终有一个按这些对象的优先顺序排列的列表(在这个例子中,按顺序列出你最喜欢的水果)。

问题在于,传统的排序策略,无论多快,都必然会涉及比人类在任何合理的时间内做的更多的操作(即使是一个短至50的列表,就像我目前的那样)测试清单是)。

由于显然没有一个保证排序算法的复杂度足够低,我想有些限制必须要做。有没有办法跳过大块的排序?我考虑了一些根据他们赢得的比较次数为项目分配价值的方法。然后在一段时间后停止排序并假设这些值给出了正确的顺序,类似于你可能解决瑞士国际象棋锦标赛的风格,如果你不能完成足够的轮次来正常确定胜利者。我不知道这是否合情合理。

澄清我的意思的一个例子: 说你有一个

列表
Apple
Orange
Kiwi
Banana
Melon

它会为你提供比较

Do you prefer:
A Apple
B Kiwi

依此类推,直到你有一个类似于

的列表
Kiwi
Apple
Orange
Melon
Banana

这是你对这些水果的偏好顺序。

3 个答案:

答案 0 :(得分:4)

您的水果偏好是什么?你有一个完整的有序偏好列表,或者你有水果吗?比大多数人更喜欢,"水果你"喜欢少于大多数,"你不会有任何强烈感受的其余部分 - 或者你甚至没有尝试过。

您如何制定问题的一个问题是,您假设一个人的偏好是total order,它自然地编码为一个列表。实际上,一个人的偏好通常是partial order,其自然编码为directed acyclic graph

例如,对于水果集{Apple, Orange, Kiwi, Banana, Melon, Starfruit},我可能会有以下水果首选项:

Melon < Apple
Apple < Banana
Banana < Kiwi
Banana < Orange

根据用户输入得出部分订单的好方法是模仿radix sort。首先,要求用户为每种水果选择他们是否喜欢它,不喜欢它,对它感到中立,或者不知道。我会回答如下:

            Like Dislike Neutral Unknown
Apple                    x
Orange      x
Kiwi        x
Banana      x
Melon            x
Starfruit                        x

假设Dislike < Neutral < Like,这些答案会对以下信息进行编码,即使我只回答了与果实一样多的问题:

Melon < Apple
Apple < Orange
Apple < Kiwi
Apple < Banana

接下来,确定哪些答案获得了最多的复选标记。在这种情况下,我似乎有3种我喜欢的水果,1我不喜欢,1我感到中立(除非涉及花生酱),1我从未尝试过(所以我没有对其他水果的偏好。)

因此,进一步调查我的偏好的自然地方将在我喜欢的成果之内。问题是递归的:现在你想在水果集{Orange, Kiwi, Banana}中确定我的偏好。您可以问我哪些水果是我的最爱,我点击OrangeKiwi。这告诉你以下内容:

Banana < Orange
Banana < Kiwi

结合第一轮信息,您现在拥有:

Melon < Apple
Apple < Orange
Apple < Kiwi
Apple < Banana
Banana < Kiwi
Banana < Orange

Apple < BananaBanana < Kiwi暗示Apple < Kiwi; Apple < BananaBanana < Orange暗示Apple < Orange。因此,我们可以消除冗余信息,以达到以下目的:

Melon < Apple
Apple < Banana
Banana < Kiwi
Banana < Orange

答案 1 :(得分:3)

您可以让用户不仅给出一个项目是否比另一个项目更优先,而且还给出1到10的评级,例如他更喜欢另一个项目的评分。这样您就可以获得更多信息并轻松创建排名。

在用户只能说更小或更大的最佳方法中,您需要对列表中的每个项目执行二进制搜索。二进制搜索具有复杂性O(log n)n n次从{1}到n执行O(n * log (n/2))function iterate(spec, options, callback) { if (spec instanceof Array) { return PromiseA; } else if (type(spec) === "[object String]") { return PromiseB; } }; 。如果有50个项目需要超过200步。

答案 2 :(得分:2)

使用insertion sort。不要让用户一次比较两个项目,而是要求他们从剩余的整个列表中选择他们喜欢的项目。将该项目放在已排序列表的末尾,将其从剩余项目中删除,然后重复,直到其余项目用完为止。