7


3

パズル:ソートおよび/またはハッシュを許可しない「複雑な」同値関係/パーティションの例が必要

「https://stackoverflow.com/questions/3256468/is-partitioning-easier-than-sorting [パーティショニングはソートより簡単ですか?]」という質問から:

_ _ アイテムのリストとそれらの等価関係があり、2つのアイテムの比較に一定の時間がかかるとします。 アイテムのパーティションを返します。 リンクされたリストのリスト。各リストには同等のアイテムがすべて含まれています。

これを行う1つの方法は、アイテムの順序付けに同等性を拡張し、それらを順序付けすることです(ソートアルゴリズムを使用)。その後、すべての同等のアイテムが隣接します。 _ _

(平等とhttp://en.wikipedia.org/wiki/Equivalence_relation[equivalence]の違いに留意してください。)

順序付けアルゴリズムを設計する際には、明らかに同値関係を考慮する必要があります。 たとえば、同値関係が「同じ年に生まれた人は同等」である場合、その人の名前に基づいたソートは適切ではありません。

  1. 次のようなデータ型と等価関係を提案できますか 順序を作成することはできませんか?

  2. 可能であればデータ型と等価関係はどうですか このような順序を作成することはできますが、同等のアイテムを同じハッシュ値にマップするデータ型にハッシュ関数を定義することはできません。

(注:同等のアイテムが同じハッシュ値にマップ(衝突)しても問題ありません-衝突の問題を解決することは求めていません-一方、 `hashFunc(item){return 1;}`は不正行為。)

私の疑いは、順序を定義することが可能なデータ型/等価ペアの場合、適切なハッシュ関数を定義することも可能であり、それらは同様のアルゴリズムの複雑さを持つことです。 その推測に対する反例は啓発的です!

8 Answer


5


質問1と2への答えは、次の意味でいいえです:文字列\ {0、1} ^ * ^の計算可能な等価関係givenが与えられた場合、x≡yがf( x)= f(y)。順序/ハッシュ関数になります。 f(x)の定義の1つは単純であり、計算が非常に遅くなります。\ {0、1} ^ * ^を辞書式順序(ε、0、1、00、01、10、11、000、…)で列挙して返すxに相当する最初の文字列。 xに達すると終了することが保証されているため、このアルゴリズムは常に停止します。


2


ハッシュ関数と順序を作成するのは高価ですが、通常は可能です。 1つの秘isは、ビットクラスと見なされたときに、そのクラスの事前に配置されたメンバー、たとえば、シリアル化された表現が最小のメンバーによって等価クラスを表すことです。 誰かが同等クラスのメンバーを渡すと、そのクラスのこの正規化されたメンバーにマッピングし、そのメンバーのビット文字列表現をハッシュまたは比較します。 例えば参照。 http://en.wikipedia.org/wiki/Canonical#Mathematics

これが不可能または便利ではない例には、誰かがequals()を実装するオブジェクトへのポインターを与えるが、他には何も役に立たない場合、およびオブジェクトの内部を見るために型システムを壊すことができず、結果が得られる場合が含まれますオブジェクト間の平等を判断することのみを人々に求める調査の また、Kruskalのアルゴリズムは内部でUnion&Findを使用して同値関係を処理するため、この特定のアプリケーションでは、これ以上費用対効果の高いものは見つかりませんでした。


1


あなたの要求に合うと思われる一例は、IEEE浮動小数点型です。 特に、NaNは、NaNであることを検出するための特別な手順を実行し、常にその同等物を呼び出す場合を除き、他の何とも同等ではありません。

ハッシュについても同様です。 メモリが機能する場合、仮数部のすべてのビットが0に設定されている浮動小数点数は、指数のビットに設定されている値に関係なく、値0.0として扱われます。 私は少し間違っていることを覚えているかもしれませんが、どのような場合でも考え方は同じです-数字の一部に正しいビットパターンがあるということは、残りのビットの値が「無視」であることを意味します。 ハッシュ関数がこれを考慮しない限り、実際に正確に等しいと比較される数値に対して異なるハッシュ値を生成します。


1


おそらくご存じのとおり、比較ベースの並べ替えには少なくともO(n log n)時間かかります(より正式にはOmega(n log n)と言います)。 log2(n)同等クラスよりも少ないことがわかっている場合、パーティション内の特定の要素を割り当てる必要があるパーティション内の部分を決定するために各同等クラスの単一のメンバーと同等をチェックするだけでよいため、パーティション化は高速になります。

I.e. アルゴリズムは次のようになります。

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に完全な順序付けがない場合でも機能することに注意してください。


1


理論的には、数え切れない数のパーティションがある場合でも、http://en.wikipedia.org/wiki/Well-ordering_theorem [Well Ordering Theorem]のために(質問1および2について)常に可能です。

計算可能な機能に制限していても、throwawayaccountの答えはそれに答えます。

より正確に質問を定義する必要があります:-)

いかなる場合でも、

実際に言えば、

次の点を考慮してください。

データ型は、符号なし整数配列のセットです。 順序は辞書式比較です。

hash(x)= xを検討することもできますが、それも不正行為だと思います:-)

ハッシュ自体が非現実的になる可能性があるため、順序付けによるパーティショニングはハッシュによるパーティショニングよりもはるかに実用的であると言えます(ただし、ハッシュ関数の取得についてはまだ考えていません)。 (ハッシュ関数が存在することは間違いありません)。


0


編集:この答えは間違っています

以下のコメントのいくつかが啓発的であるという理由だけでそれを削除するつもりはありません

すべての等価関係が順序を意味するわけではありません

あなたの同値関係は順序を誘発するべきではないので、順序付けされていない距離関数を関係として取りましょう。

関数セットf(x):R→ Rをデータ型として取得し、等価関係を次のように定義する場合:

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

次に、その順序で並べ替えることはできません(実数の単射関数は存在しません)。 関数のスペースのカーディナリティのために、データ型を数値にマップする関数を見つけることができません。


0


私は信じている…​

_ 1-順序付けを作成できないようなデータ型と同値関係を提案できますか? _

…​it’s possible only for infinite (possibly only for non-countable) セット。

_ 2-このような順序を作成することは可能ですが、データ型にハッシュ関数を定義して同等のアイテムを同じハッシュ値にマップすることができない場合のデータ型と同値関係についてはどうでしょうか。 _

…​same as above.


0


F(X)は、あるデータ型Tの要素を同じ型の別の要素にマッピングする関数であり、型Tの任意のYに対して、F(X)= Yである型TのXが1つだけ存在すると仮定します。 さらに、与えられたYに対して上記の式でXを見つける実際的な方法が一般にないように関数が選択されたと仮定します。

F0 = X、F \ {1}(X)= F(X)、F \ {2}(X)= F(F(X))などを定義します。 したがって、F \ {n}(X)= F(F \ {n-1}(X))。

ここで、正の整数Kと型TのオブジェクトXを含むデータ型Qを定義します。 したがって、同値関係を定義します。

Q(a、X)対Q(b、Y):

a> bの場合、アイテムはF \ {a-b}(Y)== Xである場合に等しい

a <bの場合、アイテムはF \ {b-a}(X)== Yである場合に等しい

a = bの場合、X == Yの場合、アイテムは等しい

任意のオブジェクトQ(a、X)に対して、F \ {a}(Z)== Xに対してZが1つだけ存在します。 2つのオブジェクトは、同じZを持つ場合は同等です。 Zに基づいて順序付け関数またはハッシュ関数を定義できます。 一方、Fが逆数を実際に計算できないように選択された場合、要素を比較する唯一の実用的な方法は、上記の等価関数を使用することです。 私は、アイテムが持つことができる最大の「a」値を知らないか、関数Fを反転させる手段を持たずに、順序付け関数またはハッシュ関数を定義する方法を知りません。