【问题标题】:Reranking items without changing ranks of all items重新排列项目而不改变所有项目的排名
【发布时间】:2017-07-21 22:13:32
【问题描述】:

我有一个项目列表,每个项目都有一个与之相关的等级。

Item 1, Rank=1
Item 2, Rank=2
Item 3, Rank=3
Item 4, Rank=4
Item 5, Rank=5

我想设计一种方法来处理项目的重新排名,而对其他项目的排名变化很小或没有变化。

我想到的一个解决方案是利用小数并使用 Java 的双变量类型。因此,例如,如果我在 item2 和 item3 之间移动 item5,这将是输出 -

Item 1, Rank=1
Item 2, Rank=2
Item 5, Rank=2.5
Item 3, Rank=3
Item 4, Rank=4

等等,

Item 1, Rank=1
Item 2, Rank=2
Item 4, Rank=2.25
Item 5, Rank=2.5
Item 3, Rank=3

此解决方案有效,但在某个点之后(在同一位置移动约 55 次,我达到双变量限制,我可能不得不在该点重置所有等级)

我只是想知道是否有更好的方法来解决这个问题?

有几件事要记住。

  • 我需要将此数据结构存储在数据库(项目、排名)中,并且我将构建一个 Web 服务,该服务根据排名按排序顺序获取所有项目,因此我将进行数据库调用以对所有项目进行排序按排名字段。
  • 我将使用 Java,所以我只能处理 Java 变量。

【问题讨论】:

  • 看看github.com/mixonic/ranked-model - 我知道这是 ruby​​/rails 而不是 java,但你可以看看它们的实现并做一些笔记。他们在等级之间使用非常大的空间来实现他们能够在不改变整个等级的情况下改变事物的目标。
  • 你使用什么数据结构?一旦迭代到所需的索引,链接列表允许 O(1) 插入列表。然后您可以使用列表中项目的结构位置来指示排名。
  • 我其实也想到了那个解决方案。但话又说回来,我只是扩大我的范围,稍后我会达到极限。感谢您将我指向 github....:)
  • @4castle - 所有这些物品对象都存储在数据库中。我必须将链接存储在数据库中,以防项目必须像持久链表一样工作。您对我如何优化它有什么建议吗?
  • 好的。嗯,你能分享的信息越多,你就能得到更好的建议。

标签: java algorithm sorting ranking rank


【解决方案1】:

编写一个小程序来平均分配数组(或列表或其他)中一系列元素的排名值怎么样?

如果您在位置 x 插入一个新元素,您会将范围 x-1 .. x+1 的元素传递到子例程中。开始和结束位置的排名值保持不变,其他的以均匀距离计算。如果成功,则返回 true。现在,如果距离变得太小,则返回 false,调用者将范围扩展到 x-2 .. x+2 并再次进入子程序。

您必须小心达到数组边界,甚至完全耗尽值空间。

【讨论】:

    【解决方案2】:

    可能有多种解决方案,这是我更喜欢的一种

    我会将这个问题拆分为多个独立的问题:

    1. 在您的 java 后端中,您希望拥有以某种方式排序的项目列表,并且可以按顺序进行快速 O(1) 更改。

    最好的结构——双链表。您将需要使用 hashmap 在此列表中按项目名称/ID 快速查找对象。

    你可以很容易地将这样的结构存储到数据库中,只需在 items 表中添加两个外键。在存储期间,您必须只更新受影响的行(请记住,当您移动项目时,上一个/下一个项目也会受到影响)。它看起来像多个update table set prev=?, next=? where id=?

    1. 在您的 java 服务中,您希望尽可能快地显示排序的项目列表,可能是分页的。

    最好的结构——预排序数组。

    要将这样的结构存储在数据库中,您需要存储位置的列(排名)。当然你需要这个列的索引。

    要检索这样的结构,您将使用非常简单、快速和高效的查询,例如select item from table order by rank limit ?,?


    现在你有矛盾了,你的编辑数据结构与你的检索数据结构不匹配,任何尝试使用单一数据结构来解决这两个问题都会导致性能下降,让我们独立解决这个问题:

    1. 您将创建单独的异步服务(cron 作业),该服务将从一个表中读取数据、转换(重新计算所有项目的排名)并存储在另一个表中。

    在这里您将有两个选择:要么在计算后完全替换第二个表中的数据,要么查找差异并仅更新更改的行。我相信完全替换更容易实现,实际上它可以更快。

    因此,通过这种方法,您系统的客户可见部分表现出色(数据管理部分和数据显示部分工作得尽可能快)。

    唯一的问题是更改传播,这通常很好,大多数用户会接受它作为合理的权衡。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-06-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-04-06
      • 2016-04-13
      • 1970-01-01
      相关资源
      最近更新 更多