【问题标题】:Restore the original order based on many incomplete ordered sets基于许多不完全有序集合恢复原始顺序
【发布时间】:2015-04-25 19:43:40
【问题描述】:

假设我的原始数据是

1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12

它被损坏了,我只有一些 不完整的集合,其中的顺序有效但并非所有元素都存在。

1, 4, 6, 7, 8, 11, 12
1, 2, 4, 5, 6, 9, 10, 12
2, 4, 7, 9, 10, 11
4, 7, 9, 12

等等

我也有所有原始元素的列表,没有任何顺序。

我需要尽可能多地恢复原始数据。我不能保证我有足够的信息来恢复一切。我需要充分了解我所拥有的东西,并弄清楚哪些部分是可靠的。

可能会有并发症(但我会先解决问题而不用它们):

不完整集合的顺序大部分是有效的,但可能会有一些错误,它是由人类编写的。

我可能对不完整集合中的每一对元素都有额外的信息,例如

  • 5 到 6 之间肯定没有任何东西”,
  • 在 7 到 12 之间肯定还有其他东西,但我不确定有多少,具体是什么”,
  • "3 到 4 之间可能有也可能没有",
  • 7 到 9 之间恰好有一个未知项目

我想将该信息合并到算法中以恢复更多数据。

到目前为止我最好的主意:

在排序函数中使用不完整数组,如下所示:如果存在 B 在 A 之前的不完整集合,则得出 A > B。如果不存在 A 和 B 都存在的集合,则返回 A == B .

我不喜欢它的是我不知道哪些部分是完全恢复的,哪些是随机的。为了帮助我将原始元素列表打乱,再次排序并查看哪些元素改变了位置,哪些没有。并做几千次(列表中的元素数量

有更好的建议吗?

【问题讨论】:

  • 您可能还想在最初的想法中考虑传递属性。例如if A > B and B > C then A > C, 即使不存在 C 在 A 之前的不完整集合。我认为这不会改善排序的顺序,但我相信它可以用来进行排序使用正确的数据结构更高效。

标签: algorithm sorting set


【解决方案1】:

从你的不完整集合构建有向图并生成topological sort

有些错误可能会发现为循环(有向无环图中没有循环)

【讨论】:

  • 这确实会找到与给定顺序一致的 some 顺序,如果它存在的话(即,如果输入没有描述一个有向循环的图)。但是您还想检测这种排序是否是唯一的;为此,请找到 关键路径 而不是拓扑排序。如果有一些顶点不在关键路径上,那么它在顺序中的确切位置是不确定的。
【解决方案2】:

按照 MBo 的建议构建有向图。如果生成的图是有向无环图 (DAG),则视为对原始数据的验证,并且可以执行拓扑排序来恢复有关原始顺序的信息。

如果您认为您的所有信息都是可靠的,则可以将一些附加信息合并到图表中。例如,“在 5 和 6 之间肯定没有任何东西”意味着(如果理解为 5 -> 6)图的从 v 到 6(v 不等于 5)的每条边都可以被来自 v 的边替换到 5。“3 和 4 之间可能有也可能没有”:这告诉我们的只是 3 -> 4,如果它甚至说了那么多的话。

其他信息更难使用。 “7 到 12 之间的东西”可以作为 7 -> 12 并入有向图,但据我所知,“某物”部分不能。可能有一种方法可以通过扩大图形以包含“某些”顶点来使用它,但我无法让它工作。相反,我建议让您的顶级排序算法吐出每个顶级排序(假设没有太多),并通过它们与多少额外的约束一致来评估它们。作为奖励,您会发现有多少种不同的答案是可能的。你也可以在排序时使用它,例如,如果你正在寻找一个在 7 之后立即出现的项目,不要选择 12,但这对我来说感觉很乱,如果你根本不会得到任何结果信息相互矛盾。

如果生成的图不是 DAG,您仍然可以将其分成强连接的组件(例如,Tarjan 算法)。强连接组件是不可靠的部分。强连接的组件本身将形成一个可以进行顶部排序的 DAG,但是每个大于 1 个顶点的组件都需要进一步的特殊处理。处理这个问题的一种方法是尝试找到一个最小反馈弧集,即在强连接组件中消除的最小边数以将其变成 DAG。最小反馈弧集问题是 NP-hard,但问题是“固定参数易处理”:http://dl.acm.org/citation.cfm?doid=1411509.1411511。不太合理的方法也可能会起作用,例如识别一个循环并删除循环中的随机边缘,直到没有更多循环为止。

【讨论】:

    【解决方案3】:

    我想如果你取一个最长的字符串并尝试通过两个 neithebor 符号(也包括 begin 和 end )将该字符串与所有其他字符串进行比较,则可以使用某种算法:如果在其他字符串中它之间存在某些内容,请将其添加到最长的字符串,然后重新开始。如果没有要添加的内容,请检查下一对。

    【讨论】:

      猜你喜欢
      • 2016-01-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-06-02
      • 2012-08-26
      • 2021-07-31
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多