【问题标题】:Sorting algorithm correctness verification排序算法正确性验证
【发布时间】:2020-06-09 07:28:22
【问题描述】:

我正在尝试验证排序算法 S 的正确性,该算法对至少 4 GB 的大型数组 A 进行排序。假设S 按非降序排序,仅检查A[i - 1] <= A[i] for 1 <= i < n 是不够的。这是因为S 生成的键,即使已排序,也可能包含一个或多个不属于原始A 的键。

我至少能想到两种简单的方法来测试正确性:

  1. 在对A 进行排序之前,将A 复制到A_copy,在A_copy 上使用std::sort,并在排序后检查A[i] == A_copy[i] for 0 <= i < n。
  2. 在排序前维护一个std::unordered_map来存储A中键的频率,除了非递减顺序检查外,还用排序后的频率进行验证。

上述方法存在明显的问题。 std::sort 对于大数据非常慢,需要O(n) 额外的内存。使用映射应该更快,但如果键是唯一的,则还需要额外的O(n) 内存。

我的问题:有没有更好的方法来执行这种既快速又使用O(1)额外内存的正确性检查?

谢谢。

【问题讨论】:

  • This is because the keys produced by S, even though sorted, may contain one or more keys that do not belong to the original A. 反之亦然吗?排序算法也可以“丢弃”元素吗?如果没有,您只需要按照您的建议检查A[i-1] <= A[i] for i=1,...n 并且元素的数量是否相同。
  • @amit 是的。我想我的意思是S 可能会用A 中没有的东西替换原始A 中的一个或多个键,并且仍然会产生一个排序数组。

标签: c++ sorting hash bigdata correctness


【解决方案1】:

您可以将您的算法视为通过不可靠通道传输的消息,并利用错误detection/correction methods。主要不同之处在于您的数据超出了原始顺序,而大多数纠错都对位置敏感,尽管不是全部。

一个简单的解决方案是将所有a的hash(a)的XOR值存储在A中,尽管它只能可靠地检测是否添加了一个元素(例如,如果一个元素被添加了两次,它将无法识别它)。

int verification = 0;
for (const auto& a : A) {
  verification ^= hash(a)
}
mySort(A);
for (const auto& a : A) {
  verification ^= hash(a)
}

if (verification != 0) {
  // invalid
} else {
  // valid
}

文献中包含更多用于识别甚至纠正电线错误的选项,您可以使用这些选项。这些将允许您在使用的额外内存量和能够找到的错误数量之间做出很好的权衡。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-27
    • 1970-01-01
    • 2023-03-29
    相关资源
    最近更新 更多