7

キーが3Dのポイントであり、3つの符号付き64ビット整数で表されるデータセットがある場合。そして、(ソートされた)Key-Valueストアを使用してそれらを格納したいと思います。ここで、キーは単なるバイト配列です(ただし、コンパレーターを指定できます)。3Dモートン数の計算方法のように、Z /モートン順序で行われるように、ビットインターリーブを使用することで、これらすべてのポイントをバイト配列に変換できると思います。

モートンの順序付けなしでより簡単に実行できる個々のポイントをフェッチすることに加えて、軸に位置合わせされたボックス内を検索する範囲検索を実行したいと思います。AとBをそれぞれ、すべての座標が最も低いボックスコーナーと、すべての座標が最も高い反対側のコーナーとして定義します。

今私の質問は次のとおりです。

  1. 論理的にAとBの間にある任意の点Cについて、Cのモートン数もAとBのモートン数の間にありますか?(それがモートンの秩序のポイントではありませんか?)

  2. 1が「いいえ」の場合、AとBは、Cが含まれることを保証する値に「丸め」られますか?

  3. 1または2が可能であると仮定すると、検索結果はそのボックスの外側も指しますか?これは「ポストフィルター」で除外する必要がありますか?その「エラーセット」はどのくらいの大きさですか(検索のサイズまたは位置によって異なりますか)。

  4. 整数が符号付きであるという事実は問題を引き起こしますか?もしそうなら、回避策はありますか?

要約すると、モートン数を使用することは、実際の問題に対する1つの可能な解決策にすぎません。3Dポイントを1次元値にマッピングする必要がある場合に、3D整数空間で効率的に範囲検索する方法は?DBで単一の範囲選択を実行し、最小キーと最大キーを使用して、理想的にはボックスの外側のポイントをできるだけ少なくすることで、AとBの間のすべてのポイントを取得したいと思います。

4

3 に答える 3

7

4)はい、サインは問題を引き起こしますが、解決するのは簡単です。

モートン数を作成する前に、x、y、zの符号ビットを1とXORするだけです。

これが機能する理由(代わりに1次元の符号付きバイトを使用):

-バイナリの-1は11111111です

バイナリの0は00000000です

バイナリの1は00000001です

必要な順序は-1、0、1ですが、現在のバイナリ順序は0​​、1、-1です。

-1 XOR 10000000 = 01111111

0 XOR 10000000 = 10000000

1 XOR 10000000 = 10000001

これで、バイナリの順序が正しくなりました

于 2012-10-11T20:01:19.650 に答える
2

自分で質問に答えなければならないようです。そして、その答えは、私が実際に求めていたz階数曲線に関連しています。これは私がそれを得る限りです:

  1. はい。これは、z階数曲線では常にそのように機能します。
  2. 1)が真であるため、無関係です。
  3. エリアの大きさや場所によって異なりますが、最悪のシナリオは、スペースから遠く離れている場合ではなく、実際にスペースの中心を含める場合です。どの次元でも、各次元で深さNビットのインデックスを使用する場合、z階数曲線が完全に一致し、検索ボックスでのみポイントを取得するという特殊なケースがあります。これは、次の条件が満たされた場合に発生します。
  4. 検索領域はすべての次元で同じサイズで、2の累乗、2 ^ Mです。ここで、0 <= M<=Nです。
  5. 検索領域は、すべての軸に揃えられた超立方体です。
  6. 検索領域の超立方体の角のすべての座標は、2^Mの倍数です。これらの条件がすべて満たされると、検索領域はサブツリーノードに正確に対応するため、完全に一致します。ただし、一般的なケースでは、必要なすべてのポイントを保持する最小のノードを見つけて、部分的に一致する小さなノードに再帰的に細分化し、最大の目的の深さまで、より良い一致を得ることができます。複数のクエリを使用するコスト。エリアのすべてのコーナーを含む最小のツリーノードを見つけることは、すべてのコーナーに共通のモートンコードのプレフィックスを見つけることと同じです。また、単一のクエリを使用する場合、返される領域の外側のポイントの量は、クエリされたそのノードの量から検索領域の量を引いたものになります。
  7. それが問題だと確信していますが、それに関する情報はまだ見つかりません。

私が言っていることがはっきりしていないようですので、少しアスキーアートをやります...

2Dの基本的なZオーダー(モートンオーダー)曲線は次のようになります(パスはA、B、C、D)。

x  0   1

0  A → B
     ↙
1  C → D

したがって、A =(0,0)B =(0,1)C =(1,0)D =(1,1)

これで、2Dの基本的なヒルベルト曲線は次のようになります(パスはA、B、C、Dです)。

x  0   1

0  A   D
   ↓   ↑
1  B → C

したがって、A =(0,0)B =(1,0)C =(1,1)D =(0,1)

Z次(モートン次)の場合、曲線は最低点A(0,0)から始まり、最高点D(1,1)で終わり、その間のすべての点をカバーします。これにより、範囲検索が簡単になり、3Dでも機能します。3Dボックス(0,0,0)から(1,1,1)のすべてのポイントは、モートン注文コード(0,0,0)と(1,1,1)の間にあります。

ヒルベルト曲線では、(0,0)で開始し、(0,1)で終了します(おそらく3Dでも同様です)。したがって、(0,0)から(1,1)のヒルベルトコードから範囲クエリを実行しても、すべてのポイントが見つかるわけではありません。

したがって、ヒルベルト曲線を使用して3Dボックス(0,0,0)から(1,1,1)までの範囲クエリを(単一のDBクエリとして)実行する場合は、何を通知する関数が必要です。 (0,0,0)と(1,1,1)は機能しないため、最初のポイントとして使用する必要があるポイントと、最後のポイントとして使用する必要があるポイント。

では、8(3Dの場合)ボックス座標を指定し、範囲クエリで使用する最初と最後のポイントを返すような関数はありますか?それがないと、ヒルベルト曲線を使用して問題を解決することはできません。

または、疑似SQLの場合:

モートンクエリ:

SELECT key,data FROM table WHERE (key >= Morton(lowest(box))) AND (key <= Morton(highest(box)))

ヒルベルトクエリ:

SELECT key,data FROM table WHERE (key >= Hilbert(XXX(box))) AND (key <= Hilbert(YYY(box)))

したがって、XXX()とYYY()が必要です。

[編集]この回答の一部は、ヒルベルト曲線を使用するように指示する他の回答を対象としていましたが、その後、回答が削除されました。

于 2012-10-11T07:04:56.567 に答える
-1

一般に、3次元を1次元に縮小しようとしても期待できることはあまりありません。ただし、試すことができること:主軸を見つけて(つまり、ポイントに線を合わせて)、ポイントを線に投影します。これにより、各ポイントに対して要求された1次元の値が得られます。ボックスの角を線に投影し、これらの値の囲み間隔を取ると、検索範囲が得られます。

于 2012-10-12T12:47:52.603 に答える