拼图:需要一个不允许排序和/或散列的“复杂”等价关系/分区的例子

时间:2010-07-16 03:42:34

标签: algorithm sorting puzzle partitioning

问题“Is partitioning easier than sorting?”:

  

假设我有一个项目列表和一个   对它们的等价关系,和   比较两个项目需要不变   时间。我想返回一个分区   物品,例如链接列表   列表,每个包含所有等价物   项目

     

这样做的一种方法是扩展   等同于对的排序   物品和订购(排序   算法);那么所有等价物品   将毗邻。

(请记住平等与equivalence之间的区别。)

显然,在设计排序算法时必须考虑等价关系。例如,如果等价关系是“同一年出生的人是等价的”,则根据人名进行排序是不合适的。

  1. 您能否建议一种数据类型和等价关系,以便无法创建排序?

  2. 数据类型和等价关系如何 可以创建这样的排序,但可以在数据类型上定义散列函数将等效项目映射到相同的哈希值。

  3. (注意:如果非等价物品映射到相同的散列值(碰撞),则可以 - 我不是要求解决碰撞问题 - 但另一方面,hashFunc(item) { return 1; }是作弊。)

    我怀疑对于任何可以定义排序的数据类型/等价对,也可以定义合适的散列函数,它们将具有类似的算法复杂度。这个猜想的一个反例就是具有启发性!

8 个答案:

答案 0 :(得分:5)

问题1和2的答案在以下意义上是否定的:给定字符串{0,1} * 上的可计算等价关系≡,存在可计算函数f,使得x≡ y当且仅当f(x)= f(y)时,才会产生订单/散列函数。 f(x)的一个定义很简单,计算速度很慢:按字典顺序枚举{0,1} * (ε,0,1,00,01,10,11,000, ...)并返回相当于x的第一个字符串。我们保证在达到x时终止,所以这个算法总是停止。

答案 1 :(得分:2)

创建哈希函数和排序可能很昂贵,但通常是可能的。一个技巧是通过该类的预先安排的成员来表示等价类,例如,当被视为位串时,其序列化表示最小的成员。当有人向您提供等价类的成员时,将其映射到该类的该规范化成员,然后散列或比较该成员的位串表示。参见例如http://en.wikipedia.org/wiki/Canonical#Mathematics

这是不可能或不方便的例子包括当某人给你一个指向实现equals()但没有其他任何有用的对象的指针时,你不会破坏类型系统来查看对象内部,当你得到调查结果,只要求人们判断对象之间的平等。此外,Kruskal的算法使用Union& Find内部来处理等价关系,因此对于这个特定的应用来说,没有找到更具成本效益的方法。

答案 2 :(得分:1)

一个似乎符合您要求的示例是IEEE浮点类型。特别是,除非你采取特殊的步骤来检测它是一个NaN,并且总是调用那个等价物,否则NaN不会与其他任何东西(甚至是它自己)等效。

同样哈希。如果存储器服务,则将有效数据的所有位设置为0的任何浮点数被视为具有值0.0,而不管指数中的位被设置为什么。我可能记得有点不对,但在任何情况下这个想法都是一样的 - 数字的一部分中的正确位模式意味着它具有值0.0,无论中的位是什么其余的部分。除非您的哈希函数考虑到这一点,否则它将为真正比较精确相等的数字生成不同的哈希值。

答案 3 :(得分:1)

正如您可能知道的那样,基于比较的排序至少需要O(n log n)时间(更正式地说,你会说它是Omega(n log n))。如果您知道log2(n)等价类少于,则分区更快,因为您只需要检查每个等价类的单个成员的等效性,以确定应该为分配给定元素的分区中的哪个部分。

即。你的算法可能是这样的:

For each x in our input set X:
    For each equivalence class Y seen so far:
        Choose any member y of Y.
        If x is equivalent to y:
            Add x to Y.
            Resume the outer loop with the next x in X.

    If we get to here then x is not in any of the equiv. classes seen so far.
    Create a new equivalence class with x as its sole member.

如果有m个等价类,则内循环运行最多m次,整体花费O(nm)时间。正如ShreetvatsaR在评论中观察到的,最多可以有n个等价类,因此这是O(n ^ 2)。请注意,即使X上没有总排序,这也有效。

答案 4 :(得分:1)

理论上,由于Well Ordering Theorem,即使你有无数的分区,也总是可能(对于问题1和2)。

即使您限制为可计算函数,throwawayaccount的答案也会回答。

您需要更准确地定义您的问题: - )

无论如何,

实际上,

请考虑以下事项:

您的数据类型是无符号整数数组的集合。排序是词典比较。

你可以考虑hash(x)= x,但我想这也是作弊: - )

我会说(但是没有考虑更多关于获取哈希函数,所以可能错了)通过排序进行分区比通过散列进行分区更加实用,因为散列本身可能变得不切实际。 (毫无疑问,存在散列函数)。

答案 5 :(得分:0)

编辑:这个答案错了​​

我不打算删除它只是因为下面的一些评论很有启发性

并非每个等价关系都意味着订单

由于你的等价关系不应该引起秩序,所以我们将无序距离函数作为关系。

如果我们得到函数集f(x):R - > R作为我们的数据类型,并将等价关系定义为:

f is equivalent to g if  f(g(x)) = g(f(x)  [commuting Operators][1]

然后你不能对那个顺序进行排序(真实数字不存在内射函数)。由于函数空间的基数,您无法找到将数据类型映射到数字的函数。

答案 6 :(得分:0)

相信 ......

  

1-你能否建议一个数据类型和等价关系   不可能创建订单?

......只有无限(可能只有不可数)的集合才有可能。

  

2-数据类型和等价关系如何   可以创建这样的排序,   但是不可能定义一个   数据类型的哈希函数   将等效项目映射到相同的项目   哈希值。

......与上述相同。

答案 7 :(得分:0)

假设F(X)是将某个数据类型T的元素映射到同一类型的另一个元素的函数,这样对于任何类型为T的Y,只有一个类型为T的X,使得F(X) )= Y。进一步假设选择函数,以便在给定Y的上述方程中通常没有找到X的实用方法。

定义F0 = X,F {1}(X)= F(X),F {2}(X)= F(F(X))等等,所以F {n}(X)= F( ˚F{N-1}(X))。

现在定义一个包含正整数K的数据类型Q和一个类型为T的对象X.定义一个等价关系:

Q(a,X)vs Q(b,Y):

如果是> b,如果F {a-b}(Y)== X

,则项目相等

如果< b,如果F {b-a}(X)== Y

,则项目相等

如果a = b,则项目等于iff X == Y

对于任何给定的对象Q(a,X),F {a}(Z)== X恰好存在一个Z.两个对象是等效的,如果它们具有相同的Z.可以基于Z定义排序或散列函数。另一方面,如果选择F使得其逆不能实际计算,则比较元素的唯一实用方法可能是使用上面的等价函数。我知道无法在不知道项目可能具有的最大可能“a”值的情况下定义排序或散列函数,或者有一种方法来反转函数F.