web-dev-qa-db-ja.com

線形探索のループ不変条件

アルゴリズム入門( http://mitpress.mit.edu/algorithms )に見られるように、演習では次のように述べています。

入力:配列A[1..n]および値v

出力:インデックスi、ここでA[i] = vまたはNILがない場合はvAで見つかりました

LINEAR-SEARCHの擬似コードを記述します。これは、シーケンスをスキャンしてvを探します。ループ不変条件を使用して、アルゴリズムが正しいことを証明します。 (ループ不変条件が、初期化、保守、終了の3つの必要なプロパティを満たしていることを確認してください。)

アルゴリズムの作成に問題はありませんが、ループ不変条件をどのように決定できるかがわかりません。ループ不変条件の概念、つまり、ループの開始前、各反復の終了/開始時に常に真であり、ループの終了時にも真である条件を理解したと思います。これが通常の目標であるため、たとえば 挿入ソート で、j = 2から開始して、jを反復処理すると、A[1..j-1]要素は常にソートされます。これは私には理にかなっています。しかし、線形探索の場合はどうでしょうか。私は何も考えられません。ループ不変条件を考えるには単純すぎるように聞こえます。私は何か間違ったことを理解しましたか?私は次のような明白なことしか考えられません(それはNILまたは0とnの間のいずれかです)。よろしくお願いします!

29
Clash

インデックスiを調べたが、vがまだ見つからなかった場合、vの前の配列の部分に関してiについて何と言えますか。 iの後の配列の部分に関して?

15
Svante

線形探索の場合、ループバリアントはインデックス(出力)を保存するために使用されるバッキングストアになります。

バッキングストアにindexという名前を付けましょう。これは、最初はNILに設定されています。ループバリアントは、次の3つの条件に従う必要があります。

  • 初期化:この条件はインデックス変数に当てはまります。NILが含まれているため、結果の結果であり、最初の反復の前に当てはまります。
  • メンテナンス:インデックスは、アイテムvが見つかるまでNILを保持します。これは、反復前と次の反復後にも当てはまります。同様に、比較条件が成功した後、ループ内に設定されます。
  • 終了:インデックスには、NILまたはアイテムvの配列インデックスが含まれます。

7
ani07

ループ不変条件は

forevery 0 <= i <k、ここでkはループ反復変数の現在の値A [i]!= v

ループ終了時:

a [k] == vの場合、ループは終了し、kを出力します

a [k]!= v、およびk + 1 == n(リストのサイズ)の場合、ループは値nilで終了します

正当性の証明:演習として残しました

5
Larry Watanabe
LINEAR-SEARCH(A, ν)
1  for i = 1 to A.length
2      if A[i] == ν 
3          return i
4  return NIL 

ループ不変条件:iループのfor番目の反復の開始時(1〜4行目)、

∀ k ∈ [1, i) A[k] ≠ ν.  

初期化:

i == 1 ⟹ [1, i) == Ø ⟹ ∀ k ∈ Ø A[k] ≠ ν,

空集合に関するすべてのステートメントが真であるため、これは真です(空虚な真理)。

Maintenance:iループのfor番目の反復の開始時にループ不変条件が真であると仮定しましょう。 A[i] == νの場合、3行目が実行されるため、現在の反復が最後の反復になります(終了セクションを参照)。それ以外の場合、A[i] ≠ νの場合、

∀ k ∈ [1, i) A[k] ≠ ν and A[i] ≠ ν ⟺ ∀ k ∈ [1, i+1) A[k] ≠ ν,

これは、次の反復(i+1th)の開始時に不変ループが引き続き真であることを意味します。

終了:forループは、次の2つの理由で終了する場合があります。

  1. return i(3行目)、A[i] == νの場合;
  2. i == A.length + 1forループの最後のテスト)。この場合、A.length + 1番目の反復の開始時にあるため、ループ不変条件は次のようになります。

    ∀ k ∈ [1, A.length + 1) A[k] ≠ ν ⟺ ∀ k ∈ [1, A.length] A[k] ≠ ν
    

    NIL値が返されます(4行目)。

どちらの場合も、LINEAR-SEARCHは期待どおりに終了します。

2
Joyce

[0 ... i-1]からインデックスが付けられた長さiの配列があり、アルゴリズムがこの配列にvが存在するかどうかをチェックしていると仮定します。完全にはわかりませんが、ループ不変条件は次のようになります。jがvのインデックスである場合、[0..j-1]はvを持たない配列になります。

初期化:0..i-1から反復する前に、チェックされている現在の配列(なし)はvで構成されていません。

メンテナンス:jでvを見つけると、[0..j-1]の配列はvのない配列になります。

終了:ループがjでvを見つけると終了するため、[0..j-1]はjのない配列になります。

配列自体にvがない場合、j = i-1であり、上記の条件は引き続き当てはまります。

2
Mayank Shah

線形検索の不変条件は、iより前のすべての要素が検索キーと等しくないことです。二分探索の妥当な不変条件は、範囲[low、high)であり、lowの前のすべての要素はキーより小さく、highの後のすべての要素はそれ以上です。わずかに異なる不変条件とプロパティを持つバイナリ検索のバリエーションがいくつかあることに注意してください。これは、キー以上の要素の最小インデックスを返す「下限」バイナリ検索の不変条件です。

出典: https://www.reddit.com/r/compsci/comments/wvyvs/what_is_a_loop_invariant_for_linear_search/

私には正しいようです。

1
Prashant N

私が書いたLSアルゴリズムは-

LINEARSEARCH(A, v)
  for i=0 to A.length-1
    if(A[i] == v)
      return i
  return NIL

線形探索の正しさをチェックするためにループ不変条件について独自の仮定をしました.....多分それは完全に間違っているので、私の仮定についての提案が必要です。

1)初期化時-i = 0で、i = 0でvを検索しています。

2)連続する反復で-i <A.length-1までvを探します

3)終了時-i = A.lengthで、A.lengthまでvを探し続けました。

0
Abhay_maniyar