web-dev-qa-db-ja.com

不変式とは何ですか?

Wordは多くの文脈で使用されるようです。私が理解できる最高のものは、それらが変化できない変数を意味するということです。それは定数/ファイナル(Java!)の目的ではありませんか?

119
Dustman

不変式は、変数よりも「概念的」です。一般に、それは常に真であるプログラム状態のプロパティです。不変式が保持されることを保証する関数または方法は、不変式を維持すると言われます。

たとえば、バイナリ検索ツリーには、ノードごとに、ノードの左の子のキーがノード自身のキーよりも小さいという不変式が含まれる場合があります。このツリーに対して正しく記述された挿入関数は、その不変式を維持します。

あなたが言うことができるように、それはあなたが変数に格納できるものの種類ではありません:それはより多くのステートメントですaboutプログラム。プログラムがどのような不変式を維持すべきかを考え、コードを見直して実際にそれらの不変式を維持していることを確認することで、コードの論理エラーを回避できます。

172
Jacob Baskin

これは、ロジック内の特定の場所で常に真であることがわかっている条件であり、デバッグ時にいつ問題が発生したかを確認するためにチェックできます。

27
moonshadow

私は通常、アルゴリズムまたは構造の観点からそれらをよりよく見ます。

たとえば、アサートできるループ不変式を使用できます。これは、各反復の開始時または終了時に常に真になります。つまり、ループが1つのスタックから別のスタックへのオブジェクトのコレクションを処理することになっている場合、ループの最上部または最下部で| stack1 | + | stack2 | = cと言うことができます。

不変式チェックが失敗した場合、何かがおかしかったことを示します。この例では、処理された要素を最終スタックなどにプッシュするのを忘れたことを意味する場合があります。

17
Michael Haren

ウィキペディアの魔法: Invariant(computer science)

コンピューターサイエンスでは、真の場合、特定の操作シーケンスを通じて真のままであるという述語は、そのシーケンスに対して不変と呼ばれます。

14
cero

この行が示すように:

コンピューターサイエンスでは、真の場合、特定の操作シーケンスを通じて真のままであるという述語は、そのシーケンスに対して不変と呼ばれます。

この希望をよりよく理解するには、C++のこの例が役立ちます。

いくつかの値を取得し、countという変数でそれらの合計数を取得し、sumという変数にそれらを追加する必要があるシナリオを考えます。

不変式(これも概念に近い):

// invariant:
// we have read count grades so far, and
// sum is the sum of the first count grades

上記のコードは次のようになります。

int count=0;
double sum=0,x=0;
while (cin >> x) {
++count;
sum+=x;
}

上記のコードは何をしますか?

1)cinから入力を読み取り、xに入れます

2)1回の読み取りに成功したら、countおよびsum = sum + x

3)読み取りが停止するまで1-2を繰り返します(つまり、ctrl + D)

ループ不変式:

不変式はTrue[〜#〜] always [〜#〜]でなければなりません。したがって、最初はこれだけでコードを開始します

while(cin>>x){
  }

このループは、標準入力からデータを読み取り、xに格納します。よくて。しかし、invariantの最初の部分が従わなかった(またはtrueのままだった)ため、invariantはfalseになります。

// we have read count grades so far, and

不変式を真に保つ方法は?

シンプル!増分カウント。

そう ++count;うまくいく!。これで、コードは次のようになります。

while(cin>>x){
 ++count; 
 }

だが

invariant(TRUEでなければならない概念)は、our invariantの2番目の部分を満たしていないため、Falseです。

// sum is the sum of the first count grades

だから今何をすべきか?

xsumに追加し、sumsum+=x)および次回cin>>xは、新しい値をxに読み込みます。

これで、コードは次のようになります。

while(cin>>x){
 ++count; 
 sum+=x;
 }

確認しよう

コードが不変条件に一致するかどうか

// invariant:
// we have read count grades so far, and
// sum is the sum of the first count grades

コード:

while(cin>>x){
 ++count; 
 sum+=x;
 }

あ!ループ不変式はTruealwaysであり、コードは正常に機能します。

上記の例はを取り、修正したものですAccelerated C++ Andrew-koeningとBarbara-E

9
void

コードブロック内で変化しないもの

4
Chris

それが何であるかに従って、不変式はきれいなコードを書くのに非常に便利です。なぜなら、不変式がどのように存在すべきかを概念的に知っているからですinこれらの目的を達成するためにコードを整理する方法。先ほど述べたように、不変式が維持されているかどうかを確認することは、実行しようとしている操作が実際に望んでいることを実際に行っているかどうかを確認する良い方法であるため、デバッグにも役立ちます。

2
Kaushik

通常、特定の数学的操作では変化しない量です。 はスカラーであり、回転しても変化しません。たとえば、磁気共鳴画像法では、回転不変量によって組織の特性を特徴付けることが有用です。なぜなら、その推定は、理想的にはスキャナー内の体の向きに依存しないからです。

2
HassanTC

ADT不変式は、インスタンスメソッドの実行の前後に常に真でなければならないデータフィールド(インスタンス変数)間の関係を指定します。

1

不変式の優れた例と、それが重要である理由が本にあります Javaの並行性の実践

Java中心ですが、この例では、指定された整数の係数の計算を担当するコードについて説明します。サンプルコードは、最後に提供された数値と、パフォーマンスを改善するために計算された要因をキャッシュしようとします。このシナリオには、コード例では考慮されなかった不変条件があり、同時シナリオで競合状態の影響を受けやすいコードを残しています。

enter image description here