三元探索

単峰関数の極値を求めるアルゴリズム

値探索アルゴリズム[1]は、単峰性関数の最小値または最大値を見つけるコンピュータサイエンスの技術です

機能

の最大値を求めており、最大値が と の間にあることが分かっていると仮定する。アルゴリズムを適用するには、となるよう な値が存在する必要がある。 f ( x ) {\displaystyle f(x)} A {\displaystyle A} B {\displaystyle B} x {\displaystyle x}

  • を満たすすべての場合、 が成り立ち a , b {\displaystyle a,b} A a < b x {\displaystyle A\leq a<b\leq x} f ( a ) < f ( b ) {\displaystyle f(a)<f(b)}
  • を満たすすべての場合、 が成り立ちます a , b {\displaystyle a,b} x a < b B {\displaystyle x\leq a<b\leq B} f ( a ) > f ( b ) {\displaystyle f(a)>f(b)}

アルゴリズム

をある区間 上の 単峰性関数としますこの区間 上の任意の2点とをとります。このとき、3つの可能性が考えられます。 f ( x ) {\displaystyle f(x)} [ l ; r ] {\displaystyle [l;r]} m 1 {\displaystyle m_{1}} m 2 {\displaystyle m_{2}} l < m 1 < m 2 < r {\displaystyle l<m_{1}<m_{2}<r}

  • ならば、必要な最大値は左側の – には存在しない。つまり、最大値は区間内でのみ探す方が意味がある。 f ( m 1 ) < f ( m 2 ) {\displaystyle f(m_{1})<f(m_{2})} [ l ; m 1 ] {\displaystyle [l;m_{1}]} [ m 1 ; r ] {\displaystyle [m_{1};r]}
  • ならば、対称性までは前述と同様である。ここで、必要な最大値は右側の にはあり得ないので、線分 へ進む。 f ( m 1 ) > f ( m 2 ) {\displaystyle f(m_{1})>f(m_{2})} [ m 2 ; r ] {\displaystyle [m_{2};r]} [ l ; m 2 ] {\displaystyle [l;m_{2}]}
  • の場合、探索は で行われるべきですが、この場合は(コードを簡略化するために)前の2つのケースのいずれかに帰属させることができます。遅かれ早かれ、セグメントの長さは所定の定数よりわずかに短くなり、処理を停止できます。 f ( m 1 ) = f ( m 2 ) {\displaystyle f(m_{1})=f(m_{2})} [ m 1 ; m 2 ] {\displaystyle [m_{1};m_{2}]}

選択ポイント m 1 {\displaystyle m_{1}} m 2 {\displaystyle m_{2}}

  • m 1 = l + ( r l ) / 3 {\displaystyle m_{1}=l+(r-l)/3}
  • m 2 = r ( r l ) / 3 {\displaystyle m_{2}=r-(r-l)/3}
実行時間順序
T ( n ) = T ( 2 n / 3 ) + O ( 1 ) = Θ ( log n ) {\displaystyle T(n)=T(2n/3)+O(1)=\Theta (\log n)} (マスター定理による

再帰アルゴリズム

def ternary_search ( f , left , right , absolute_precision ) -> float : """left と right が現在の境界です    。最大値はそれらの間にあります。    """ if abs ( right - left ) < absolute_precision : return ( left + right ) / 2      
    


         
             

    左から3番目 =  ( 2  *  + )  /  3
    右から3番目 =  ( +  2  * )  /  3

     f ( left_third )  <  f ( right_third )
        の場合: ternary_search ( f , left_third , right , absolute_precision )を返します。 そうでない場合: ternary_search ( f , left , right_third , absolute_precision )を返します。   
    
            

反復アルゴリズム

def ternary_search ( f , left , right , absolute_precision ) -> float : """[left, right] の範囲内で単峰関数 f() の最大値を求めます。    最小値を求めるには、if/else 文を逆にするか、比較を逆にします。    """ while abs ( right - left ) >= absolute_precision : left_third = left + ( right - left ) / 3 right_third = right - ( right - left ) / 3      
    


         
                
                

         f ( left_third )  <  f ( right_third )の場合: 
            left  =  left_third 
        、そうでない場合: 
            right  =  right_third

    # 左と右が現在の境界です。最大値はそれらの間にあります。
    return  ( left  +  right )  /  2

参照

参考文献

  1. ^ “Ternary Search”. cp-algorithms.com . 2023年8月21日閲覧
Retrieved from "https://en.wikipedia.org/w/index.php?title=Ternary_search&oldid=1275560970"