算法:有没有解决比较的好方法?
Posted
技术标签:
【中文标题】算法:有没有解决比较的好方法?【英文标题】:Algorithm: Is there a good way of solving a comparison? 【发布时间】:2011-01-18 15:43:45 【问题描述】:我有一组数字要比较。假设我必须从用户那里得到这个比较。我可以选择问他一个包含 2 个数字或 3 个数字的 4 个数字的问题。例如,我可以提出以下任何问题:
哪个数字更大? 2 或 4 哪个数字更大? 2 或 3 或 4 哪个数字更大? 2 或 3 或 4 或 5我的目标是尽量减少我以某种组合向用户提出的问题的数量,这最终会给我一个集合中所有数字的排序...例如,如果只有 4 个数字 2,3, 4,5,我可以问他第三类问题,我给他 4 个数字进行比较。但是在我设计的生态系统中,用户对冗长的问题感到恼火,所以我想尽量减少我会问的这类问题的数量。因此,如果每个问题都有特定的权重,我会试图找出一种方法来最终获得所有数字的排序,同时给用户带来最小的麻烦。
有没有解决这个问题的好方法?有没有人认为这属于一般问题,或者我只是让它太复杂了?有什么建议吗?
【问题讨论】:
这是作业题吗?如果是,您应该向我们展示您到目前为止所做的事情以及您遇到的问题。 Naa... 这是我正在为我的网站设计的东西。几个小时前在这里发布了一个有关游戏设计的相关问题。我可以指出:***.com/questions/2278896/… 我主要是在寻找某种游戏,我可以用它来建立声誉系统和游戏系统,并正在探索一些奇怪的想法。对不起,如果我把它当作一个家庭作业问题...... 另外我在想这是否与集团问题有关,但我想被证明是错误的......有些人建议排序,但我只是看看是否有其他方法还有…… 您是否只对长度为 4 的列表进行排序?你可以问3个数字的中位数吗?在我看来,这将比 3 个数字中最大的一个更有用。 @Justin:我只是用数字作为例子。如果我找到一个好的算法来做这件事,我最终可能会将其扩展到其他各种情况。 【参考方案1】:让我们做实验,好吗?
1.示例
让我们看看A,B,C,D
并对其进行排序。
解决方案 1:按组
A,B,C,D
中的较大者 -> B
(因此为 B>A
、B>C
和 B>D
)
A,C,D
中的较大者 -> D
(因此是 D>A
和 D>C
)
A,C
中的较大者 -> A
(因此为 A>C
)
总订单
[B,D,A,C]
解决方案 2:成对
A
和 C
之间更大 -> A
(因此为A>C
)
B
和 D
之间更大 -> B
(因此 B>D
)
D
和 A
之间的较大值 -> D
总订单
[B,D,A,C]
有什么收获?显然成对比较困难,这里我选择了它们以便合并容易(无)。
2。备注
a) 总排序
>
仅适用于总排序:即对于集合中的两个给定元素 A
和 B
,A>B
或 B>A
。如果这两个关系都不成立,那么A
和B
是等价的。
解决方案 1 方法的问题在于,如果您向用户展示 A,B,C,D
和 A
和 B
等价且大于 C
和 D
.. . 答案应该是什么?
b) 传递性
>
关系是可传递的,这意味着如果A>B
和B>C
然后A>C
。使用这一事实很重要,因为您可以推断两个元素之间的关系,而无需询问用户。
c) 目标是什么?
目标是应该尽量减少向用户提出的问题,还是应该尽量减少用户的工作?因为显然用户更难回答第一个解决方案中的问题......
3.建模
可以将问题建模为“图”问题。
您从一组节点 A,B,C,D
开始,它们代表您要测试的值。
对集合进行排序相当于计算连接这些节点的最小定向边集,以便给定任意两个节点,一条路径从一个节点通向另一个节点。我确实坚持最低限度。
例如,如果我有 2 条边:B>A
和 B>C
,那么如果我发现不是 A>C
,我将删除 B>C
,因为我可以通过传递性推断它。重要的属性是,如果没有两个节点是等价的,则生成的边集的基数是节点集的基数减去 1。在我的示例中(给定 4 个节点),它将是 3。
一个预言机(或一个非常幸运的人)因此只能提出 3 个问题,但要构建这个图表......这就是我们应该努力的目标。
4.如何解决这个问题?
好的,假设我们没有 2 个等效元素。这意味着如果A>B
为假,那么我可以推断出B>A
...
为了表示我们的小图,我们用一个数组:
A B C D
D . > . # . represent the unknown
C . >
B > # < and > have their usual meaning...
A
由于对称性,我们只需要一个三角形。
通过计算.
的数量,我们可以看到未知关系的数量,理想的解决方案是摆脱所有.
,同时向用户提出尽可能少的问题。
因此,一个好的问题是一次性删除尽可能多的.
。
5.我的问题
因此,我有另一种类型的问题:
Select the elements lower than "D" in the following A,B,C: _
这个问题比 What is the great... 感觉更好,因为我明确地针对那些我想知道的关系(D?A
、D?B
和 D?C
)而 greater 保证我将获得尽可能多的关系,但我无法提前知道哪个。
我试图最大化问题的有用性
当然,懒惰是没有余地的:在利用问题的结果时考虑传递性仍然很重要。
6.探索更大的集合
对于较大的集合,您可以对元素进行分组,然后稍后将它们合并,但合并总是一个混乱的操作:您可能会得到您已经知道的答案。但是,对于我的小问题,这是一个很好的做法:
给定 2 个有序(不相交)集合:[A,B,C,D,...]
和 [R,S,T,U,...]
,让我们看看工具箱的 3 个问题:
-
哪个更大:
A
或 R
? _
A,B,R,S
的最大元素是什么? _
R,S,T
中哪些元素大于A
? _
提供 1 个关系
提供 2 种关系:其中 3 种是已知的 提供 3 个关系第三个问题要求更详细的答案,但它更适合合并情况。在合并的情况下,它与要求对元素进行排序一样有效,因为它精确地要求我们在董事会中不知道的仅有的 3 个关系。
7.结论
现在您的框中有 4 个问题:
排序:将下列元素从大到小排序 A,B,C,D ? _ Pivot:在这个集合 B,C,D 中哪些元素大于 A? _ 更大:在这个集合 A,B,C,D 中哪个元素更大? _ Pair:A 和 B 中哪个元素更大? _(Pair可以看作是Greater或Pivot的退化情况)
鉴于每个问题都为n
节点提供n-1
关系,您可以尝试衡量用户回答问题T(n)
所需的时间,然后找到最大化T(n)/n
的n
;)
【讨论】:
当问题很有趣时... :)【参考方案2】:如果您对数组进行排序,那么您通常在 O(n log(n)) 时间内进行排序。这意味着您有时会多次比较成对的数字。如果您不断提出 4 个问题,那么您将获得可以存储的额外信息。
当你在排序中找到一个点时,你问 a>b,那么你不妨问是 b,c,d,e,... 中最大的一个。这样您就不必询问 a>c、a>d 等。如果您将这些已知的比较存储在一个表中,那么您就不必再做这些了。至于确切地选择 caparison 设置来询问用户的问题,我不确定,这当然是一个很好的问题。
对于向用户提出问题的问题,我的直觉是查看快速排序的工作原理。它将数据分成两部分,并且永远不会比较不在同一组中的数字,这样您就知道不应该将什么放入集合中询问用户。尽可能长地使用 4 个数字,直到快速排序进入少于 4 个数字的组。
【讨论】:
一个很好的解释......谢谢你......在你第二段的相关说明中,我唯一的想法是,如果你在算法中达到了你'已经使用了许多大小为 4 的问题来构建不同的集合,并且正处于您现在需要合并它们的阶段,如何选择大小?知道这会很有趣,因为并非所有问题都具有相同的权重...正如您所建议的,我将更详细地进行快速排序..但是如果您有更多的 cmets,我将不胜感激...跨度> @Legend:对不起,我不明白你的评论,但这里已经很晚了。如果你澄清我明天可以检查。即:什么是“您已经使用了许多大小为 4 的问题来构建不同的集合,并且正处于您现在需要合并它们的阶段,如何选择大小?”什么大小?我的意思是正常执行该算法,但始终检查和更新表格并使用智能问题集。我只以快速排序为例, 哦,我明白了……明白了……你明天有时间就可以回答这个问题……只是一个小小的想法是复杂性是 O(nlog n)。如果 n 很大,那么我相信我最终会惹恼用户。我可能已经准备好为了加快速度而牺牲一些准确性......我目前正在谷歌搜索,但我想知道是否有任何概率方法可以在小于 O(nlog n) 的时间内做到这一点【参考方案3】:你可以做一个合并排序或快速排序算法,其中比较函数询问用户问题的两个数字版本,然后他们必须回答的最多问题是 n log n。
那么问题就是,能够提出 3 或 4 中最大的问题是否会减少您必须提出的问题的数量。我的直觉说不,但我很难证明这一点。
【讨论】:
【参考方案4】:您可以通过quicksort或mergesort的算法提出问题。尽量减少比较次数,保证结果正确。
【讨论】:
-1:但是当您尝试利用您可以一次询问用户 4 个比较的事实时,您会选择哪些元素? 不要一次进行 4 次比较。通过进行这样的比较(例如 2,3,4,5),您只知道 5 大于 2、3 和 4,但没有获得排序信息。每个问题只比较两个。编辑:只需阅读您的答案。好主意。 通过询问谁是最伟大的 1,2,3,4,5 你知道 5>4, 5>3, 5>2, 5>1....这不仅仅是信息一。以上是关于算法:有没有解决比较的好方法?的主要内容,如果未能解决你的问题,请参考以下文章
6-22——“ == ”不能用来比较两个字符串是否相等,解决方法——折半查找算法找素数的简单算法
6-22——“ == ”不能用来比较两个字符串是否相等,解决方法——折半查找算法找素数的简单算法