如何计算将一种排序顺序转换为另一种排序顺序的绝对最小更改量?

2023-12-31

Goal

如何使用尽可能少的数据对描述如何将静态列表从一个顺序重新排序到另一个顺序的数据进行编码?

我有一种感觉,有一种算法或计算机科学术语可以帮助我,但现在我太专注于这个问题,无法找出其他看待它的方法。

背景动机

我有一个程序部署到一个远程位置,所有通信都是通过间歇性的极其昂贵的卫星连接进行的。这有点夸张,但数据成本接近每千字节一美元,而且每天只能发生几次。

在一天开始时,用户会收到一个项目列表,他们到现场做一些事情,但最终结果或多或少是按不同顺序排序的相同项目列表。还有其他数据,但对这个问题来说并不重要。

现在我正在发回所有发生的动作的记录并按顺序回放它们。随着用户对系统的熟悉,移动记录列表的大小开始接近仅发回所有项目本身的大小,并且通常某些移动组合会导致撤消以前的记录。

假设

  • 起始列表和结束列表由完全相同的一组项目组成
  • 每个项目都有一个唯一的 id(32 位整数)
  • 每个项目都有一个唯一的排序顺序(32 位整数)
  • 用户将拥有数百到一千甚至更多项目的列表
  • 用户通常会在一天内重新订购其中大约 100 件商品
  • 可以检测到顺序的更改,将项目移动到列表中的新位置
  • 有些“举动”可能会撤销之前的举动
  • 用于找出最佳解决方案的计算资源很便宜/不受限制
  • 传输时间昂贵
  • 发回更改数据比发回整个列表更便宜

最简单的数据结构

为了解决这个问题,假设以下数据结构可用。

  • ListItem
    • item_id
    • 排序
  • MoveRecord
    • 项目 ID
    • 新职位

这是一个示例列表。每个列表中的项目都是相同的。请注意,尽管只有少数项目发生了更改,但每个项目 id 都有一个新的排序顺序,因此您不能只发回新的 item_id/sort_order_id 对。

**List 1: Original List**    **List 2: Re-ordered List**    
order - id                    order - id
     1. 10                         1. 90
     2. 20                         2. 30
     3. 30                         3. 40
     4. 40                         4. 50
     5. 50                         5. 60
     6. 60                         6. 10
     7. 70                         7. 80
     8. 80                         8. 70
     9. 90                         9. 20

如何使用尽可能少的数据量对将列表 1 的顺序转换为列表 2 的顺序所需的更改进行编码?

出于好奇,有可能prove那有一个解决方案是最优的吗?

Update

一位同事指出,“交换”可能不是正确的理解方式。您还可以将项目发送到列表的顶部或底部,这更像是移动而不是交换。然后交换就变成了两个动作的组合。

感谢您的指点。到目前为止,我还没有看到有保证的最佳解决方案。而且问题只是发生了一点变化。

如果我无法证明任何一种方法都能产生最佳结果,那么我将使用每种方法找出一个解决方案,并将该解决方案发回,并用一个小标头指示所使用的方法。不过,请继续提出解决方案,我将用我的研究更新这个问题。

感谢大家!


算法部分:

列表的重新排序称为排列。每个排列可以分成一组循环 http://en.wikipedia.org/wiki/Permutation#Permutations_in_group_theory,每个 N 个元素的循环需要 (N - 1) 次交换。例如

1, 2, 3, 4, 5, 6 --> 3, 2, 4, 1, 6, 5

这可以分为 1 - 4 - 3(需要 2 次交换) 2 - 2(0 次交换) 5 - 6(1 次交换)

要找到解决方案,您只需选择错误位置的任何元素并将其放在原来的位置即可。

详情部分:

当然,你可以使用更小的数据类型、RLE或者一些其他的编码算法等等。

非常理论但非实践的部分。

N 个数字序列的所有排列可以按字典顺序排序 http://en.wikipedia.org/wiki/Permutation#Numbering_permutations,并且从 0 到 (N! - 1) 的一个数字足以表示该序列。因此,理论上最好的答案是:计算排列的索引,传输它,通过该索引重新创建排列。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何计算将一种排序顺序转换为另一种排序顺序的绝对最小更改量? 的相关文章

  • 如何从一组重叠的圆计算多边形集?

    这个问题是一些计算细节的扩展这个问题 https stackoverflow com questions 1667310 combined area of overlapping circles 假设有一组 可能重叠的 圆 并且希望计算这组
  • 删除队列中的最后一个元素

    我需要删除队列的最后一个元素 我唯一可以使用的操作是 Peek 获取第一个元素而不删除它 Enqueue element 向队列末尾插入一个元素 Dequeue 删除第一个元素 IsEmpty true 或 false 队列是否为空 而且我
  • 一起使用“过滤”和“排序”的 Google 表格

    这是我的第一个问题 我希望一切都好 我是使用谷歌表格的新手 但我正在慢慢进步 我正在尝试构建一个工作表 其中包含工作表 1 中的所有数据 在工作表 2 上 我想过滤工作表 2 中 D 列中标有数字 1 的所有数据 为此 我正在使用 FILT
  • C - 对浮点数组进行排序,同时跟踪索引

    我有一个包含 3 个浮点值的数组 float norms 3 norms 0 0 4 norms 1 3 2 norms 2 1 7 我想按降序对这个数组进行排序同时跟踪数组中值的原始索引 换句话说 给定数组norms 0 4 3 2 1
  • Java中如何对对象数组进行排序?

    我的数组不包含任何字符串 但它包含对象引用 每个对象引用都通过 toString 方法返回名称 id 作者和发布者 public String toString return name n id n author n publisher n
  • 找到一系列间隔的最有效分组

    我有一个应用程序 其中有一系列不重叠的固定宽度间隔 每个间隔都有一个给定的键 每个间隔具有相同的宽度 并且可以存在连续的间隔 本质上 我想以最小化单独间隔的数量的方式对间隔和键进行分组 这可以通过合并具有相同键的连续间隔或查找匹配间隔并将它
  • 点集子集的最小周长凸包

    给定平面上的 n 个点 没有 3 个共线 给定数字 k 找到 k 个点的子集 使得 k 个点的凸包在 k 个点的子集的任何凸包中具有最小周长 我可以想到一个简单的方法 运行时间为 O n k k log k 找到大小为 k 的每个子集的凸包
  • 时间复杂度和运行时间有什么区别?

    时间复杂度和运行时间有什么区别 它们是一样的吗 运行时间是指程序运行所需的时间 时间复杂度是对输入大小趋于无穷大时运行时间渐进行为的描述 您可以说运行时间 是 O n 2 或其他什么 因为这是描述复杂性类和大 O 表示法的惯用方式 事实上
  • 将字符串中的“奇怪”字符转换为罗马字符

    我需要能够将用户输入仅转换为 a z 罗马字符 不区分大小写 所以 我感兴趣的角色只有26个 然而 用户可以输入他们想要的任何 形式 的字符 西班牙语 n 法语 e 和德语 u 都可以包含用户输入中的重音符号 这些重音符号会被程序删除 我已
  • 如何按某些属性对对象列表进行排序

    我有简单的课 public class ActiveAlarm public long timeStarted public long timeEnded private String name private String descrip
  • 用 C++ 生成 AST

    我正在用 C 制作一个解释器 到目前为止我已经有了词法分析器来生成标记 问题是我不确定如何生成 行走 解析树 我正在考虑使用数组数组来制作解析树 但我不确定如何以正确的顺序将标记实际插入到解析树中 我不确定是自上而下 左右还是自下而上 左右
  • 在常数空间中创建 1..N 的随机排列

    我正在寻找枚举固定空间中数字 1 N 的随机排列 这意味着我无法将所有数字存储在列表中 原因是 N 可能非常大 超过可用内存 我仍然希望能够一次遍历这样一个数字的排列 只访问每个数字一次 我知道对于某些 N 可以这样做 许多随机数生成器随机
  • Woocommerce,基于短代码的产品列表上的排序下拉列表

    在我们的商店里 我们有许多标准的 WP 页面 在这些页面上 我们使用标准 Woocommerce 短代码展示了约 40 种产品 例如 product category category boots per page 20 columns 4
  • 在应用程序创建完成时设置 Spark DataGrid 列的默认排序(Flex 4.5)

    我有一个包含多个列的 Spark DataGrid 组件 我希望我的应用程序默认按 DataGrid 中第一列的降序排列 我想使用单击顶部标题一次时发生的内置默认排序 我不需要对我正在使用的 ArrayCollection 进行排序或更改比
  • 计算两点之间的最短路线

    过去几周我一直在开发一款多人 HTML5 游戏 使用nodejs and websockets 我已经被这个问题困扰了一段时间 想象一下 我用数组实现了这个平铺地图 如下所示 1 or 棕色瓷砖 路上有障碍物 玩家无法通过 0 or 绿色瓷
  • VBScript:从 Scripting.Dictionary 中对项目进行排序

    我有下面的代码 它获取这样的数据 姓名 1 姓名 4 姓名 2 姓名 3 并像这样列出 是一个复选框 姓名 1 姓名 4 姓名 2 姓名 3
  • shell脚本中关联数组的时间复杂度

    我想知道在 shell 脚本中使用关联数组时如何构造 实现 另外 我想知道基于 shell 脚本的关联数组的时间复杂度是否是最佳的 因为我们可以使用字母和数字作为它们各自的键 编辑 他们使用什么哈希函数 如果您使用关联数组 则不能通过 使用
  • 找到一条穿过任意节点序列的最短路径?

    In 这个先前的问题 https stackoverflow com questions 7314333 find shortest path from vertex u to v passing through a vertex wOP询
  • 负整数的基数排序

    我正在尝试对整数 包括负整数 实现基数排序 对于非负整数 我计划为数字0 9创建一个10个队列的队列 并实现LSD算法 但我对负整数有点困惑 我现在的想法是继续为它们创建另一个包含 10 个队列的队列 并分别对它们进行排序 然后在最后 我将
  • 如何在Python中按AaB而不是ABa顺序对字符串进行排序

    我正在尝试对字符串进行排序 为 punnetsquare 制作基因型 我目前的实现是 unsorted genotype ABaB sorted genotype sorted list unsorted genotype sorted s

随机推荐