2016-05-14 16 views
2

2Dポイントpが与えられているので、私はそのポイントと関数カーブの間の最小距離を計算しようとしています。 pを入力し、その距離を計算します。私が使用している例示的な機能は、いくつかの点p、提供機能との間の距離のためにscipy.optimize.minimizeを使用してグローバル最小値を探す

f(x) = 2*sin(x) 

マイ距離関数は、入力として受け取り

def dist(p, x, func): 
    x = np.append(x, func(x)) 
    return sum([[i - j]**2 for i,j in zip(x,p)]) 

、点p、位置であるx関数にはfuncという関数ハンドルがあります。これはユークリッド距離の2乗であることに注意してください(ユークリッド空間での最小化はユークリッド空間の2乗で最小化と同じです)。

これの重要な部分は、私は自分の関数の境界を提供できるようにしたいので、実際に関数セグメントに最も近い距離を見つけることです。この例では、私の境界が、私は境界を使用して、私の距離関数を最小化するためにscipy.optimize.minimize機能を使用してい

bounds = [0, 2*np.pi] 

です。上記のプロセスの結果を下のグラフに示します。

Contour plot of distance

これはsin関数からの距離を示す等高線図です。輪郭に不連続性があるように見えることに注意してください。便宜上、私はその不連続点とそれらがマップするカーブの "クローゼット"点の周りにいくつかの点をプロットしました。

ここで実際に起こっているのは、scipy関数が局所的な最小値をとっていることです(いくつかの初期推測では)が、グローバルなものではなく、不連続性を引き起こしています。グローバルな最小限の機能を見つけることは不可能だと私は知っていますが、グローバルな最小値を見つけるより信頼性の高い方法を探しています。大域的最小値を見つけるための

可能な方法は

  1. スマート初期推定を選択して、これは世界最小で開始するところ約知りになる、解決する問題の解決策を使用しているだろうそれ。
  2. 複数の初期推測を使用して、最適な最小値になる回答を選択します。しかし、これは貧しい選択のように思えます。特に、私の機能がより複雑になる(そしてより高次元になる)場合。
  3. 最小値を求めて、最小値を見つけたら、最小値を探し直して、最小値を再度探してください。私は多分、複雑なMCMCアルゴリズムやそのようなものを呼び起こさずにこれを行う方法があると思っています。このプロセスのスピードをカウントします。

この問題に取り組むための最良の方法や、この問題に取り組む可能性のある有用な機能への道案内については、お勧めできます。

+0

4.模擬アニーリング動機付けアルゴリズム(または任意の他のメタヒューリスティック)。おそらく最適化呼び出しを非常に低い反復に制限し、解決策をつかんで、この解決策が受け入れられるかどうかをSAに決定させてください。別の最適化アルゴリズムを使用する(ランダムに選択されるか、並行して実行されるか、競合するか)。 6. ipopt、bonmin、couenne(最後はグローバルソルバー)のような重いものを試してみてください。 – sascha

答えて

5

コメントで示唆しているように、scipy.optimize.differential_evolutionなどのグローバル最適化アルゴリズムを試すことができます。しかし、この場合、明確に定義され、分析的に扱いにくい目的関数がある場合、最小限の一次条件を利用して半分析的アプローチを採用することができます。

以下では、第1の関数は距離メトリックであり、第2の関数はその微分w.r.t(の分子)である。最小値が0<x<2*np.piになる場合はゼロになるはずです。今

import numpy as np  
def d(x, p): 
    return np.sum((p-np.array([x,2*np.sin(x)]))**2) 

def diff_d(x, p): 
    return -2 * p[0] + 2 * x - 4 * p[1] * np.cos(x) + 4 * np.sin(2*x) 

、点p所与、d(x,p)の電位のみminimizersはdiff_d(x,p)の根(もしあれば)、ならびに境界点x=0x=2*np.piあります。 diff_dは複数のルートを持つことができます。微分が連続関数であることに留意して、pychebfunライブラリは、すべての根を見つけるための非常に効率的な方法を提供し、scipyルート探索アルゴリズムに基づく厄介なアプローチを回避する。

以下の関数は与えられた点pためd(x, p)の最小値を提供する:ここ

import pychebfun 
def min_dist(p): 
    f_cheb = pychebfun.Chebfun.from_function(lambda x: diff_d(x, p), domain = (0,2*np.pi)) 
    potential_minimizers = np.r_[0, f_cheb.roots(), 2*np.pi] 
    return np.min([d(x, p) for x in potential_minimizers]) 

結果である:

enter image description here

関連する問題