【问题标题】:Quick relative ranking algorithm快速相对排名算法
【发布时间】:2013-07-15 04:58:18
【问题描述】:

假设我拥有 100 个视频游戏,我想将它们从最喜欢到最不喜欢的顺序排列。很难给每个视频游戏一个代表我有多喜欢它的数值,所以我想把它们相互比较。

我想出的一个解决方案是随机选择 2 个视频游戏,然后选择我更喜欢的一个,然后丢弃另一个。不幸的是,这个解决方案只让我知道排名第一的视频游戏,因为那将是最后一个,并且几乎没有提供关于其他游戏的信息。然后我可以对其他 99 个视频游戏重复这个过程,等等,但这是非常不切实际的:O(n^2)。

是否有任何 O(n)(或只是合理的)算法可用于根据相关标准对数据进行排序?

【问题讨论】:

  • 嗯,您需要以某种方式为每个游戏分配一个值,以显示您对它的使用程度。
  • 由于绝对值是“不准确的”,也许有一种折中的方法:以某种方式同时使用绝对排名和相对排名。
  • 你真的有必要有一个确切的订单吗?为什么不把它们放在五个桶里(讨厌的、不喜欢的、矛盾的、喜欢的、喜欢的)?或者您是否使用此示例作为其他排名问题的代理?
  • 确实不需要确切的顺序,因此存储桶建议可以很好地工作。谢谢。
  • 我怀疑你甚至不能同意你自己的独特排名(我认为我不能为我自己的游戏、电影或你拥有的东西这样做);您对游戏的偏好可能无法传递,因此如果您在这三者之间有几对,那么您很可能会陷入 a > b、b > c、a

标签: algorithm ranking


【解决方案1】:

我知道很难量化你喜欢某样东西的程度,但是如果你创建了几个“领域”来评判每款游戏呢:

graphics
story
multiplayer
etc...

为每个类别打出 5 分中的每 1-5 分(更改您认为更重要的类别的权重)。尝试创建一个客观的评判标准(可能使用外部资源,例如 metacritic)

然后您将它们全部加起来,从而得出您喜欢它们的总体评分。然后使用排序算法(MergeSort?InsertionSort?)将它们按顺序排列。那将是O(n*m+nlogn) [n = games, m = categories],考虑到 m 可能非常小,这非常好。

如果你真的下定决心,你可以使用机器学习根据你过去的选择来估计未来的游戏。

【讨论】:

    【解决方案2】:

    另一种方法是扩展您的想法。显示超过 2 个游戏并按您的评分对其进行排序。这个想法类似于merge sort 来评价你的游戏。如果您正确选择游戏进行评级,您将不需要进行大量迭代。只是一点点。 IMO O(n) 将非常困难,因为您(作为人类)的观察是有限的。

    【讨论】:

      【解决方案3】:

      至于是否有O(n) 对n 个对象进行排序的方法,没有。这种排序的下限是O(nlogn)

      但是,有一种特殊情况。如果您有一个独特且有限的偏好,那么您可以执行所谓的桶排序。

      如果没有两场比赛打成平手,则偏好是唯一的。 如果您的偏好有最小值和最大值,则偏好是有界的。

      1 .. m 成为您游戏集的界限。

      只需创建一个包含m 元素的数组,然后根据您的喜好将每个游戏放入索引中。

      现在您可以对数组进行线性扫描以获取您的排序顺序。

      当然,这不是基于比较的。

      【讨论】:

        【解决方案4】:

        您可以使用快速排序又名枢轴排序。选择一个游戏,然后将所有其他游戏与它进行比较,这样你就有了一组更糟糕的游戏和更好的游戏。递归地重复每一半。平均案例性能为 n log n。

        http://en.wikipedia.org/wiki/Quicksort

        【讨论】:

        • 当然!我不知道为什么这对我来说不是一个简单的排序问题。我最初的解决方案类似于冒泡排序。我最终将算法实现为快速排序,其中比较功能提示用户在 2 个游戏之间进行选择。
        【解决方案5】:

        首先,您可以保留一个列表并使用二分搜索逐个插入每个元素,从而为您提供O(n log n) 方法。

        我也确定你无法击败O(n log n),除非我误解了你想要的。基本上,您告诉我的是您希望能够仅使用比较对某些元素(在您的示例中为视频游戏)进行排序。

        把你的算法想象成这样:你从n!可能的方式来安排你的游戏,每次你进行比较时,你把安排分成POSSIBLEIMPOSSIBLE,丢弃后一组。 (这里的POSSIBLE表示排列与您所做的比较一致)

        在最坏的情况下,POSSIBLE 组始终至少与IMPOSSIBLE 组一样大。在这种情况下,您的任何比较都不会将搜索空间减少至少 2 倍,这意味着您至少需要 log_2(n!) = O(n log n) 比较才能将空间减少到 1,从而为您提供游戏排序。

        【讨论】:

          【解决方案6】:

          一种可能性是创建多个标准C1, C2, ..., Cn,例如:

          • 视频质量
          • 难度
          • 场景兴趣
          • ...

          您通过这个筛子通过每个游戏。

          然后您比较游戏对的子集(2 级选择),并告诉您更喜欢哪一个。存在一些多标准决策/分析(MCDM 或 MCDA)算法,可以将您的 2 排名选择转换为多标准排名函数,例如可以计算系数 a1,...,构建一个线性排名函数a1*C1+a2*C2+...+an*Cn

          好的算法不会让你随机选择对,而是会根据非支配子集向你推荐要比较的对。

          请参阅 wikipedia http://en.wikipedia.org/wiki/Multi-criteria_decision_analysis,它提供了一些有用的链接,并准备好做/阅读一些数学。

          或者购买像 ModeFrontier 这样嵌入了其中一些算法的软件(如果只是为了对库进行排名,那就有点贵了)。

          【讨论】:

            【解决方案7】:

            如果你想按顺序展示游戏,你需要决定它。

            可以从一组成对比较中导出顺序。

            这是一个例子。你有 100 个视频游戏。我们假设每个视频游戏都与一个参数 ai 相关联(其中 i 的范围从 1 到 100)。这是一个实数,描述了您对游戏的“喜欢程度”。 我们还不知道这些参数的值。 然后,我们选择一个函数来描述您在参数方面更喜欢视频游戏 i 而不是视频游戏 j 的可能性。我们选择逻辑曲线并定义

            P[i 优先于 j] = 1/(1+eaj - ai)

            现在当 ai = aj 你有 P = 0.5,当 ai = 1 和 aj = 0 你有 P = 1/(1 + e-1) = 0.73,表明相对较高的参数值会增加相应视频游戏被首选的概率。

            现在,当您在表格中获得实际比较结果时,您可以使用maximum likelihood 的方法来计算参数ai 的实际值。然后按计算参数的降序对视频游戏进行排序。

            发生的情况是最大似然法计算参数 ai 的那些值,使实际观察到的偏好尽可能地接近,因此计算出的参数代表最佳猜测 em> 关于视频游戏之间的总排序。请注意,为此,您需要将视频游戏与其他视频游戏进行足够多次比较——每个游戏都需要至少一次比较,并且比较不能形成不相交的子集(例如,您将 A 与 B 与 C 与 A 进行比较,和 D 到 E 到 F 到 D,但是 {A,B,C} 的游戏和 {D,E,F} 的游戏之间没有可比性。

            【讨论】:

              【解决方案8】:

              我不认为它可以在 O(n) 时间内完成。我们能得到的最好结果是使用合并或快速排序的 O(nlogn)。

              【讨论】:

                【解决方案9】:

                我的方法是使用一个包含游戏标题和计数槽的数组。

                Object[][] Games = new Object[100][2];
                Games[0][0] = "Game Title1";
                Games[0][1] = 2;
                Games[1][0] = "Game Title2";
                Games[1][1] = 1;
                

                每次您投票时,它都应该在Games[*][1] 插槽中添加一个,然后您可以根据该位置进行排序。

                【讨论】:

                  【解决方案10】:

                  虽然不是 O(n),但成对比较是一种对集合中的元素进行相对排名的方法。

                  实现算法:

                  1. 创建一个 100x100 矩阵
                  2. 每一行代表一部电影,每一列代表一部电影。 r1 处的电影与 c1 处的电影相同,r2=c2...r100=c100。

                  这里有一些快速的伪代码来描述算法:

                  
                      for each row
                          for each column
                              if row is better than column
                                  row.score++
                              else 
                                  column.score++
                              end
                          end
                      movie_rating = movie[row] + movie[column]
                      sort_by_movie_rating()
                  

                  【讨论】:

                    猜你喜欢
                    • 1970-01-01
                    • 2016-11-24
                    • 2018-05-17
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 2017-01-14
                    • 2021-09-21
                    • 1970-01-01
                    相关资源
                    最近更新 更多