Arielが指摘しているように、以下に示す標準の最大検出アルゴリズム:
def find_maximum(a):
m = a[0]
for x in a:
if x > m: m = x
return m
実際には、次の条件が満たされる限り、変更なしで機能します
- 要素の任意のペアを比較できます。
- 入力には、最大要素、つまり入力内の他の要素よりもペアワイズが大きい要素が含まれることが保証されます。
(最大の要素が他のすべての要素と同等でありx > y
、要素x
とy
比較できない場合は常に偽であると仮定する限り、アルゴリズムを変更しなくても、上記の最初の仮定は実際に緩和できます。)
特に、あなたの主張:
[…]確実に答えを出すには、要素を他のすべての要素と明示的に比較する必要があります(比較は推移的ではないため)。
上記の仮定の下では当てはまりません。実際、上記のアルゴリズムが常に最大要素を見つけることを証明するには、以下を観察するだけで十分です。
- ループはすべての入力要素を反復処理するため、ある反復
x
では最大要素になります。
- 最大要素は他のすべての要素よりもペアワイズが大きいため、その反復の最後に
m
最大要素になります。そして
- 他の要素は最大要素よりもペア単位で大きくなること
m
はできないため、後続の反復で変更されることはありません。
したがって、ループの最後ではm
、入力に要素が含まれている場合、常に最大要素になります。
追伸 入力に常に最大要素が含まれているとは限らない場合、その事実を検証するには、実際に最大であることを検証するために、他のすべての要素に対して候補の回答をテストする必要があります。ただし、上記の最大値検出アルゴリズムを実行した後でも、O(n)時間でそれを行うことができます。
def find_maximum_if_any(a):
# step 1: find the maximum, if one exists
m = a[0]
for x in a:
if x > m: m = x
# step 2: verify that the element we found is indeed maximal
for x in a:
if x > m: return None # the input contains no maximal element
return m # yes, m is a maximal element
(ここでは、関係>
が非再帰的であると仮定しています。つまり、それ自体よりも大きくなる要素はありません。そうでない場合は、x > m
ステップ2 の比較をに置き換えます。x ≠ m and x > m
ここで、≠
同一性比較を示します。以下に記載されています。)
アルゴリズムのこのバリエーションの正確性を証明するために、考えられる2つのケースを検討してください。
- 入力に最大要素が含まれている場合、ステップ1でそれが検出され(上記を参照)、ステップ2で確認されます。
- 入力に最大要素が含まれていない場合、ステップ1は任意の要素をとして選択し
m
ます。どの要素でも最大ではないため、どの要素であるかは関係ありませんNone
。したがって、ステップ2はそれを検出してを返します。
のインデックスをm
入力配列に保存した場合a
、実際にはステップ2を最適化m
してa
、前に来る要素のみをチェックできm
ます。これは、後の要素が既にステップ1 と比較されているためです。アルゴリズムの、まだO(n)です。