私は惑星科学研究者であり、私が取り組んでいるプロジェクトの1つは、土星の環のN体シミュレーションです。この特定の研究の目標は、粒子が自身の自己重力の下で凝集するのを観察し、凝集塊の総質量とセル内のすべての粒子の平均速度を測定することです。これが、土星の夏至の間にカッシーニ宇宙船によって行われた観測を説明できるかどうかを解明しようとしています。以下は、任意のタイムステップがどのように見えるかのスクリーンショットです。(各粒子の直径は2 mで、シミュレーションセル自体の直径は約700 mです。)
私が使用しているコードは、すでにすべてのタイムステップで平均速度を吐き出します。私がしなければならないのは、塊の中の浮遊粒子ではなく、塊の中の粒子の質量を決定する方法を見つけ出すことです。私はすべての粒子の位置、質量、サイズなどを知っていますが、例えば、粒子30,000〜40,000と102,000〜105,000が人間の目に明らかな1本の鎖を構成していることは簡単にはわかりません。
したがって、私が記述する必要があるアルゴリズムは、すべての粒子位置を通過し、どの粒子が塊に属しているかを把握し、計算するユーザー入力パラメーターを可能な限り少なくする必要があります(複製可能性と客観性のため)質量。セル上のすべてとは対照的に、「各」クランプ/ストランドに対してそれを行うことができれば素晴らしいと思いますが、実際にそれらを分離する必要はないと思います。
私が考えていた唯一のことは、あらゆる粒子間の距離を計算するN 2距離計算を行うことでした。たとえば、最も近い100個の粒子が特定の距離内にある場合、その粒子はクラスタ。しかし、それはかなりずさんなようであり、CSの人々やプログラマーがよりエレガントなソリューションを知っていることを望んでいましたか?
私のソリューションで編集: 私がやったのは、ある種の最近隣/クラスターアプローチを採用し、最初にクイックnダーティN 2実装を行うことでした。したがって、すべての粒子を取得し、他のすべての粒子までの距離を計算します。クラスター内のしきい値は、d距離内にN個の粒子があるかどうかでした(残念ながら、先験的に設定する必要がある2つのパラメーターですが、応答/コメント、私はそれらのいくつかを持っていないことで逃げるつもりはなかった)。
次に、距離を並べ替えずに、順序Nの検索を行ってd内のパーティクルのカウンターをインクリメントすることで速度を上げました。その速度は6倍になりました。ツリーコードについてはほとんど何もありません)。Iは、グリッドの設定数に(グリッドサイズ≈7ときに最良の結果をシミュレーションセルを分割D細胞と主グリッドラインアップは、1つのグリッドがで半分だけオフセットされている)のxとyの、及び他の二つがずれています1/4 x ± xおよび± y。次に、コードはパーティクルをグリッドに分割し、各パーティクルNはそのセル内の他のパーティクルまでの距離を計算するだけで済みます。
理論的には、これが実際のツリーである場合、N 2の速度ではなく次数N * log(N)を取得する必要があります。私は2つの間のどこかに行きました、そこでは50,000個の粒子のサブセットで速度が17倍になり、150,000個の粒子のセルでは速度が38倍になりました。最初の12秒、2番目の53秒、500,000粒子セルの460秒。これらは、コードがシミュレーションを1タイムステップ先に実行するのにかかる時間に匹敵する速度であるため、この時点では妥当です。ああ-そしてそれは完全にスレッド化されているので、私がそれに投げつけることができる限り多くのプロセッサーを必要とします。