web-dev-qa-db-ja.com

アルゴリズム:ソートできないデータのバイナリ検索/ツリー/パーティショニング?

まず、この質問は実際には 二分探索 に関するものではありません。私はどちらもソートされたデータもソート可能なデータもまったく持っていません。 :-)

W.r.t「分類できない」主張は以下を参照してください。しかし、ここでは「ソートできない」というタイトルの用語が重要だと思います。なぜなら、どんなソートでも、すべての「ノード」にアクセスする必要があるからです。

質問以下のアルゴリズム/アルゴリズム検索アプローチの用語を提供してください

例による長い曲がりくねったイントロ:私が持っているものは、本質的に、名前のリストであり、すべての「有効な」名前を見つける必要があります。ただし、有効な名前を決定するには、サードパーティのシステムにクエリを実行する必要があります。これに関しては、単純化された問題インターフェイス関数は1つだけです。

_// remote 3rd party interface
// return true if all names in the given list are valid
// [names] may be a list of 1 - n strings
bool has_invalid_names(List names)
_

したがって、私のリスト_l := [a, b, c, ...]_が与えられた場合、すべての有効な名前、つまりhas_invalid_names([i]) == falseを収集する必要があります。

最も簡単なことは、明らかに線形検索を実行することですが、これはall_names_are_valid(i)をn回呼び出すことを意味し、各リモート呼び出しにはかなりのオーバーヘッドがあるため、非常にコストがかかる可能性があります。

最初のリストに非常に少数無効な名前しかないと予想されることを考えると、直感的には、リストを半分にスライスしてこれらを検索するというアイデアを思いつきました。

_a) Split list in halve
b) for each half, check if any names are invalid
c) rinse and repeat for all slices that show "invalid"
   until you're down to calls with just single names
_

これは、最初のリストのスライスのツリーを構築するだけです

_[a, b, c, d, e, f, g*, h]
            /\
[a, b, c, d]  [e, f, g*, h]
      /\              /\
[a, b]  [c, d]  [e, f]  [g*, h]
  /\      /\      /\      /\  
[a][b]  [c][d]  [e][f]  [g*][h]
_

無効な名前の数が少ない場合、このツリーをたどる必要があるパスはごくわずかであり、基本的にニアlog2(n)呼び出しのみが必要です。すべての名前が無効な最悪の場合は_2*n-1_。

上記の例では、サブリストを左から右に試してみるとすると、リモート関数を6回呼び出して、「無効な」_g*_を見つける必要があります。 nが大きい場合、無効なアイテムがごくわずかである限り、節約はより重要になります。

だから、私はこの問題の解決策を持っていますが、これは何と呼ばれていますか

  • データセットをスライスのツリーに分割する特定の名前はありますか
  • 検索アルゴリズム/その一部は何と呼ばれますか?

    nsortedbinary tree search のようです。ここでpredicateeach nodeに適用され、どのサブ-ツリーに従うべきですが、私は全体のアルゴリズムとデータ構造Zooに本当に弱いです。 :-)

    機械的には、より複雑なマップ関数で map、filter(、reduce) が達成する方向に向かっているようです。

別の言い方をすると、この問題を解決したい場合、どのライブラリ、 既存のアルゴリズム 、およびデータ構造を使用しますか? ->注:質問全体は、私が怠惰で、スライス、ツリー化、場合によっては自分自身を繰り返してコード化したくないという事実によって引き起こされましたが、WideNetはプレハブのもので私を甘やかしませんでした。 :-)

2
Martin Ba

これは、無効な要素のバイナリ検索と解釈できます。それは一種の分割統治戦略です。

再帰で十分なので、通常は特別なデータ構造やアルゴリズムを使用しません。表示されているツリーは、コールグラフとしてエンコードされているだけであり、明示的に存在する必要はありません。配列を半分に分割するsplit()操作を指定すると、すべての無効な要素を見つけることができます。

_find_invalid_elements(input: array): array
  return [] if input is empty
  return [] if not has_invalid_element(input)
  return input if input size = 1
  left, right := split(input)
  return find_invalid_elements(left) + find_invalid_elements(right)
_

has_invalid_element() Oracleが唯一の利用可能な情報源である場合、これが最適だと思います。さらに便利なOracleは、無効な要素のnumberを提供します。これは、より小さなスライスに再帰する代わりに、重複する複数のパーティションをテストできるためです。

1
amon