それは正確にはかなりの解決策ではありません。実際、実装するのはかなり面倒ですが、確かに多項式の複雑さが増します。複雑さも大きいですが (n^5*k は私の概算です)、誰かがそれを改善する方法を見つけたり、ここでより良い解決策のアイデアを見つけたりするかもしれません。または、それで十分かもしれません。この複雑さでさえ、ブルートフォースよりもはるかに優れています。
注S
:ハルを使用した最適解 (セット) にH
は、元のセット内のすべてのポイントが含まれますH
。そうしないと、 の境界点の 1 つを破棄してH
、その欠落した点を含めて、周囲を減らすことができます。
( 「最適化」mbeckishの投稿と同じように更新)
仮定: セットからの 2 つの点が垂直線を形成しない。座標の原点を中心に不合理な角度で点のセット全体を回転させることで簡単に実現できます。
上記の仮定により、複雑なハルには左端と右端に 1 つのポイントがあります。また、この2点で船体をパーツに分けていtop
ますbottom
。
top
では、この船体のパーツからセグメントを 1 つと、パーツからセグメントを 1 つ取り出しますbottom
。middle segments
これらの 2 つのセグメントと、この船体の右側の部分の境界を境界と呼びましょうright
。
注: これら 2 つのセグメントは、凸包の右側部分を左側に構築し続けるために知っておく必要があるすべてです。しかし、4 点ではなく 2 点だけでは十分ではありません。この方法では「凸性」の条件を維持できませんでした。
解決へと導きます。i
ポイント {p0, p1, p2, p3} と数値(i <= k)の各セットについて、right
[p0, p1]、[p2, p3] が 2 つのmiddle
セグメントでありi
、このソリューションの一部のポイントright
(境界線だけでなく、その内部のものも含む)。
右から左にすべてのポイントを通過します。新しい点ごとに、点 p がこの船体を左側 (またはパーツ上)p
に継続できるように、点 {p0、p1、p2、p3} のすべての組み合わせをチェックします。そのような set と size ごとに、最適な周囲サイズが既に保存されています (上記の段落を参照)。top
bottom
i
注:ポイント {p0, p1, p2, p3} で形成されたポイントにポイントp
を追加する場合、セット サイズを少なくとも 1 増やします。ただし、この数が 1 を超える場合もあります。三角形 {p, p0, p2}。船体の上ではなく、船体の中にあります。right-hull
i
アルゴリズムは終わりです :) さらに、恐ろしく複雑ですが、すべてのセグメント [p0, p1]、[p2, p3] がmiddle
セグメントであるとは限らないことに注意してください: 実際の計算時間を大幅に短縮するはずです。
更新これは、セット自体ではなく、最適な周囲サイズのみを提供します。しかし、セットを見つけるのは簡単です。上記の「状態」ごとに、周囲のサイズだけでなく、最後に追加されたポイントも保存します。次に、ソリューションを「トレース」できます。それは非常に標準的なトリックです。あなたにとっては問題ではないと思います。あなたはアルゴリズムが得意なようです:)
update2 これは本質的に DP (動的プログラミング) であり、少し肥大化しただけです