9

2x2の非線形問題を解くための2D二分法を実行するアルゴリズムが必要です。例:2つの方程式f(x,y)=0g(x,y)=0同時に解きたい。私は1D二分法(および他の数値的方法)に非常に精通しています。解が境界x1 < x < x2との間にあることを私がすでに知っていると仮定しy1 < y < y2ます。

グリッドでは、開始境界は次のとおりです。

    ^
    |   C       D
y2 -+  o-------o
    |  |       |
    |  |       |
    |  |       |
y1 -+  o-------o
    |   A       B
    o--+------+---->
       x1     x2

そして私は値f(A), f(B), f(C) and f(D)と同様に知っていますg(A), g(B), g(C) and g(D)。二等分線を開始するには、ポイントを中央だけでなくエッジに沿って分割する必要があると思います。

    ^
    |   C   F   D
y2 -+  o---o---o
    |  |       |
    |G o   o M o H
    |  |       |
y1 -+  o---o---o
    |   A   E   B
    o--+------+---->
       x1     x2

f(G)*f(M)<0 AND g(G)*g(M)<0今、圧倒されるかどうかをチェックするなどの組み合わせの可能性を検討しています。これを少し複雑にしすぎているかもしれませんが、ニュートンラプソン法を勾配演算子を使用して簡単に多次元化できるように、二等分線の多次元バージョンが必要だと思います。

手がかり、コメント、またはリンクを歓迎します。

4

7 に答える 7

7

申し訳ありませんが、二等分線は1次元で機能しますが、高次元では失敗します。領域のコーナーと内部のポイントの関数に関する情報のみを使用して、2次元領域をサブ領域に分割することはできません。ミック・ジャガーの言葉によれば、「あなたはいつもあなたが望むものを手に入れることができるとは限らない」

于 2010-08-18T16:23:39.990 に答える
6

私はgeometrictools.comC++コードからこれに対する答えに出くわしました。

編集:コードはgithubにあります。

タイトル

于 2014-01-08T22:17:02.713 に答える
5

領域を単一の次元のみに沿って分割し、次元を交互に変えます。単一の関数がゼロであるための条件は、「領域の境界に異なる符号の2つのポイントがある」ということになるので、2つの関数について確認します。ただし、特定の領域の両方の関数のゼロは共通のゼロを保証しないため、うまく機能するとは思いません(これは、基準を満たさない別の領域に存在する場合もあります)。

たとえば、次の画像を見てください。

代替テキスト

ABED正方形を区別して、それらの境界でのとの動作のみをEFIH指定する方法はありません。ただし、共通のゼロは含まれていません。f()g()ABEDEFIH

これは、たとえばを使用したリージョンクエリに似ています。kD-trees、領域にゼロなどが含まれていないことを明確に識別できる場合。f。それでも、状況によってはこれが遅くなる可能性があります。

于 2010-08-18T16:04:53.210 に答える
2

(ウッドチップへのコメントによると)f(x、y)=0が連続単調関数y= f2(x)を定義すると仮定できる場合、つまり、各x1 <= x <= x2に対して、y( f)の乱雑な形式のため、分析的に表現することはできません。同様に、y = g2(x)は連続単調関数であり、結合解を見つける方法があります。

f2とg2を計算できる場合は、[x1、x2]で1次元二分法を使用して、f2(x)-g2(x)=0を解くことができます。そして、[y1、y2]で1-d二等分線を再度使用して、考慮する必要のある任意の固定xのyについてf(x、y)= 0を解くことにより、これを行うことができます(x1、x2、(x1 + x2) / 2など)-継続的な単調性が役立つ場合-そしてgについても同様です。各ステップの後に、必ずx1-x2とy1-y2を更新する必要があります。

このアプローチは効率的ではないかもしれませんが、うまくいくはずです。もちろん、多くの2変数関数は、連続単調関数としてz平面と交差しません。

于 2010-08-18T22:58:41.927 に答える
2

私は最適化の経験があまりありませんが、質問で説明されているような二分アルゴリズムを使用して、この問題の解決策を構築しました。場合によってはルートの2倍を計算するため、ソリューションのバグを修正する必要があると思いますが、これは単純で、後で試す予定です。

編集:私はのコメントのようですjpalecek、そして今私は私が仮定したいくつかの前提が間違っていることを理解していますが、方法はまだほとんどの場合に機能します。より具体的には、ゼロは、2つの関数が反対方向で信号を変化させる場合にのみ保証されますが、頂点でゼロの場合を処理する必要があります。それに対して正当で満足のいくヒューリスティックを構築することは可能だと思いますが、それは少し複雑であり、今ではより有望な関数を取得しf_abs = abs(f, g)、ローカル最小値を見つけるためのヒューリスティックを構築して、エッジの中央。

序章

質問の構成を検討してください。

    ^
    |   C       D
y2 -+  o-------o
    |  |       |
    |  |       |
    |  |       |
y1 -+  o-------o
    |   A       B
    o--+------+---->
       x1     x2

これを行うには多くの方法がありますが、私はコーナーポイント(A、B、C、D)のみを使用し、質問が示唆する中間点や中心点は使用しないことを選択しました。あなたが説明するように、私が2つの関数f(x、y)とg(x、y)を持っていると仮定します。実際には、それは一般的に関数(x、y)->(f(x、y)、g(x、y))です。

手順は次のとおりで、最後に履歴書(Pythonコード付き)があります。

ステップバイステップの説明

  1. 各スカラー関数(fとg)の積を、隣接する点でそれら自身によって計算します。変動の各方向(軸、x、y)について、それぞれの最小積を計算します。
Fx = min(f(C)*f(B), f(D)*f(A))
Fy = min(f(A)*f(B), f(D)*f(C))

Gx = min(g(C)*g(B), g(D)*g(A))
Gy = min(g(A)*g(B), g(D)*g(C))

長方形の2つの反対側から製品を調べ、それらの最小値を計算します。これは、信号が負の場合に変化する信号の存在を表します。少し冗長ですが、うまく機能します。代わりに、ポイントを使用するなどの他の構成を試すこともできます(E、F、G、Hは質問に表示されます)が、長方形の領域全体をより適切に考慮するため、コーナーポイントを使用するのは理にかなっていると思いますが、これは印象。

  1. 各関数の牽引軸の最小値を計算します。
F = min(Fx, Fy)
G = min(Gx, Gy)

この値のそれは、長方形内の各関数fおよびgのゼロの存在を表します。

  1. それらの最大値を計算します。
max(F, G)

max(F、G)<0の場合、長方形の内側にルートがあります。さらに、f(C)= 0およびg(C)= 0の場合、ルートもあり、同じことを行いますが、ルートが他のコーナーにある場合、他の長方形がそれを計算するため、彼を無視します(根の二重計算を避けてください)。以下のステートメントが再開されます。

guaranteed_contain_zeros = max(F, G) < 0 or (f(C) == 0 and g(C) == 0)

この場合、長方形が必要なだけ小さくなるまで、領域を再帰的に分割する必要があります。

それ以外の場合は、長方形内にルートがまだ存在している可能性があります。そのため、最小の粒度になるまで、この領域を分割するためにいくつかの基準を使用する必要があります。私が使用した基準は、現在の長方形の最大寸法が元の長方形の最小寸法よりも小さいことを表明することです(以下deltaのコードサンプルで)。

履歴書

このPythonコードの履歴書:

def balance_points(x_min, x_max, y_min, y_max, delta, eps=2e-32):

    width = x_max - x_min
    height = y_max - y_min
    x_middle = (x_min + x_max)/2
    y_middle = (y_min + y_max)/2

    Fx = min(f(C)*f(B), f(D)*f(A))
    Fy = min(f(A)*f(B), f(D)*f(C))
    Gx = min(g(C)*g(B), g(D)*g(A))
    Gy = min(g(A)*g(B), g(D)*g(C))

    F = min(Fx, Fy)
    G = min(Gx, Gy)

    largest_dim = max(width, height)
    guaranteed_contain_zeros = max(F, G) < 0 or (f(C) == 0 and g(C) == 0)

    if guaranteed_contain_zeros and largest_dim <= eps:
        return [(x_middle, y_middle)]
    elif guaranteed_contain_zeros or largest_dim > delta:
        if width >= height:
            return balance_points(x_min, x_middle, y_min, y_max, delta) + balance_points(x_middle, x_max, y_min, y_max, delta)
        else:
            return balance_points(x_min, x_max, y_min, y_middle, delta) + balance_points(x_min, x_max, y_middle, y_max, delta)
    else:
        return []

結果

私は個人的なプロジェクト(ここではGitHub )で同様のコードを使用し、アルゴリズムとルートの長方形を描画します(システムには原点にバランスポイントがあります): Rectangles

それはうまくいきます。

改善

場合によっては、アルゴリズムは同じゼロの2倍を計算します。私はそれが2つの理由を持っている可能性があります:

  • 私の場合、関数は隣接する長方形で非常にゼロになります(数値の切り捨てのため)。この場合の解決策は、増やすeps(長方形を増やす)ことです。私が選んだeps=2e-32のは、32ビットが(64ビットアーキテクチャの)精度の半分であるため、関数がゼロを与えない可能性が高いからです...しかし、それは推測のようでした。より良い。ただし、を大幅に減らすとeps、Pythonインタープリターの再帰制限が推定されます。
  • 魔女の場合、f(A)、f(B)などはゼロに近く、積はゼロに切り捨てられます。関数の積の代わりにfとgの信号の積を使うと減らすことができると思います。
  • 長方形を破棄する基準を改善することは可能だと思います。これは、長方形の領域で関数がどれだけ変化しているか、および関数がゼロからどれだけ離れているかを考慮して作成できます。おそらく、コーナーの関数値の平均と分散の間の単純な関係です。別の方法(およびより複雑な方法)では、スタックを使用して各再帰インスタンスの値を格納し、この値が収束して再帰を停止することを保証できます。
于 2021-06-27T22:16:45.057 に答える
1

これは、ベクトル場で臨界点を見つけるのと同様の問題です(http://alglobus.net/NASAwork/topology/Papers/alsVugraphs93.psを参照)。

四辺形の頂点にf(x、y)とg(x、y)の値があり、離散的な問題が発生している場合(f(x、y)の解析式がないなど) g(x、y)も四辺形内の他の位置の値も)、双一次内挿法を使用して2つの方程式(fとg)を取得できます。2Dの場合、解析解は2次方程式になります。これは、解(1根、2実根、2虚根)に従って、1解、2解、解なし、四辺形の内側または外側の解になる場合があります。

代わりに、f(x、y)とg(x、y)の分析関数があり、それらを使用したい場合、これは役に立ちません。代わりに、四辺形を再帰的に分割することもできますが、 jpalecek2番目の投稿)ですでに指摘されているように、四辺形内にゼロがないことを保証するテストを考え出すことで、分割を停止する方法が必要になります。

于 2011-12-15T19:51:40.567 に答える
1

f_1(x、y)、f_2(x、y)を、xとyに関して連続で単調な2つの関数とします。問題は、システムf_1(x、y)= 0、f_2(x、y)=0を解くことです。

交互方向アルゴリズムを以下に示します。ここで、線はセット{f_1=0}と{f_2=0}を表しています。アルゴリズムの移動方向(右下または左上)は、方程式f_i(x、y)= 0を解く順序に依存することは簡単にわかります(たとえば、f_1(x、y)= 0を解く) wrt x次にf_2(x、y)= 0 wrt yを解くか、最初にf_1(x、y)= 0 wrt yを解いてからf_2(x、y)= 0 wrt x)を解きます。

最初の推測では、ルートがどこにあるかはわかりません。したがって、システムのすべてのルートを見つけるには、両方向に移動する必要があります。

于 2019-10-22T21:20:14.513 に答える